<script>
    import { onMount, onDestroy } from 'svelte';
    import { browser } from '$app/environment';
    import { gamesOverlay, hasGame, currentGame, gameMode } from '$lib/stores/gamesOverlay';
    import { nakama, ChessOpCode } from '$lib/stores/nakama';
    import { auth } from '$lib/stores/auth';

    // Chess state
    let game = null;
    let Chess = null;
    let boardSquares = [];
    let selectedSquare = null;
    let legalMoves = [];
    let moveHistory = [];

    // Match state from overlay store
    let myColor = null;

    // Drag state
    let isDragging = false;
    let dragOffset = { x: 0, y: 0 };
    let position = { x: null, y: null };
    let isResizing = false;
    let resizeDirection = '';
    let dimensions = { width: 450, height: 520 };
    let startDimensions = { width: 0, height: 0 };
    let startPos = { x: 0, y: 0 };

    // Callbacks cleanup
    let unsubscribeMatch = null;
    let isDestroyed = false;

    // Load/save position
    function loadPosition() {
        if (!browser) return;
        try {
            const saved = localStorage.getItem('chessGameOverlayPosition');
            if (saved) {
                const parsed = JSON.parse(saved);
                position = parsed.position || { x: null, y: null };
                dimensions = parsed.dimensions || { width: 450, height: 520 };
            }
        } catch (e) {}
    }

    function savePosition() {
        if (!browser) return;
        try {
            localStorage.setItem('chessGameOverlayPosition', JSON.stringify({
                position,
                dimensions
            }));
        } catch (e) {}
    }

    // Computed position (default to center-right if not set)
    $: computedPosition = {
        right: position.x === null ? '1rem' : 'auto',
        top: position.y === null ? '50%' : 'auto',
        left: position.x !== null ? `${position.x}px` : 'auto',
        bottom: position.y !== null ? `${position.y}px` : 'auto',
        transform: position.y === null ? 'translateY(-50%)' : 'none'
    };

    // Calculate chess board cell size based on container dimensions
    // Account for header (~45px), footer (~45px), board border/padding (~20px)
    $: cellSize = Math.floor(Math.min(dimensions.width - 30, dimensions.height - 120) / 8);

    async function initChess() {
        console.log('[ChessOverlay] initChess called, matchId:', $gamesOverlay.matchId);
        if (!browser) return;

        try {
            const chessModule = await import('chess.js');
            Chess = chessModule.Chess;
            game = new Chess();

            // Set up match event handler
            console.log('[ChessOverlay] Registering match event handler...');
            unsubscribeMatch = nakama.onMatchEvent(handleMatchEvent);
            console.log('[ChessOverlay] Handler registered');

            updateBoardDisplay();
        } catch (e) {
            console.error('[ChessOverlay] Failed to initialize chess:', e);
        }
    }

    function handleMatchEvent(type, data) {
        if (isDestroyed) return;

        console.log('[Chess] handleMatchEvent:', type, 'op_code:', data?.op_code);

        if (type === 'disconnect') {
            gamesOverlay.setMode('finished');
            gamesOverlay.updateState({ result: 'disconnect', reason: 'Disconnected from server' });
            return;
        }

        if (type !== 'matchdata') return;

        try {
            const payload = JSON.parse(new TextDecoder().decode(data.data));
            // Convert op_code to number for safe comparison (Nakama SDK uses snake_case)
            const opCode = Number(data.op_code);

            console.log('[Chess] Received op_code:', opCode, 'payload:', payload);

            if (opCode === ChessOpCode.GAME_STATE) {
                console.log('[Chess] Processing GAME_STATE with status:', payload.status);
                handleGameState(payload);
            } else if (opCode === ChessOpCode.MOVE) {
                handleOpponentMove(payload);
            } else if (opCode === ChessOpCode.GAME_OVER) {
                handleGameOver(payload);
            } else {
                console.log('[Chess] Unknown opCode:', opCode);
            }
        } catch (e) {
            console.error('Error handling match event:', e, data);
        }
    }

    function handleGameState(payload) {
        if (payload.status === 'waiting') {
            myColor = payload.yourColor;
            gamesOverlay.setMode('waiting');
            gamesOverlay.updateState({
                positionId: payload.positionId,
                whiteName: payload.whiteName,
                blackName: payload.blackName
            });
        } else if (payload.status === 'playing') {
            const session = nakama.getSession();
            myColor = payload.whiteId === session?.user_id ? 'w' : 'b';

            if (game) {
                game.load(payload.fen);
            }

            gamesOverlay.setMode('playing');
            gamesOverlay.updateState({
                positionId: payload.positionId,
                fen: payload.fen,
                turn: payload.turn || game?.turn(),
                whiteId: payload.whiteId,
                blackId: payload.blackId,
                whiteName: payload.whiteName,
                blackName: payload.blackName,
                myColor
            });

            updateBoardDisplay();
        } else if (payload.status === 'spectating') {
            myColor = null; // Spectator has no color

            if (game) {
                game.load(payload.fen);
            }

            gamesOverlay.setMode('spectating');
            gamesOverlay.updateState({
                positionId: payload.positionId,
                fen: payload.fen,
                turn: payload.turn || game?.turn(),
                whiteId: payload.whiteId,
                blackId: payload.blackId,
                whiteName: payload.whiteName,
                blackName: payload.blackName
            });

            updateBoardDisplay();
        }
    }

    function handleOpponentMove(payload) {
        if (game) {
            game.load(payload.fen);
        }
        moveHistory = [...moveHistory, payload.move];

        gamesOverlay.updateState({
            fen: payload.fen,
            turn: game?.turn()
        });

        updateBoardDisplay();
    }

    function handleGameOver(payload) {
        gamesOverlay.setMode('finished');
        gamesOverlay.updateState({
            result: payload.result,
            reason: payload.reason
        });
    }

    function updateBoardDisplay() {
        if (!game) return;

        const board2d = [];
        const files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
        // Spectators see from white's perspective, players see from their own side
        const viewColor = myColor || 'w';
        const ranks = viewColor === 'b' ? ['1', '2', '3', '4', '5', '6', '7', '8'] : ['8', '7', '6', '5', '4', '3', '2', '1'];

        for (const rank of ranks) {
            const row = [];
            for (const file of files) {
                const square = file + rank;
                const piece = game.get(square);
                row.push({
                    square,
                    piece: piece ? getPieceSymbol(piece) : null,
                    color: piece?.color || null,
                    isLight: (files.indexOf(file) + parseInt(rank)) % 2 === 1
                });
            }
            board2d.push(row);
        }

        boardSquares = board2d;
    }

    function getPieceSymbol(piece) {
        const symbols = {
            'wk': '\u2654', 'wq': '\u2655', 'wr': '\u2656', 'wb': '\u2657', 'wn': '\u2658', 'wp': '\u2659',
            'bk': '\u265A', 'bq': '\u265B', 'br': '\u265C', 'bb': '\u265D', 'bn': '\u265E', 'bp': '\u265F'
        };
        return symbols[piece.color + piece.type] || '';
    }

    function handleSquareClick(square) {
        if ($gameMode !== 'playing') return;
        if (!game || game.turn() !== myColor) return;

        const piece = game.get(square);

        if (selectedSquare) {
            if (legalMoves.includes(square)) {
                makeMove(selectedSquare, square);
            }
            selectedSquare = null;
            legalMoves = [];
        } else if (piece && piece.color === myColor) {
            selectedSquare = square;
            const moves = game.moves({ square, verbose: true });
            legalMoves = moves.map(m => m.to);
        }

        updateBoardDisplay();
    }

    async function makeMove(from, to) {
        if (!game) return;

        const piece = game.get(from);
        const isPromotion = piece.type === 'p' &&
            ((piece.color === 'w' && to[1] === '8') || (piece.color === 'b' && to[1] === '1'));

        const moveData = { from, to };
        if (isPromotion) {
            moveData.promotion = 'q';
        }

        const result = game.move(moveData);
        if (!result) {
            console.error('Invalid move');
            return;
        }

        await nakama.sendMatchData($gamesOverlay.matchId, ChessOpCode.MOVE, moveData);

        moveHistory = [...moveHistory, result];
        gamesOverlay.updateState({
            fen: game.fen(),
            turn: game.turn()
        });
        updateBoardDisplay();
    }

    async function resign() {
        if ($gameMode !== 'playing') return;
        if (confirm('Are you sure you want to resign?')) {
            await nakama.sendMatchData($gamesOverlay.matchId, ChessOpCode.RESIGN, {});
        }
    }

    function copyInviteLink() {
        const url = `${window.location.origin}/games/chess?match=${$gamesOverlay.matchId}`;
        navigator.clipboard.writeText(url).then(() => {
            alert('Invite link copied!');
        });
    }

    function handleClose() {
        if ($gamesOverlay.matchId) {
            nakama.leaveMatch($gamesOverlay.matchId);
        }

        if (unsubscribeMatch) {
            unsubscribeMatch();
            unsubscribeMatch = null;
        }

        game = null;
        boardSquares = [];
        selectedSquare = null;
        legalMoves = [];
        moveHistory = [];
        myColor = null;

        gamesOverlay.closeGame();
    }

    function handleMinimize() {
        gamesOverlay.toggleMinimized();
    }

    // Drag handling
    function startDrag(e) {
        if (e.target.closest('button')) return;

        isDragging = true;
        const rect = e.currentTarget.closest('.chess-overlay').getBoundingClientRect();
        dragOffset = {
            x: e.clientX - rect.left,
            y: e.clientY - rect.top
        };
        e.preventDefault();
    }

    function handleMouseMove(e) {
        if (isDragging) {
            position = {
                x: e.clientX - dragOffset.x,
                y: window.innerHeight - (e.clientY - dragOffset.y) - dimensions.height
            };
        } else if (isResizing) {
            const dx = e.clientX - startPos.x;
            const dy = e.clientY - startPos.y;

            let newWidth = startDimensions.width;
            let newHeight = startDimensions.height;

            if (resizeDirection.includes('e')) {
                newWidth = Math.max(400, startDimensions.width + dx);
            }
            if (resizeDirection.includes('w')) {
                newWidth = Math.max(400, startDimensions.width - dx);
            }
            if (resizeDirection.includes('s')) {
                newHeight = Math.max(450, startDimensions.height + dy);
            }
            if (resizeDirection.includes('n')) {
                newHeight = Math.max(450, startDimensions.height - dy);
            }

            dimensions = { width: newWidth, height: newHeight };
        }
    }

    function stopDrag() {
        if (isDragging || isResizing) {
            savePosition();
        }
        isDragging = false;
        isResizing = false;
        resizeDirection = '';
    }

    function startResize(e, direction) {
        e.preventDefault();
        e.stopPropagation();
        isResizing = true;
        resizeDirection = direction;
        startPos = { x: e.clientX, y: e.clientY };
        startDimensions = { ...dimensions };
    }

    // Watch for overlay changes
    let currentMatchId = null;
    $: if (browser && $gamesOverlay.enabled && $gamesOverlay.matchId && $gamesOverlay.matchId !== currentMatchId) {
        console.log('[ChessOverlay] Reactive: matchId changed from', currentMatchId, 'to', $gamesOverlay.matchId);
        currentMatchId = $gamesOverlay.matchId;
        initChess();
    }

    // Cleanup when game is closed
    $: if (!$hasGame) {
        currentMatchId = null;
        if (unsubscribeMatch) {
            unsubscribeMatch();
            unsubscribeMatch = null;
        }
        game = null;
        boardSquares = [];
        moveHistory = [];
        myColor = null;
    }

    onMount(() => {
        loadPosition();
        if (browser) {
            window.addEventListener('mousemove', handleMouseMove);
            window.addEventListener('mouseup', stopDrag);

            if ($gamesOverlay.enabled && $gamesOverlay.matchId) {
                currentMatchId = $gamesOverlay.matchId;
                initChess();
            }
        }
    });

    onDestroy(() => {
        isDestroyed = true;
        if (unsubscribeMatch) {
            unsubscribeMatch();
        }
        if (browser) {
            window.removeEventListener('mousemove', handleMouseMove);
            window.removeEventListener('mouseup', stopDrag);
        }
    });

    // Computed values for display
    $: statusMessage = (() => {
        switch ($gameMode) {
            case 'waiting': return 'Waiting for opponent...';
            case 'playing':
                if (!game) return 'Loading...';
                return game.turn() === myColor ? 'Your turn' : "Opponent's turn";
            case 'spectating':
                if (!$currentGame) return 'Spectating...';
                return `${$currentGame.turn === 'w' ? 'White' : 'Black'} to move`;
            case 'finished':
                return getResultText();
            default: return 'Connecting...';
        }
    })();

    function getResultText() {
        if (!$currentGame) return 'Game over';
        const result = $currentGame.result;
        const reason = $currentGame.reason || '';

        if ($gameMode === 'spectating') {
            if (result === '1-0') return `White wins${reason ? ` (${reason})` : ''}`;
            if (result === '0-1') return `Black wins${reason ? ` (${reason})` : ''}`;
            return `Draw${reason ? ` (${reason})` : ''}`;
        }

        if (result === '1-0') {
            return myColor === 'w' ? 'You win!' : 'You lose';
        } else if (result === '0-1') {
            return myColor === 'b' ? 'You win!' : 'You lose';
        } else if (result === 'timeout') {
            return reason || 'Match timed out';
        }
        return `Draw${reason ? ` (${reason})` : ''}`;
    }

    $: headerTitle = (() => {
        if (!$currentGame) return 'Chess960';
        const white = $currentGame.whiteName || 'Waiting...';
        const black = $currentGame.blackName || 'Waiting...';
        return `${white} vs ${black}`;
    })();

    $: positionLabel = $currentGame?.positionId !== undefined
        ? `#${$currentGame.positionId}`
        : '';
