"use client";

import React, { useState, useCallback, useMemo, useEffect } from 'react';
import { cn } from '@/lib/utils';
import { ChessIcon } from './ChessIcon';
import { Button } from '@/components/ui/button';
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { pieceMap } from '../shared/Helpers';

type Piece = string | null;
type Board = Piece[][];
type Move = { from: { r: number, c: number }, to: { r: number, c: number }, notation: string };

const initialBoard: Board = [
  ['br', 'bn', 'bb', 'bq', 'bk', 'bb', 'bn', 'br'],
  ['bp', 'bp', 'bp', 'bp', 'bp', 'bp', 'bp', 'bp'],
  [null, null, null, null, null, null, null, null],
  [null, null, null, null, null, null, null, null],
  [null, null, null, null, null, null, null, null],
  [null, null, null, null, null, null, null, null],
  ['wp', 'wp', 'wp', 'wp', 'wp', 'wp', 'wp', 'wp'],
  ['wr', 'wn', 'wb', 'wq', 'wk', 'wb', 'wn', 'wr'],
];

// The "Opera Game" - Paul Morphy vs. Duke Karl / Count Isouard, 1858
const operaGameMoves: { white: Move, black?: Move }[] = [
    { white: { from: { r: 4, c: 4 }, to: { r: 4, c: 4 }, notation: "e4" }, black: { from: { r: 1, c: 4 }, to: { r: 3, c: 4 }, notation: "e5" } },
    { white: { from: { r: 7, c: 6 }, to: { r: 5, c: 5 }, notation: "Nf3" }, black: { from: { r: 1, c: 3 }, to: { r: 2, c: 3 }, notation: "d6" } },
    { white: { from: { r: 7, c: 3 }, to: { r: 3, c: 3 }, notation: "d4" }, black: { from: { r: 0, c: 5 }, to: { r: 4, c: 1 }, notation: "Bg4" } },
    { white: { from: { r: 3, c: 3 }, to: { r: 2, c: 4 }, notation: "dxe5" }, black: { from: { r: 4, c: 1 }, to: { r: 5, c: 2 }, notation: "Bxf3" } },
    { white: { from: { r: 7, c: 2 }, to: { r: 5, c: 2 }, notation: "Qxf3" }, black: { from: { r: 2, c: 4 }, to: { r: 3, c: 4 }, notation: "dxe5" } },
    { white: { from: { r: 7, c: 5 }, to: { r: 4, c: 2 }, notation: "Bc4" }, black: { from: { r: 0, c: 6 }, to: { r: 2, c: 5 }, notation: "Nf6" } },
    { white: { from: { r: 5, c: 2 }, to: { r: 1, c: 1 }, notation: "Qb3" }, black: { from: { r: 1, c: 4 }, to: { r: 2, c: 4 }, notation: "Qe7" } },
    { white: { from: { r: 7, c: 1 }, to: { r: 5, c: 2 }, notation: "Nc3" }, black: { from: { r: 1, c: 2 }, to: { r: 2, c: 2 }, notation: "c6" } },
    { white: { from: { r: 7, c: 0 }, to: { r: 5, c: 0 }, notation: "Bg5" }, black: { from: { r: 1, c: 1 }, to: { r: 2, c: 1 }, notation: "b5" } },
    { white: { from: { r: 5, c: 2 }, to: { r: 3, c: 1 }, notation: "Nxb5" }, black: { from: { r: 2, c: 2 }, to: { r: 3, c: 1 }, notation: "cxb5" } },
    { white: { from: { r: 4, c: 2 }, to: { r: 3, c: 1 }, notation: "Bxb5+" }, black: { from: { r: 0, c: 1 }, to: { r: 2, c: 3 }, notation: "Nbd7" } },
    { white: { from: { r: 7, c: 4 }, to: { r: 7, c: 2 }, notation: "O-O-O" }, black: { from: { r: 0, c: 0 }, to: { r: 3, c: 0 }, notation: "Rd8" } },
    { white: { from: { r: 7, c: 3 }, to: { r: 3, c: 0 }, notation: "Rxd7" }, black: { from: { r: 3, c: 0 }, to: { r: 3, c: 0 }, notation: "Rxd7" } },
    { white: { from: { r: 0, c: 3 }, to: { r: 3, c: 0 }, notation: "Rd1" }, black: { from: { r: 2, c: 4 }, to: { r: 4, c: 4 }, notation: "Qe6" } },
    { white: { from: { r: 3, c: 1 }, to: { r: 2, c: 3 }, notation: "Bxd7+" }, black: { from: { r: 2, c: 3 }, to: { r: 2, c: 3 }, notation: "Nxd7" } },
    { white: { from: { r: 1, c: 1 }, to: { r: 1, c: 7 }, notation: "Qb8+" }, black: { from: { r: 2, c: 3 }, to: { r: 1, c: 7 }, notation: "Nxb8" } },
    { white: { from: { r: 3, c: 0 }, to: { r: 0, c: 3 }, notation: "Rd8#" } }
];

