import { UI } from '../modules/ui.js';
import { Game } from '../modules/game.js';

document.addEventListener('DOMContentLoaded', () => {
    // 1. 퍼즐 데이터 확인
    const puzzleData = window.puzzleData;
    if (!puzzleData) return;

    // 2. DOM 요소
    const modeSelector = document.getElementById('mode-selector');
    const gameBoard = document.getElementById('game-board');
    const pointsDisplay = document.getElementById('points-display');
    const hintBtn = document.getElementById('hint-btn');

    // 3. 게임 상태
    let currentMode = 'fill';
    let points = 5;
    let isGameFinished = false;
    let gameStartTime = 0;

    // 드래그 상태
    let isDragging = false, dragAction = null;
    let startCell = null, lastHoveredCell = null;
    let currentSelection = new Set(), affectedRows = new Set(), affectedCols = new Set();

    const solution = puzzleData.solutionGrid;
    const numRows = solution.length;
    const numCols = solution[0].length;
    let playerGrid = Array(numRows).fill(0).map(() => Array(numCols).fill(0));
    let lockedRows = Array(numRows).fill(false);
    let lockedCols = Array(numCols).fill(false);

    // 4. 초기화 및 함수들
    function updateMode() {
        const checked = document.querySelector('input[name="play-mode"]:checked');
        if (checked) currentMode = checked.value;
    }

    function calculateCellSize() {
        // [수정] body가 아니라 실제 게임이 들어갈 viewport의 너비를 기준
        const viewport = document.getElementById('board-viewport');
        const width = viewport ? viewport.clientWidth : document.body.clientWidth;

        // 힌트 공간 제외하고 셀 크기 계산
        const availableWidth = width - 80;
        const calculated = Math.floor(availableWidth / numCols);

        return Math.max(15, Math.min(calculated, 35));
    }

    function drawBoard(cellSize) {
        // [수정] 힌트 영역 너비/높이 계산 (글자 크기 고려하여 넉넉하게)
        // 숫자 하나당 10px + 여백 20px
        const maxRowClues = Math.max(...puzzleData.rowClues.map(c => c.length));
        const maxColClues = Math.max(...puzzleData.colClues.map(c => c.length));

        const rowHintWidth = Math.max(60, maxRowClues * 20);
        const colHintHeight = Math.max(60, maxColClues * 20);

        // 전체 레이아웃 (gap: 0으로 설정하여 미세 오차 제거)
        gameBoard.style.display = 'grid';
        gameBoard.style.gap = '0px';
        gameBoard.style.border = '2px solid #333';
        gameBoard.style.backgroundColor = '#333'; // 틈새로 보이는 색 (구분선 역할)

        gameBoard.style.gridTemplateColumns = `${rowHintWidth}px auto`;
        gameBoard.style.gridTemplateRows = `${colHintHeight}px auto`;

        gameBoard.innerHTML = '';

        // 1. 코너 (빈칸)
        const corner = document.createElement('div');
        corner.style.background = '#f0f0f0';
        corner.style.borderRight = '2px solid #333'; // 구분선
        corner.style.borderBottom = '2px solid #333'; // 구분선
        gameBoard.appendChild(corner);

        // 2. 열 힌트 (Top)
        const colContainer = document.createElement('div');
        colContainer.className = 'col-clues-container';
        colContainer.style.display = 'grid';
        // [핵심] 게임판과 동일한 구조 적용
        colContainer.style.gridTemplateColumns = `repeat(${numCols}, ${cellSize}px)`;
        colContainer.style.gap = '1px'; // 게임판과 동일한 간격
        colContainer.style.backgroundColor = '#999'; // 간격 색상
        colContainer.style.borderBottom = '2px solid #333'; // 구분선

        puzzleData.colClues.forEach((clues, i) => {
            const cell = document.createElement('div');
            cell.className = 'clue-cell col-clue';
            cell.id = `col-clue-${i}`;
            cell.style.width = '100%'; // 꽉 채우기
            cell.innerHTML = clues.join('<br>');
            if ((i+1)%5===0 && i<numCols-1) cell.style.borderRight = '2px solid #555';
            colContainer.appendChild(cell);
        });
        gameBoard.appendChild(colContainer);

        // 3. 행 힌트 (Left)
        const rowContainer = document.createElement('div');
        rowContainer.className = 'row-clues-container';
        rowContainer.style.display = 'grid';
        // [핵심] 게임판과 동일한 구조 적용
        rowContainer.style.gridTemplateRows = `repeat(${numRows}, ${cellSize}px)`;
        rowContainer.style.gap = '1px'; // 게임판과 동일한 간격
        rowContainer.style.backgroundColor = '#999'; // 간격 색상
        rowContainer.style.borderRight = '2px solid #333'; // 구분선

        puzzleData.rowClues.forEach((clues, i) => {
            const cell = document.createElement('div');
            cell.className = 'clue-cell row-clue';
            cell.id = `row-clue-${i}`;
            cell.style.height = '100%'; // 꽉 채우기
            cell.textContent = clues.join(' ');
            if ((i+1)%5===0 && i<numRows-1) cell.style.borderBottom = '2px solid #555';
            rowContainer.appendChild(cell);
        });
        gameBoard.appendChild(rowContainer);

        // 4. 퍼즐 그리드 (Main)
        const gridContainer = document.createElement('div');
        gridContainer.className = 'puzzle-grid-container';
        gridContainer.style.display = 'grid';
        // [핵심] 픽셀 단위 고정 및 간격 통일
        gridContainer.style.gridTemplateColumns = `repeat(${numCols}, ${cellSize}px)`;
        gridContainer.style.gridTemplateRows = `repeat(${numRows}, ${cellSize}px)`;
        gridContainer.style.gap = '1px'; // 힌트 영역과 동일한 간격 필수!
        gridContainer.style.backgroundColor = '#999'; // 간격 색상

        for (let r = 0; r < numRows; r++) {
            for (let c = 0; c < numCols; c++) {
                const cell = document.createElement('div');
                cell.className = 'grid-cell';
                cell.dataset.row = r;
                cell.dataset.col = c;

                // 5칸마다 굵은 가이드라인
                if ((c+1)%5===0 && c<numCols-1) cell.style.borderRight = '2px solid #555';
                if ((r+1)%5===0 && r<numRows-1) cell.style.borderBottom = '2px solid #555';

                gridContainer.appendChild(cell);
            }
        }
        gameBoard.appendChild(gridContainer);

        gameStartTime = Date.now();
        attachEventListeners(gridContainer);
    }

    function fitBoardToScreen() {
        const viewport = document.getElementById('board-viewport');
        const board = document.getElementById('game-board');

        // [수정] 중앙 정렬을 위해 기준점을 'top center'로 변경 (또는 상황에 따라 left)
        // 하지만 Grid 레이아웃에선 transform보다 max-width 제어가 더 깔끔합니다.
        // 여기서는 기존 로직을 보완하여 중앙에 오도록 합니다.
        board.style.transformOrigin = 'top left';
        board.style.transform = 'scale(1)';

        const boardRect = board.getBoundingClientRect();
        const viewportRect = viewport.getBoundingClientRect();

        if (boardRect.width > viewportRect.width) {
            const scale = viewportRect.width / boardRect.width;
            board.style.transform = `scale(${scale})`;
            viewport.style.height = `${boardRect.height * scale}px`;
        } else {
            viewport.style.height = `${boardRect.height}px`;
            // [추가] 보드가 뷰포트보다 작으면 중앙 정렬 (CSS Flex가 처리하지만 명시적으로)
            // game_nonogram.css의 #board-viewport { justify-content: center; }가 있어야 함
        }
    }

    // ... (이하 updateCellState, 이벤트 리스너 등 기존 로직 동일) ...
    // 아래 코드는 기존 파일의 내용을 그대로 유지해주세요. (분량상 생략)

    function updateCellState(cell, action) {
        if (isGameFinished) return;
        const row = parseInt(cell.dataset.row), col = parseInt(cell.dataset.col);
        if (lockedRows[row] || lockedCols[col]) return;
        affectedRows.add(row); affectedCols.add(col);
        const currentState = playerGrid[row][col];
        let newState = currentState;

        if (action === 'fill') {
            if (solution[row][col] === 0) {
                points--; updatePoints();
                cell.classList.add('incorrect');
                setTimeout(() => cell.classList.remove('incorrect'), 500);
                if (points <= 0) triggerGameOver();
                return;
            }
            newState = 1;
        } else if (action === 'mark') newState = -1;
        else if (action === 'clear') newState = 0;

        if (currentState !== newState) {
            playerGrid[row][col] = newState;
            cell.classList.toggle('filled', newState === 1);
            cell.classList.toggle('marked', newState === -1);
        }
    }

    function attachEventListeners(grid) {
        grid.addEventListener('mousedown', handleDragStart);
        grid.addEventListener('mouseover', handleDragMove);
        grid.addEventListener('touchstart', handleDragStart, { passive: false });
        grid.addEventListener('touchmove', handleDragMove, { passive: false });
    }
    window.addEventListener('mouseup', handleDragEnd);
    window.addEventListener('touchend', handleDragEnd);
    modeSelector.addEventListener('change', updateMode);

    function handleDragStart(e) {
        if (isGameFinished || !e.target.classList.contains('grid-cell')) return;
        isDragging = true; e.preventDefault();
        const cell = e.target;
        const r = parseInt(cell.dataset.row), c = parseInt(cell.dataset.col);
        const currentState = playerGrid[r][c];

        if (e.type === 'mousedown') {
            if (e.button === 0) dragAction = (currentState === 1) ? 'clear' : 'fill';
            else if (e.button === 2) dragAction = (currentState === -1) ? 'clear' : 'mark';
        } else {
            dragAction = (currentMode === 'fill') ? ((currentState === 1) ? 'clear' : 'fill') : ((currentState === -1) ? 'clear' : 'mark');
        }
        startCell = { row: r, col: c };
        lastHoveredCell = startCell;
        updateSelectionVisuals();
    }

    function handleDragMove(e) {
        if (!isDragging) return;
        e.preventDefault();
        const target = (e.touches) ? document.elementFromPoint(e.touches[0].clientX, e.touches[0].clientY) : e.target;
        if (target && target.classList.contains('grid-cell')) {
            const r = parseInt(target.dataset.row), c = parseInt(target.dataset.col);
            if (r !== lastHoveredCell.row || c !== lastHoveredCell.col) {
                lastHoveredCell = { row: r, col: c };
                updateSelectionVisuals();
            }
        }
    }

    function handleDragEnd() {
        if (!isDragging) return;
        currentSelection.forEach(cell => updateCellState(cell, dragAction));
        clearSelectionVisuals();
        if (dragAction === 'fill' || dragAction === 'clear') checkCompleted();
        checkWin();
        isDragging = false; currentSelection.clear(); affectedRows.clear(); affectedCols.clear();
    }

    function updateSelectionVisuals() {
        const newSel = new Set();
        if (!startCell || !lastHoveredCell) return;
        const r1 = Math.min(startCell.row, lastHoveredCell.row), r2 = Math.max(startCell.row, lastHoveredCell.row);
        const c1 = Math.min(startCell.col, lastHoveredCell.col), c2 = Math.max(startCell.col, lastHoveredCell.col);
        for (let r = r1; r <= r2; r++) {
            for (let c = c1; c <= c2; c++) {
                const cell = document.querySelector(`.grid-cell[data-row='${r}'][data-col='${c}']`);
                if (cell) newSel.add(cell);
            }
        }
        currentSelection.forEach(cell => { if (!newSel.has(cell)) cell.classList.remove('selecting'); });
        newSel.forEach(cell => { if (!currentSelection.has(cell)) cell.classList.add('selecting'); });
        currentSelection = newSel;
    }
    function clearSelectionVisuals() { currentSelection.forEach(cell => cell.classList.remove('selecting')); }

    function isRowComplete(r) { for (let c=0; c<numCols; c++) if (solution[r][c]===1 && playerGrid[r][c]!==1) return false; return true; }
    function isColComplete(c) { for (let r=0; r<numRows; r++) if (solution[r][c]===1 && playerGrid[r][c]!==1) return false; return true; }

    function checkCompleted() {
        affectedRows.forEach(r => {
            if (!lockedRows[r] && isRowComplete(r)) {
                lockedRows[r] = true; document.getElementById(`row-clue-${r}`).classList.add('completed');
                for (let c=0; c<numCols; c++) document.querySelector(`.grid-cell[data-row='${r}'][data-col='${c}']`).classList.add('locked');
            }
        });
        affectedCols.forEach(c => {
            if (!lockedCols[c] && isColComplete(c)) {
                lockedCols[c] = true; document.getElementById(`col-clue-${c}`).classList.add('completed');
                for (let r=0; r<numRows; r++) document.querySelector(`.grid-cell[data-row='${r}'][data-col='${c}']`).classList.add('locked');
            }
        });
    }

    function checkWin() {
        if (isGameFinished) return;
        for (let r=0; r<numRows; r++) {
            for (let c=0; c<numCols; c++) {
                if ((playerGrid[r][c]===1 ? 1 : 0) !== solution[r][c]) return;
            }
        }
        triggerSuccess();
    }

    function updatePoints() {
        pointsDisplay.textContent = points;
        hintBtn.disabled = (points <= 0 || isGameFinished);
    }

    function triggerGameOver() {
        if (isGameFinished) return;
        isGameFinished = true;
        document.querySelector('.puzzle-grid-container').style.pointerEvents = 'none';
        hintBtn.disabled = true;
        UI.showAlert("게임 오버", "포인트를 모두 사용했습니다.");
    }

    function triggerSuccess() {
        if (isGameFinished) return;
        isGameFinished = true;
        const completionTime = Math.floor((Date.now() - gameStartTime) / 1000);
        const hintsUsed = 5 - points;

        const viewport = document.getElementById('board-viewport');
        const grid = document.querySelector('.puzzle-grid-container');
        const gray = document.getElementById('grayscale-reveal');
        const orig = document.getElementById('original-reveal');
        grid.style.pointerEvents = 'none'; hintBtn.disabled = true;

        const gridRect = grid.getBoundingClientRect();
        const viewRect = viewport.getBoundingClientRect();

        [gray, orig].forEach(img => {
            img.style.top = `${gridRect.top - viewRect.top}px`;
            img.style.left = `${gridRect.left - viewRect.left}px`;
            img.style.width = `${gridRect.width}px`;
            img.style.height = `${gridRect.height}px`;
            img.src = (img.id === 'grayscale-reveal')
                ? `/puzzle/images/${puzzleData.grayscaleImageFile}`
                : `/puzzle/images/${puzzleData.originalImageFile}`;
        });

        setTimeout(() => {
            gray.style.opacity = '1';
            setTimeout(() => {
                orig.style.opacity = '1';
                setTimeout(() => {
                    Game.showSuccessModal({
                        gameType: 'NONOGRAM', contextId: puzzleData.id,
                        successMessage: `완성! (시간: ${completionTime}초)`,
                        primaryScore: completionTime, secondaryScore: hintsUsed
                    });
                }, 2000);
            }, 2000);
        }, 500);
    }

    hintBtn.addEventListener('click', () => {
        if (points <= 0 || isGameFinished) return;
        points--; updatePoints();
        const candidates = [];
        for (let r=0; r<numRows; r++) for (let c=0; c<numCols; c++) if (solution[r][c]===1 && playerGrid[r][c]!==1) candidates.push({r,c});

        if (candidates.length > 0) {
            const hint = candidates[Math.floor(Math.random() * candidates.length)];
            const cell = document.querySelector(`.grid-cell[data-row='${hint.r}'][data-col='${hint.c}']`);
            updateCellState(cell, 'fill');
            checkCompleted(); checkWin();
        } else {
            UI.showAlert("알림", "사용할 힌트가 없습니다.");
            points++; updatePoints();
        }
        if (points <= 0 && !isGameFinished) triggerGameOver();
    });

    const cellSize = calculateCellSize();
    drawBoard(cellSize);
    updatePoints();
    updateMode();
    requestAnimationFrame(() => {
        fitBoardToScreen();
        window.addEventListener('resize', fitBoardToScreen);
    });
});