import { Api } from '../modules/api.js';
import { Game } from '../modules/game.js';
import { UI } from '../modules/ui.js';
import { CommonCanvas } from '../modules/canvas_utils.js';

document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('sudokuCanvas');
    if (!canvas) return;

    // 설정: 600x820 (보드 600 + 하단 UI 220)
    const V_W = 600, V_H = 820, CELL = 600/9;
    const common = CommonCanvas.init(canvas, V_W, V_H);
    const { ctx, resize, getCoords, isInside, showSuccessOverlay, fillRoundRect } = common;

    let gameState = 'START';
    let board = [], solution = [], isEditable = [], isIncorrect = [];
    let history = []; // 실행 취소 스택
    let selectedNumber = null;
    let lives = 5, seconds = 0, timerInterval = null, currentPuzzleId = null;

    const layout = {
        menu: {
            easy: { x: 100, y: 320, w: 400, h: 60, label: "쉬움 (Easy)" },
            medium: { x: 100, y: 400, w: 400, h: 60, label: "보통 (Medium)" },
            hard: { x: 100, y: 480, w: 400, h: 60, label: "어려움 (Hard)" }
        },
        controls: {
            undo: { x: 20, y: 610, w: 100, h: 40, label: "↺ 취소" },
            hint: { x: 140, y: 610, w: 100, h: 40, label: "💡 힌트" },
            memo: { x: 480, y: 610, w: 100, h: 40, label: "SCORE" } // 점수 표시용
        },
        numPadY: 680, numBtnW: V_W / 9
    };

    function draw() {
        ctx.clearRect(0, 0, V_W, V_H);
        ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, V_W, V_H);

        if (gameState === 'START') drawMenu();
        else drawGame();
    }

    function drawMenu() {
        ctx.fillStyle = "#333"; ctx.font = "bold 50px Arial"; ctx.textAlign = "center";
        ctx.fillText("SUDOKU", V_W/2, 220);
        Object.values(layout.menu).forEach(btn => {
            fillRoundRect(btn.x, btn.y, btn.w, btn.h, 10, "#4a90e2");
            ctx.fillStyle = "#fff"; ctx.font = "bold 24px Arial";
            ctx.fillText(btn.label, btn.x + btn.w/2, btn.y + btn.h/2 + 8);
        });
    }

    function drawGame() {
        // 1. 보드
        const counts = getNumberCounts();
        board.forEach((val, i) => {
            const r = Math.floor(i/9), c = i%9, x = c*CELL, y = r*CELL;
            // 배경
            if (isIncorrect[i]) { ctx.fillStyle = "#ffe3e3"; ctx.fillRect(x,y,CELL,CELL); }
            else if (selectedNumber && val === selectedNumber) { ctx.fillStyle = "#e2f0ff"; ctx.fillRect(x,y,CELL,CELL); }

            // 격자
            ctx.strokeStyle = "#ddd"; ctx.lineWidth = 1; ctx.strokeRect(x,y,CELL,CELL);

            // 숫자
            if (val !== 0) {
                ctx.fillStyle = isIncorrect[i] ? "#e03131" : (isEditable[i] ? "#4a90e2" : "#333");
                ctx.font = `bold ${CELL*0.6}px Arial`; ctx.textAlign = "center";
                ctx.fillText(val, x+CELL/2, y+CELL/2+10);
            }
        });

        // 3x3 굵은 선
        ctx.strokeStyle = "#333"; ctx.lineWidth = 3;
        for(let i=0; i<=9; i+=3) {
            ctx.beginPath(); ctx.moveTo(i*CELL, 0); ctx.lineTo(i*CELL, 600); ctx.stroke();
            ctx.beginPath(); ctx.moveTo(0, i*CELL); ctx.lineTo(600, i*CELL); ctx.stroke();
        }

        // 2. 컨트롤 버튼 (Undo, Hint)
        [layout.controls.undo, layout.controls.hint].forEach(btn => {
            fillRoundRect(btn.x, btn.y, btn.w, btn.h, 5, "#6c757d");
            ctx.fillStyle = "#fff"; ctx.font = "16px Arial"; ctx.textAlign = "center";
            ctx.fillText(btn.label, btn.x+btn.w/2, btn.y+btn.h/2+6);
        });
        // 점수/생명 표시
        ctx.fillStyle = "#333"; ctx.font = "20px Arial"; ctx.textAlign = "right";
        ctx.fillText(`LIFE: ${lives}   TIME: ${seconds}s`, V_W-20, 635);

        // 3. 숫자 패드
        for(let i=1; i<=9; i++) {
            const bx = (i-1)*layout.numBtnW;
            const isDone = counts[i] >= 9;
            const bgColor = isDone ? "#e0e0e0" : (selectedNumber == i ? "#4a90e2" : "#f8f9fa");
            const textColor = isDone ? "#aaa" : (selectedNumber == i ? "#fff" : "#333");

            fillRoundRect(bx+4, layout.numPadY, layout.numBtnW-8, 80, 8, bgColor);
            ctx.fillStyle = textColor; ctx.font = "bold 30px Arial"; ctx.textAlign = "center";
            ctx.fillText(i, bx+layout.numBtnW/2, layout.numPadY+50);
        }
    }

    function getNumberCounts() {
        const counts = {}; for(let i=1; i<=9; i++) counts[i]=0;
        board.forEach((v, i) => { if(v!==0 && !isIncorrect[i]) counts[v]++; });
        return counts;
    }

    // --- 게임 로직 ---
    async function startGame(diff) {
        try {
            const data = await Api.request(`/puzzle/sudoku/start?difficulty=${diff}`);
            board = data.question.split('').map(Number);
            solution = data.solution.split('').map(Number);
            isEditable = board.map(v => v === 0);
            isIncorrect = Array(81).fill(false);
            currentPuzzleId = data.puzzleId;
            history = []; lives = 5; seconds = 0; gameState = 'PLAYING';
            if (timerInterval) clearInterval(timerInterval);
            timerInterval = setInterval(() => { seconds++; draw(); }, 1000);
            draw();
        } catch(e) { console.error(e); }
    }

    function fillCell(idx, num) {
        if (!isEditable[idx]) return;
        const prev = board[idx];
        if (prev === num) return; // 변경 없음

        // 히스토리 저장
        history.push({ idx, prev, wasIncorrect: isIncorrect[idx] });

        board[idx] = num;

        if (solution[idx] === num) {
            isIncorrect[idx] = false;
            // 숫자 9개 다 찼으면 선택 해제
            if (getNumberCounts()[num] >= 9) selectedNumber = null;
            checkWin();
        } else {
            isIncorrect[idx] = true;
            lives--;
            if (lives <= 0) {
                alert("Game Over"); location.reload();
            }
        }
    }

    function handleUndo() {
        if (history.length === 0) return;
        const last = history.pop();
        board[last.idx] = last.prev;
        isIncorrect[last.idx] = last.wasIncorrect;
    }

    function handleHint() {
        const emptyIndices = board.map((v, i) => v === 0 || isIncorrect[i] ? i : -1).filter(i => i !== -1);
        if (emptyIndices.length === 0) return;

        const idx = emptyIndices[Math.floor(Math.random() * emptyIndices.length)];
        // 힌트는 히스토리 없이 정답 처리
        board[idx] = solution[idx];
        isIncorrect[idx] = false;
        // 힌트 사용 시 점수나 생명 차감 등 추가 가능
        checkWin();
    }

    function checkWin() {
        if (board.every((v, i) => v === solution[i])) {
            clearInterval(timerInterval);
            showSuccessOverlay({ title: "SUDOKU CLEAR!", scoreLabel: "LIFE", scoreValue: lives, timeValue: seconds });
            setTimeout(() => Game.showSuccessModal({
                gameType: 'SUDOKU', contextId: currentPuzzleId, primaryScore: seconds
            }), 2500);
        }
    }

    // --- 입력 핸들러 ---
    canvas.addEventListener('mousedown', (e) => {
        const p = getCoords(e);
        if (gameState === 'START') {
            for(const [k, btn] of Object.entries(layout.menu)) if(isInside(p, btn)) startGame(k);
        } else {
            // 컨트롤 버튼
            if (isInside(p, layout.controls.undo)) { handleUndo(); draw(); return; }
            if (isInside(p, layout.controls.hint)) { handleHint(); draw(); return; }

            // 숫자 패드
            if (p.y > layout.numPadY) {
                const num = Math.floor(p.x / layout.numBtnW) + 1;
                if (getNumberCounts()[num] < 9) selectedNumber = (selectedNumber == num) ? null : num;
            }
            // 보드 클릭
            else if (p.y < 600 && selectedNumber) {
                const c = Math.floor(p.x/CELL), r = Math.floor(p.y/CELL);
                if (c>=0 && c<9 && r>=0 && r<9) fillCell(r*9+c, parseInt(selectedNumber));
            }
        }
        draw();
    });

    resize(); draw();
});