//! Browser entry point for the Ferrous Solitaire Bevy WASM build.
//!
//! This crate compiles the full `solitaire_engine` to `wasm32-unknown-unknown`
//! and renders to a `<canvas id="bevy-canvas">` element. It shares the same
//! ECS code path as the desktop and Android builds; the only differences are:
//! - Audio, sync, and analytics plugins are cfg-gated out in `CoreGamePlugin`
//!   on the wasm32 target (see `solitaire_engine/src/core_game_plugin.rs`).
//! - `LocalOnlyProvider` is passed as the sync provider (sync is disabled).
//! - Storage is handled automatically by `WasmStorage` (localStorage-backed),
//!   wired by `CoreGamePlugin` via `default_storage_backend()`.

use bevy::asset::AssetMetaCheck;
use bevy::prelude::*;
use bevy::render::RenderPlugin;
use bevy::render::settings::{RenderCreation, WgpuSettings, WgpuSettingsPriority};
use bevy::window::{Window, WindowPlugin, WindowResolution};
use solitaire_data::LocalOnlyProvider;
use solitaire_engine::CoreGamePlugin;
use wasm_bindgen::prelude::*;

#[wasm_bindgen(start)]
pub fn start() {
    console_error_panic_hook::set_once();

    App::new()
        .add_plugins(
            DefaultPlugins
                .set(WindowPlugin {
                    primary_window: Some(Window {
                        // Bind to the existing <canvas id="bevy-canvas"> in play.html.
                        // Without this, Bevy appends its own canvas to <body>.
                        canvas: Some("#bevy-canvas".into()),
                        // Let CSS size the canvas; Bevy follows the element's size.
                        fit_canvas_to_parent: true,
                        // Prevent the browser stealing keyboard events and scroll.
                        prevent_default_event_handling: true,
                        // Render at CSS/logical pixels (scale_factor 1.0) rather
                        // than physical (CSS × devicePixelRatio). This keeps the
                        // surface smaller on HiDPI displays — lighter GPU load and
                        // stable sizing — at the cost of some crispness. The wgpu
                        // texture-dimension limit is now taken from the adapter (see
                        // the RenderPlugin below), so this is purely a quality/perf
                        // choice, no longer a crash-avoidance hack.
                        resolution: WindowResolution::default()
                            .with_scale_factor_override(1.0),
                        ..default()
                    }),
                    ..default()
                })
                // Bevy's default AssetPlugin fetches a `.meta` sidecar file for
                // every asset before loading the asset itself. We don't ship
                // `.meta` files, so skip the check to avoid a flood of 404s.
                .set(AssetPlugin {
                    meta_check: AssetMetaCheck::Never,
                    ..default()
                })
                // `Functionality` makes wgpu adopt the *adapter's* real limits
                // instead of the conservative `downlevel_webgl2_defaults()` that
                // `WebGL2` priority forces. On the WebGL2 (Gl) backend the adapter
                // already reports WebGL2-constrained features/limits — no storage
                // buffers, etc., so shaders stay GLES-compatible on both Firefox and
                // Chromium — but it reports the GPU's *true* `max_texture_dimension`
                // (e.g. 16384) rather than 2048. The device is requested with exactly
                // what the adapter offers, so creation can't fail, and the surface is
                // no longer capped at 2048: large viewports (4K, etc.) render natively
                // with no letterbox and no hardcoded cap.
                .set(RenderPlugin {
                    render_creation: RenderCreation::Automatic(WgpuSettings {
                        priority: WgpuSettingsPriority::Functionality,
                        ..default()
                    }),
                    ..default()
                }),
        )
        // LocalOnlyProvider disables cloud sync — correct for the web build
        // since SyncPlugin is cfg-gated out on wasm32 anyway.
        .add_plugins(CoreGamePlugin::new(Box::new(LocalOnlyProvider)))
        .run();
}
