import { _decorator, Component, director, Node, Label, Button, UITransform, Color, Vec3, Graphics } from 'cc';
import { UIFlowMgr, ISceneEnter } from '../ui/UIFlowMgr';
import { DESIGN_WIDTH, DESIGN_HEIGHT } from '../common/Constants';

const { ccclass, property } = _decorator;

/** Maps abstract SceneId → physical Cocos Creator scene name. */
const SCENE_MAP: Record<string, string> = {
    boot: 'Boot',
    story_intro: 'StoryIntro',
    main_menu: 'MainMenu',
    // level_select currently reuses MainMenu until a dedicated LevelSelect scene exists.
    level_select: 'MainMenu',
    // `gameplay` is dispatched by levelId — resolved at runtime.
    gameplay: 'Level_1_1',
    settlement: 'Settlement',
    // Settings panel is overlayed on MainMenu for the MVP.
    settings: 'MainMenu',
};

/** levelId → physical scene name mapping (chapter 1 only). */
const LEVEL_SCENE_MAP: Record<string, string> = {
    '1-1': 'Level_1_1',
    '1-2': 'Level_1_2',
    '1-3': 'Level_1_3',
    '1-4': 'Level_1_4',
    '1-5': 'Level_1_5',
    '1-5-boss': 'Boss_ShuangHuanFang',
};

/**
 * MainMenu scene entry (task 9.2 hookup).
 *
 * Owns a `UIFlowMgr` instance and translates each abstract `onSceneEnter`
 * callback into a concrete `director.loadScene` call. Attach this component
 * to the root node of `MainMenu.scene`.
 *
 * When `autoBuildUI` is enabled (default), two centered buttons (Start /
 * Settings) and a title label are created programmatically so the scene is
 * usable out of the box even before any art pass.
 */
@ccclass('MainMenuEntry')
export class MainMenuEntry extends Component {
    @property({ tooltip: '是否自动生成 Start / Settings 按钮 (方便没美术时就能跑通)' })
    public autoBuildUI: boolean = true;

    private flow: UIFlowMgr | undefined;

    protected onLoad(): void {
        this.flow = new UIFlowMgr(undefined, {
            onSceneEnter: (ev) => this.handleSceneEnter(ev),
        });
        if (this.autoBuildUI) this.buildDefaultUI();
    }

    /** Bind this to the "Start" button's click event in the Inspector. */
    public onPressStart(): void {
        this.flow?.onPressStartGame();
    }

    /** Bind this to the "Settings" button's click event. */
    public onPressSettings(): void {
        this.flow?.onOpenSettings();
    }

    private handleSceneEnter(ev: ISceneEnter): void {
        const payload = ev.payload ?? {};
        if (ev.scene === 'gameplay' && typeof payload.levelId === 'string') {
            const physical = LEVEL_SCENE_MAP[payload.levelId];
            if (physical) {
                director.loadScene(physical);
                return;
            }
        }
        const physical = SCENE_MAP[ev.scene];
        if (physical) director.loadScene(physical);
    }

    // ------------------------------------------------------------------
    // Auto-built UI (development affordance; art pass will replace it)
    // ------------------------------------------------------------------
    private buildDefaultUI(): void {
        // Ensure the host node has a UITransform matching the design resolution.
        ensureCanvasSize(this.node);

        // Title.
        createLabel(this.node, '影 之 传 说', 0, 140, 44, Color.WHITE);

        // Start button (centered, 40 above origin).
        createButton(this.node, 'Start', 0, 40, 220, 60, () => this.onPressStart());

        // Settings button (centered, 40 below origin).
        createButton(this.node, 'Settings', 0, -40, 220, 60, () => this.onPressSettings());

        // Hint line at the bottom.
        createLabel(this.node, 'Chapter 1 · MVP', 0, -200, 20, new Color(180, 180, 180, 255));
    }
}

// ======================================================================
// Shared UI helpers — intentionally kept inline (no external module) so
// each Scene Entry stays self-contained and easy to remove once real UI is
// authored in the editor.
// ======================================================================

function ensureCanvasSize(host: Node): void {
    let ut = host.getComponent(UITransform);
    if (!ut) ut = host.addComponent(UITransform);
    ut.setContentSize(DESIGN_WIDTH, DESIGN_HEIGHT);
    host.setPosition(0, 0, 0);
}

function createLabel(parent: Node, text: string, x: number, y: number, fontSize: number, color: Color): Node {
    const n = new Node('AutoLabel');
    n.layer = parent.layer;
    parent.addChild(n);
    const ut = n.addComponent(UITransform);
    ut.setContentSize(DESIGN_WIDTH, fontSize * 1.6);
    const lb = n.addComponent(Label);
    lb.useSystemFont = true;
    lb.string = text;
    lb.fontSize = fontSize;
    lb.lineHeight = Math.floor(fontSize * 1.2);
    lb.color = color;
    lb.horizontalAlign = 1; // CENTER
    lb.verticalAlign = 1;   // CENTER
    n.setPosition(new Vec3(x, y, 0));
    return n;
}

function createButton(
    parent: Node,
    text: string,
    x: number,
    y: number,
    w: number,
    h: number,
    onClick: () => void
): Node {
    const n = new Node(`Btn_${text}`);
    n.layer = parent.layer;
    parent.addChild(n);
    const ut = n.addComponent(UITransform);
    ut.setContentSize(w, h);

    // Background drawn via Graphics — avoids needing any texture asset.
    const g = n.addComponent(Graphics);
    g.fillColor = new Color(40, 40, 60, 230);
    g.rect(-w / 2, -h / 2, w, h);
    g.fill();
    g.strokeColor = new Color(200, 200, 220, 255);
    g.lineWidth = 2;
    g.rect(-w / 2, -h / 2, w, h);
    g.stroke();

    // Label child for the text.
    const labelNode = new Node('Label');
    labelNode.layer = parent.layer;
    n.addChild(labelNode);
    const lut = labelNode.addComponent(UITransform);
    lut.setContentSize(w, h);
    const lb = labelNode.addComponent(Label);
    lb.useSystemFont = true;
    lb.string = text;
    lb.fontSize = 24;
    lb.lineHeight = 28;
    lb.color = Color.WHITE;
    lb.horizontalAlign = 1;
    lb.verticalAlign = 1;

    const btn = n.addComponent(Button);
    btn.transition = Button.Transition.SCALE;
    btn.target = n;
    btn.zoomScale = 0.95;
    n.on(Node.EventType.TOUCH_END, onClick, n);

    n.setPosition(new Vec3(x, y, 0));
    return n;
}

// Re-export helpers so sibling Scene Entries can reuse them.
export { ensureCanvasSize, createLabel, createButton };
