import { StorageMgr, globalStorageMgr } from '../common/StorageMgr';
import { STORAGE_KEY } from '../common/Constants';

/**
 * Tutorial manager (req 11.1-11.5, task 9.3).
 *
 * Pre-defined tutorial sequences for levels 1-1, 1-2, 1-3. Each step has an
 * ID the view layer uses to drive highlight-arrows; the step is "completed"
 * when the player performs the action, which the view layer signals via
 * `reportAction()`.
 */

export interface ITutorialStep {
    id: string;
    /** Human-readable hint (displayed by the view layer). */
    hint: string;
    /** Action id the player must perform to advance. */
    requiredAction: string;
}

export interface ITutorialSequence {
    levelId: string;
    steps: ITutorialStep[];
}

/** Built-in tutorials for Chapter 1 (req 11.1-11.3). */
export const BUILTIN_TUTORIALS: ITutorialSequence[] = [
    {
        levelId: '1-1',
        steps: [
            { id: 'attack', hint: '点击右下的手里剑按钮', requiredAction: 'fire_shuriken' },
            { id: 'joystick', hint: '拖动左下摇杆移动', requiredAction: 'move' },
            { id: 'jump', hint: '点击跳跃按钮', requiredAction: 'jump' },
        ],
    },
    {
        levelId: '1-2',
        steps: [
            { id: 'parabolic', hint: '摇杆 45° 并跳跃 — 抛物线跳跃', requiredAction: 'parabolic_jump' },
            { id: 'exclusive', hint: '两个攻击按钮互斥，选一个用', requiredAction: 'attack_switch' },
            { id: 'parry', hint: '忍者刀可以格挡敌人刀剑', requiredAction: 'parry' },
            { id: 'combo', hint: '跳跃中同时攻击', requiredAction: 'jump_attack' },
            { id: 'auto_upgrade', hint: '拾取水晶玉自动强化', requiredAction: 'pickup_crystal' },
        ],
    },
    {
        levelId: '1-3',
        steps: [
            { id: 'butterfly', hint: '先击中 BOSS 身旁的蝴蝶', requiredAction: 'hit_butterfly' },
            { id: 'boss_identify', hint: '识别 BOSS 攻击模式', requiredAction: 'dodge_boss_attack' },
            { id: 'one_shot', hint: '显形后一击必杀', requiredAction: 'hit_revealed_boss' },
        ],
    },
];

export class TutorialMgr {
    private currentLevelId: string | null = null;
    private currentStepIndex = 0;

    constructor(
        private readonly storage: StorageMgr = globalStorageMgr,
        private readonly sequences: ITutorialSequence[] = BUILTIN_TUTORIALS
    ) {}

    /** Start the tutorial for `levelId` if not already completed. */
    public maybeStart(levelId: string): ITutorialStep | null {
        if (this.isCompleted(levelId)) return null;
        const seq = this.sequences.find((s) => s.levelId === levelId);
        if (!seq) return null;
        this.currentLevelId = levelId;
        this.currentStepIndex = 0;
        return seq.steps[0];
    }

    /** Called by gameplay whenever the player performs an action. */
    public reportAction(action: string): ITutorialStep | 'finished' | 'no_op' {
        if (!this.currentLevelId) return 'no_op';
        const seq = this.sequences.find((s) => s.levelId === this.currentLevelId);
        if (!seq) return 'no_op';
        const current = seq.steps[this.currentStepIndex];
        if (action !== current.requiredAction) return 'no_op';
        this.currentStepIndex++;
        if (this.currentStepIndex >= seq.steps.length) {
            this.markCompleted(this.currentLevelId);
            this.currentLevelId = null;
            this.currentStepIndex = 0;
            return 'finished';
        }
        return seq.steps[this.currentStepIndex];
    }

    public isCompleted(levelId: string): boolean {
        const completed = this.storage.get<string[]>(STORAGE_KEY.TutorialDone, []);
        return completed.includes(levelId);
    }

    public resetAll(): void {
        this.storage.remove(STORAGE_KEY.TutorialDone);
        this.currentLevelId = null;
        this.currentStepIndex = 0;
    }

    public get isActive(): boolean {
        return this.currentLevelId !== null;
    }

    public currentStep(): ITutorialStep | null {
        if (!this.currentLevelId) return null;
        const seq = this.sequences.find((s) => s.levelId === this.currentLevelId);
        return seq?.steps[this.currentStepIndex] ?? null;
    }

    private markCompleted(levelId: string): void {
        const current = this.storage.get<string[]>(STORAGE_KEY.TutorialDone, []);
        if (!current.includes(levelId)) current.push(levelId);
        this.storage.set(STORAGE_KEY.TutorialDone, current);
    }
}