// "The Traxler Variation" - Reinisch vs. Karel Traxler, 1890
const traxlerGameMoves: { white: Move; black?: Move }[] = [
  { white: { from: { r: 6, c: 4 }, to: { r: 4, c: 4 }, notation: "e4" }, black: { from: { r: 1, c: 4 }, to: { r: 3, c: 4 }, notation: "e5" } },
  { white: { from: { r: 7, c: 6 }, to: { r: 5, c: 5 }, notation: "Nf3" }, black: { from: { r: 0, c: 1 }, to: { r: 2, c: 2 }, notation: "Nc6" } },
  { white: { from: { r: 7, c: 5 }, to: { r: 4, c: 2 }, notation: "Bc4" }, black: { from: { r: 0, c: 6 }, to: { r: 2, c: 5 }, notation: "Nf6" } },
  { white: { from: { r: 5, c: 5 }, to: { r: 3, c: 6 }, notation: "Ng5" }, black: { from: { r: 0, c: 5 }, to: { r: 3, c: 2 }, notation: "Bc5" } },
  { white: { from: { r: 3, c: 6 }, to: { r: 1, c: 5 }, notation: "Nxf7" }, black: { from: { r: 3, c: 2 }, to: { r: 6, c: 5 }, notation: "Bxf2+" } },
  { white: { from: { r: 7, c: 4 }, to: { r: 6, c: 4 }, notation: "Ke2" }, black: { from: { r: 2, c: 2 }, to: { r: 4, c: 3 }, notation: "Nd4+" } },
  { white: { from: { r: 6, c: 4 }, to: { r: 5, c: 3 }, notation: "Kf1" }, black: { from: { r: 1, c: 1 }, to: { r: 3, c: 1 }, notation: "Qe7" } },
  { white: { from: { r: 4, c: 2 }, to: { r: 5, c: 1 }, notation: "Nc3" }, black: { from: { r: 2, c: 5 }, to: { r: 4, c: 4 }, notation: "c6" } },
  { white: { from: { r: 1, c: 5 }, to: { r: 0, c: 3 }, notation: "Nxe5" }, black: { from: { r: 4, c: 4 }, to: { r: 3, c: 2 }, notation: "Qxe5" } },
  { white: { from: { r: 5, c: 3 }, to: { r: 5, c: 2 }, notation: "Nxh8" }, black: { from: { r: 4, c: 3 }, to: { r: 6, c: 4 }, notation: "Qf4+" } },
  { white: { from: { r: 7, c: 3 }, to: { r: 6, c: 4 }, notation: "Ke1" }, black: { from: { r: 6, c: 5 }, to: { r: 4, c: 3 }, notation: "d5" } },
  { white: { from: { r: 5, c: 2 }, to: { r: 4, c: 1 }, notation: "Bxd5" }, black: { from: { r: 1, c: 0 }, to: { r: 3, c: 0 }, notation: "Qf2#" } },
  { white: { from: { r: 4, c: 1 }, to: { r: 3, c: 1 }, notation: "Nc3" }, black: { from: { r: 0, c: 2 }, to: { r: 2, c: 0 }, notation: "c6" } },
  { white: { from: { r: 3, c: 1 }, to: { r: 3, c: 0 }, notation: "Nxe5" }, black: { from: { r: 2, c: 0 }, to: { r: 5, c: 3 }, notation: "Qxe5" } },
  { white: { from: { r: 3, c: 0 }, to: { r: 4, c: 1 }, notation: "Nxh8" }, black: { from: { r: 3, c: 2 }, to: { r: 2, c: 0 }, notation: "Qf4+" } },
  { white: { from: { r: 4, c: 1 }, to: { r: 4, c: 0 }, notation: "Ke1" }, black: { from: { r: 2, c: 0 }, to: { r: 4, c: 1 }, notation: "d5" } },
  { white: { from: { r: 4, c: 0 }, to: { r: 4, c: 1 }, notation: "Bxd5" }, black: { from: { r: 1, c: 2 }, to: { r: 3, c: 2 }, notation: "Qf2#" } },
];

const games = [
  // {
  //   title: "The Opera Game",
  //   description: "Paul Morphy vs. Duke Karl / Count Isouard, 1858",
  //   moves: operaGameMoves,
  // },
  {
    title: "The Traxler Variation",
    description: "Reinisch vs. Karel Traxler, 1890",
    moves: traxlerGameMoves,
  },
];

const executeMove = (board: Board, from: {r: number, c: number}, to: {r: number, c: number}): Board => {
    const newBoard = board.map(r => [...r]);
    const piece = newBoard[from.r][from.c];
    newBoard[from.r][from.c] = null;
    newBoard[to.r][to.c] = piece;
    
    // Handle castling for this specific game
    if (piece === 'wk' && from.r === 7 && from.c === 4 && to.c === 2) { // white O-O-O
      newBoard[7][3] = newBoard[7][0];
      newBoard[7][0] = null;
    }
    return newBoard;
};