</script>

{#if $gamesOverlay.enabled && $gamesOverlay.matchId}
    <div
        class="chess-overlay"
        class:minimized={$gamesOverlay.minimized}
        style="
            {computedPosition.right !== 'auto' ? `right: ${computedPosition.right};` : ''}
            {computedPosition.top !== 'auto' ? `top: ${computedPosition.top};` : ''}
            {computedPosition.left !== 'auto' ? `left: ${computedPosition.left};` : ''}
            {computedPosition.bottom !== 'auto' ? `bottom: ${computedPosition.bottom};` : ''}
            {computedPosition.transform !== 'none' ? `transform: ${computedPosition.transform};` : ''}
            width: {dimensions.width}px;
            {!$gamesOverlay.minimized ? `height: ${dimensions.height}px;` : ''}
        "
    >
        <div class="overlay-header" on:mousedown={startDrag}>
            <div class="header-left">
                <span class="header-icon">♛</span>
                <div class="header-info">
                    <span class="header-title">{headerTitle}</span>
                    {#if positionLabel}
                        <span class="header-meta">Position {positionLabel}</span>
                    {/if}
                </div>
            </div>
            <div class="header-controls">
                {#if $gameMode === 'spectating'}
                    <span class="mode-badge spectator">Spectating</span>
                {/if}
                <button class="control-btn" on:click={handleMinimize} title={$gamesOverlay.minimized ? 'Expand' : 'Minimize'}>
                    {$gamesOverlay.minimized ? '□' : '−'}
                </button>
                <button class="control-btn close" on:click={handleClose} title="Close">×</button>
            </div>
        </div>

        {#if !$gamesOverlay.minimized}
            <div class="overlay-body">
                <!-- Status Bar -->
                <div class="status-bar" class:your-turn={$gameMode === 'playing' && game?.turn() === myColor}>
                    {#if $gameMode === 'playing' && myColor}
                        <span class="color-indicator" class:white={myColor === 'w'} class:black={myColor === 'b'}>
                            {myColor === 'w' ? 'White' : 'Black'}
                        </span>
                    {/if}
                    <span class="status-text">{statusMessage}</span>
                </div>

                <!-- Chess Board -->
                <div class="board-wrapper">
                    <div class="chess-board">
                        {#each boardSquares as row}
                            <div class="board-row">
                                {#each row as cell}
                                    <div
                                        class="board-cell"
                                        class:light={cell.isLight}
                                        class:dark={!cell.isLight}
                                        class:selected={selectedSquare === cell.square}
                                        class:legal-move={legalMoves.includes(cell.square)}
                                        class:clickable={$gameMode === 'playing'}
                                        style="width: {cellSize}px; height: {cellSize}px;"
                                        on:click={() => handleSquareClick(cell.square)}
                                    >
                                        {#if cell.piece}
                                            <span class="piece" style="font-size: {cellSize * 0.7}px;" class:white-piece={cell.color === 'w'} class:black-piece={cell.color === 'b'}>
                                                {cell.piece}
                                            </span>
                                        {/if}
                                    </div>
                                {/each}
                            </div>
                        {/each}
                    </div>
                </div>
            </div>

            <div class="overlay-footer">
                {#if $gameMode === 'waiting'}
                    <button class="action-btn" on:click={copyInviteLink}>Copy Invite Link</button>
                {:else if $gameMode === 'playing'}
                    <button class="action-btn danger" on:click={resign}>Resign</button>
                {:else if $gameMode === 'finished'}
                    <button class="action-btn" on:click={handleClose}>Close</button>
                {/if}

                <div class="move-count">
                    {moveHistory.length} moves
                </div>
            </div>

            <!-- Resize handles -->
            <div class="resize-handle resize-e" on:mousedown={(e) => startResize(e, 'e')}></div>
            <div class="resize-handle resize-s" on:mousedown={(e) => startResize(e, 's')}></div>
            <div class="resize-handle resize-se" on:mousedown={(e) => startResize(e, 'se')}></div>
            <div class="resize-handle resize-w" on:mousedown={(e) => startResize(e, 'w')}></div>
            <div class="resize-handle resize-sw" on:mousedown={(e) => startResize(e, 'sw')}></div>
        {/if}
    </div>
{/if}

<style>
    .chess-overlay {
        position: fixed;
        background: #161b22;
        border: 1px solid #30363d;
        border-radius: 8px;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
        z-index: 9998;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
        min-width: 400px;
        min-height: 450px;
        max-width: calc(100vw - 2rem);
        max-height: calc(100vh - 2rem);
    }

    .chess-overlay.minimized {
        height: auto !important;
        min-height: auto;
    }

    .overlay-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0.5rem 0.75rem;
        background: #0d1117;
        border-bottom: 1px solid #30363d;
        cursor: move;
        flex-shrink: 0;
    }

    .header-left {
        display: flex;
        align-items: center;
        gap: 0.6rem;
        min-width: 0;
        flex: 1;
    }

    .header-icon {
        font-size: 1.2rem;
        color: #f59e0b;
    }

    .header-info {
        display: flex;
        flex-direction: column;
        gap: 0.1rem;
        min-width: 0;
    }

    .header-title {
        color: #c9d1d9;
        font-size: 0.75rem;
        font-weight: 500;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .header-meta {
        color: #6e7681;
        font-size: 0.65rem;
    }

    .header-controls {
        display: flex;
        align-items: center;
        gap: 0.4rem;
        flex-shrink: 0;
    }

    .mode-badge {
        font-size: 0.6rem;
        padding: 0.15rem 0.4rem;
        border-radius: 3px;
        font-weight: 500;
    }

    .mode-badge.spectator {
        background: rgba(139, 92, 246, 0.2);
        color: #a78bfa;
    }

    .control-btn {
        width: 22px;
        height: 22px;
        border: none;
        background: none;
        color: #8b949e;
        font-size: 1rem;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 4px;
        transition: all 0.15s ease;
    }

    .control-btn:hover {
        background: rgba(255, 255, 255, 0.1);
        color: #c9d1d9;
    }

    .control-btn.close:hover {
        color: #f85149;
    }

    .overlay-body {
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        padding: 0.5rem;
        gap: 0.5rem;
    }

    .status-bar {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0.4rem 0.6rem;
        background: #1a1a2e;
        border-radius: 4px;
        flex-shrink: 0;
    }

    .status-bar.your-turn {
        background: #2a4a2a;
    }

    .color-indicator {
        font-weight: bold;
        font-size: 0.7rem;
        padding: 0.15rem 0.4rem;
        border-radius: 3px;
    }

    .color-indicator.white {
        background: #fff;
        color: #000;
    }

    .color-indicator.black {
        background: #333;
        color: #fff;
    }

    .status-text {
        color: #ccc;
        font-size: 0.75rem;
    }

    .board-wrapper {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 0;
    }

    .chess-board {
        display: flex;
        flex-direction: column;
        border: 3px solid #333;
        background: #333;
    }

    .board-row {
        display: flex;
    }

    .board-cell {
        width: 42px;
        height: 42px;
        display: flex;
        align-items: center;
        justify-content: center;
        position: relative;
    }

    .board-cell.clickable {
        cursor: pointer;
    }

    .board-cell.light {
        background: #f0d9b5;
    }

    .board-cell.dark {
        background: #b58863;
    }

    .board-cell.selected {
        background: #7fc97f !important;
    }

    .board-cell.legal-move::after {
        content: '';
        position: absolute;
        width: 30%;
        height: 30%;
        border-radius: 50%;
        background: rgba(0, 0, 0, 0.2);
    }

    .board-cell.legal-move:hover {
        background: #aad4aa !important;
    }

    .piece {
        font-size: 2rem;
        line-height: 1;
        user-select: none;
    }

    .white-piece {
        color: #fff;
        text-shadow: 0 0 2px #000;
    }

    .black-piece {
        color: #000;
        text-shadow: 0 0 2px #fff;
    }

    .overlay-footer {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0.5rem 0.75rem;
        background: #0d1117;
        border-top: 1px solid #30363d;
        flex-shrink: 0;
    }

    .action-btn {
        padding: 0.4rem 0.8rem;
        border: 1px solid #30363d;
        background: #161b22;
        color: #c9d1d9;
        font-size: 0.7rem;
        cursor: pointer;
        border-radius: 4px;
        transition: all 0.15s ease;
    }

    .action-btn:hover {
        background: #21262d;
        border-color: #484f58;
    }

    .action-btn.danger {
        border-color: rgba(248, 81, 73, 0.4);
        color: #f85149;
    }

    .action-btn.danger:hover {
        background: rgba(248, 81, 73, 0.15);
        border-color: #f85149;
    }

    .move-count {
        color: #6e7681;
        font-size: 0.65rem;
    }

    /* Resize handles */
    .resize-handle {
        position: absolute;
        background: transparent;
    }

    .resize-e {
        top: 0;
        right: 0;
        width: 6px;
        height: 100%;
        cursor: ew-resize;
    }

    .resize-w {
        top: 0;
        left: 0;
        width: 6px;
        height: 100%;
        cursor: ew-resize;
    }

    .resize-s {
        bottom: 0;
        left: 0;
        width: 100%;
        height: 6px;
        cursor: ns-resize;
    }

    .resize-se {
        bottom: 0;
        right: 0;
        width: 12px;
        height: 12px;
        cursor: se-resize;
    }

    .resize-sw {
        bottom: 0;
        left: 0;
        width: 12px;
        height: 12px;
        cursor: sw-resize;
    }

    .resize-handle:hover {
        background: rgba(245, 158, 11, 0.3);
    }

    @media (max-width: 500px) {
        .chess-overlay {
            right: 0.5rem !important;
            left: 0.5rem !important;
            top: auto !important;
            bottom: 0.5rem !important;
            width: auto !important;
            transform: none !important;
            max-width: none;
        }

        .board-cell {
            width: 36px;
            height: 36px;
        }

        .piece {
            font-size: 1.7rem;
        }

        .resize-handle {
            display: none;
        }
    }
</style>
