import { _decorator, Component, director, screen, view, Settings, settings, sys, game, view as viewMgr } from 'cc';
import { DESIGN_WIDTH, DESIGN_HEIGHT, TARGET_FPS } from './common/Constants';
import { UIFlowMgr, ISceneEnter } from './ui/UIFlowMgr';

const { ccclass } = _decorator;

/**
 * Game bootstrap component. Attached to the root node of the initial scene
 * (`assets/scenes/Boot.scene`). Responsible for:
 *
 *  1. Locking landscape orientation (requirement - tech-stack constraint).
 *  2. Forcing the design resolution to 960x540 with the "fit height" policy
 *     so that any wider aspect ratio (18:9 / 19.5:9 / 20:9) simply extends
 *     horizontally without distorting the UI (requirement 1.7 / 18.6).
 *  3. Locking frame rate to 30 fps (requirement 18.1-18.3).
 *  4. Loading the first gameplay-facing scene (story intro if not seen, else
 *     main menu). This is the very first place we branch on the local storage
 *     flag defined in `STORAGE_KEY.StoryIntroSeen` (requirement 19.5).
 *
 * NOTE: Do NOT put any heavy logic here; this component runs on the very
 * first frame and must stay cheap.
 */
@ccclass('GameBoot')
export class GameBoot extends Component {
    protected onLoad(): void {
        this.lockOrientationLandscape();
        this.applyDesignResolution();
        this.lockFrameRate();
    }

    protected start(): void {
        // Drive the very first scene transition through UIFlowMgr so that
        // story-intro / main-menu selection lives in one place (req 19.5).
        const flow = new UIFlowMgr(undefined, {
            onSceneEnter: (ev: ISceneEnter) => this.jumpToScene(ev),
        });
        flow.onBoot();
    }

    /**
     * Translate the abstract UIFlow event into a concrete Cocos scene load.
     * Boot scene itself never needs persisting; once we jump away the node
     * is discarded naturally.
     */
    private jumpToScene(ev: ISceneEnter): void {
        const map: Record<string, string> = {
            story_intro: 'StoryIntro',
            main_menu: 'MainMenu',
        };
        const scene = map[ev.scene];
        if (scene) {
            director.loadScene(scene);
        }
    }

    /**
     * Lock the device to landscape. On WeChat Mini Game this is declared in
     * `game.json` (deviceOrientation: "landscape"); on web/simulator we call
     * the `screen.orientation` API when available.
     */
    private lockOrientationLandscape(): void {
        // `screen.orientation` is not declared as writable in every engine
        // build, so we access it guardedly.
        try {
            // @ts-ignore - engine API surface differs across platforms.
            if (typeof screen.orientation === 'number') {
                // macro.ORIENTATION_LANDSCAPE = 3 in Cocos Creator 3.8.
                // @ts-ignore - write is legal on runtime builds.
                screen.orientation = 3;
            }
        } catch (e) {
            // Silently ignore: editor preview already enforces orientation
            // through `profiles/v2/project.json`.
        }
    }

    /**
     * Apply the 960x540 landscape design resolution. Any physical screen
     * whose aspect ratio is >= 16:9 will simply show more horizontal world;
     * narrower screens (unlikely on landscape) will letterbox.
     */
    private applyDesignResolution(): void {
        const v = view;
        v.setDesignResolutionSize(DESIGN_WIDTH, DESIGN_HEIGHT, 4 /* FIT_HEIGHT */);
    }

    /** Clamp the engine game loop to 30 fps. */
    private lockFrameRate(): void {
        game.frameRate = TARGET_FPS;
    }
}