export function ClassicGameExplorer() {
  const [history, setHistory] = useState<Board[]>([initialBoard]);
  const [currentMove, setCurrentMove] = useState(0); // Index of the half-move
  const [currentGameIndex, setCurrentGameIndex] = useState(0);
  const currentGame = games[currentGameIndex];


  useEffect(() => {
    setHistory([initialBoard]);
    setCurrentMove(0);
  }, [currentGameIndex]);

  const fullMoves = useMemo(() => {
    const arr: Move[] = [];
    for (const move of currentGame.moves) {
      arr.push(move.white);
      if (move.black) arr.push(move.black);
    }
    return arr;
  }, [currentGame]);


  const board = history[currentMove] || initialBoard;

  const navigateTo = useCallback((moveIndex: number) => {
    if (moveIndex < 0 || moveIndex > fullMoves.length) return;

    if (moveIndex < history.length) {
      setCurrentMove(moveIndex);
      return;
    }
    
    let currentBoard = history[history.length - 1];
    const newHistory = [...history];
    for (let i = history.length; i < moveIndex + 1; i++) {
        const move = fullMoves[i-1];
        if(!move) continue;
        currentBoard = executeMove(currentBoard, move.from, move.to);
        newHistory.push(currentBoard);
    }
    setHistory(newHistory);
    setCurrentMove(moveIndex);
  }, [history, fullMoves]);

  return (
    <div className="flex flex-col md:flex-row gap-8 items-center justify-center">
      <div className="w-full max-w-md md:max-w-xl">
         <div className="grid grid-cols-8 aspect-square shadow-2xl rounded-lg overflow-hidden border-4 border-primary/50">
            {board.map((row, rowIndex) =>
              row.map((piece, colIndex) => (
                <div
                  key={`${rowIndex}-${colIndex}`}
                  className={cn(
                    'flex items-center justify-center aspect-square',
                    (rowIndex + colIndex) % 2 !== 0 ? 'bg-[#64676E]' : 'bg-white'
                  )}
                >
                  {piece && 
                    <ChessIcon 
                      piece={piece}
                      className="w-10 h-10 md:w-12 md:h-12 drop-shadow-md" 
                      alt="White King"
                      width={45}
                      height={45}
                      src={pieceMap(piece)}
                    />
                  }
                </div>
              ))
            )}
          </div>
      </div>
      <Card className="w-full max-w-md">
        <CardHeader className="flex items-center justify-between gap-2 flex-row">
          <Button
            variant="ghost"
            size="icon"
            onClick={() => setCurrentGameIndex((prev) => Math.max(prev - 1, 0))}
            disabled={currentGameIndex === 0}
          >
            <ChevronLeft />
          </Button>

          <div className="flex flex-col items-center flex-1 text-center">
            <CardTitle>{currentGame.title}</CardTitle>
            <CardDescription>{currentGame.description}</CardDescription>
          </div>

          <Button
            variant="ghost"
            size="icon"
            onClick={() => setCurrentGameIndex((prev) => Math.min(prev + 1, games.length - 1))}
            disabled={currentGameIndex === games.length - 1}
          >
            <ChevronRight />
          </Button>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="w-full bg-muted/50 p-4 rounded-md h-48 overflow-y-auto text-sm">
            <ol className="grid grid-cols-[auto,1fr,1fr] gap-x-4 gap-y-1">
              {currentGame.moves.map((move, index) => (
                <React.Fragment key={index}>
                  <li className="font-bold text-right pt-1">{index + 1}.</li>
                  <li className={cn("cursor-pointer hover:font-bold rounded px-2 py-1", currentMove === (index * 2 + 1) && "font-bold bg-accent text-accent-foreground")}>
                    {move.white.notation}
                  </li>
                  {move.black && (
                    <li className={cn("cursor-pointer hover:font-bold rounded px-2 py-1", currentMove === (index * 2 + 2) && "font-bold bg-accent text-accent-foreground")}>
                      {move.black.notation}
                    </li>
                  )}
                </React.Fragment>
              ))}
            </ol>
          </div>
          <div className="flex justify-center items-center gap-2">
            <Button onClick={() => navigateTo(0)} variant="outline" size="icon" disabled={currentMove === 0}><ChevronsLeft /></Button>
            <Button onClick={() => navigateTo(currentMove - 1)} variant="outline" size="icon" disabled={currentMove === 0}><ChevronLeft /></Button>
            <div className="font-mono text-center w-24">Move {currentMove}</div>
            <Button onClick={() => navigateTo(currentMove + 1)} variant="outline" size="icon" disabled={currentMove >= fullMoves.length}><ChevronRight /></Button>
            <Button onClick={() => navigateTo(fullMoves.length)} variant="outline" size="icon" disabled={currentMove >= fullMoves.length}><ChevronsRight /></Button>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
