'use client';

import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import {
  ArrowLeft,
  Undo2,
  Flag,
  AlertTriangle,
} from 'lucide-react';
import Link from 'next/link';
import { apiRequest } from '../../../lib/api';
import { subscribeToMatch } from '../../../lib/socket';
import { Badge } from '../../../components/Badge';
import { Button } from '../../../components/Button';
import { Modal } from '../../../components/Modal';

const RUNS = [0, 1, 2, 3, 4, 6];
const EXTRAS = [
  { type: 'WIDE', label: 'Wide' },
  { type: 'NO_BALL', label: 'No-Ball' },
  { type: 'BYE', label: 'Bye' },
  { type: 'LEG_BYE', label: 'Leg-Bye' },
  { type: 'OVERTHROW', label: 'Overthrow' },
] as const;
const WICKETS = [
  { kind: 'BOWLED', label: 'Bowled' },
  { kind: 'LBW', label: 'LBW' },
  { kind: 'CAUGHT', label: 'Caught' },
  { kind: 'WICKETKEEPER_CATCH', label: 'WK Catch' },
  { kind: 'STUMPING', label: 'Stumping' },
  { kind: 'RUN_OUT', label: 'Run Out' },
  { kind: 'HIT_WICKET', label: 'Hit Wicket' },
  { kind: 'RETIRED_HURT', label: 'Retired Hurt' },
] as const;

function newIdempotencyKey() {
  return `score-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
}

export default function LiveScoringConsolePage() {
  const params = useParams();
  const router = useRouter();
  const matchId = params.matchId as string;

  const [match, setMatch] = useState<any>(null);
  const [innings, setInnings] = useState<any[]>([]);
  const [latestBalls, setLatestBalls] = useState<any[]>([]);
  const [commentary, setCommentary] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');
  const [commentaryText, setCommentaryText] = useState('');
  const [strikerId, setStrikerId] = useState('');
  const [nonStrikerId, setNonStrikerId] = useState('');
  const [bowlerId, setBowlerId] = useState('');
  const [completeOpen, setCompleteOpen] = useState(false);
  const [winType, setWinType] = useState<'RUNS' | 'WICKETS' | 'TIE' | 'NO_RESULT'>('RUNS');
  const [winMargin, setWinMargin] = useState(1);
  const [winnerTeamId, setWinnerTeamId] = useState('');
  const undoLock = useRef(false);

  const loadMatch = useCallback(async () => {
    try {
      const res = await apiRequest(`/matches/${matchId}`);
      const m = res.data.match;
      setMatch(m);
      setInnings(res.data.innings || []);
      setLatestBalls(res.data.latestBalls || []);
      setCommentary(res.data.commentary || []);

      // Seed player selectors from last ball or playing XI defaults
      const last = res.data.latestBalls?.[0];
      if (last) {
        setStrikerId(String(last.strikerId?._id || last.strikerId || ''));
        setNonStrikerId(String(last.nonStrikerId?._id || last.nonStrikerId || ''));
        setBowlerId(String(last.bowlerId?._id || last.bowlerId || ''));
      } else if (m.players?.length >= 3) {
        const teamA = m.players.filter((p: any) => String(p.teamId) === String(m.teamA.teamId));
        const teamB = m.players.filter((p: any) => String(p.teamId) === String(m.teamB.teamId));
        setStrikerId(String(teamA[0]?.playerId || ''));
        setNonStrikerId(String(teamA[1]?.playerId || ''));
        setBowlerId(String(teamB[0]?.playerId || ''));
      }
      if (!winnerTeamId) setWinnerTeamId(String(m.teamA?.teamId || ''));
      setError('');
    } catch (err: any) {
      setError(err.message || 'Failed to load match');
    } finally {
      setLoading(false);
    }
  }, [matchId, winnerTeamId]);

  useEffect(() => {
    loadMatch();
  }, [matchId]);

  useEffect(() => {
    if (!matchId) return;
    return subscribeToMatch(matchId, () => {
      loadMatch();
    });
  }, [matchId, loadMatch]);

  const readOnly = match?.status === 'COMPLETED';
  const scoringLocked =
    match?.status === 'SCHEDULED' &&
    Date.now() < new Date(match.startTime).getTime() - 30 * 60 * 1000;

  const players = match?.players || [];
  const battingPlayers = players.filter(
    (p: any) =>
      String(p.teamId) ===
      String(match?.currentInning === 1 ? match.teamA.teamId : match.teamB.teamId)
  );
  const bowlingPlayers = players.filter(
    (p: any) =>
      String(p.teamId) ===
      String(match?.currentInning === 1 ? match.teamB.teamId : match.teamA.teamId)
  );

  const scoreBall = async (payload: Record<string, unknown>) => {
    if (!match || busy || readOnly || scoringLocked) return;
    if (!strikerId || !nonStrikerId || !bowlerId) {
      setError('Select striker, non-striker, and bowler before scoring.');
      return;
    }
    setBusy(true);
    setError('');
    try {
      const res = await apiRequest('/scoring/ball', {
        method: 'POST',
        idempotencyKey: newIdempotencyKey(),
        body: JSON.stringify({
          matchId,
          expectedVersion: match.version,
          strikerId,
          nonStrikerId,
          bowlerId,
          commentaryText: commentaryText || undefined,
          ...payload,
        }),
      });
      setCommentaryText('');
      // Prefer server payload; reload for full scorecard
      if (res.data?.match) setMatch(res.data.match);
      await loadMatch();
    } catch (err: any) {
      setError(err.message || 'Scoring failed');
      if (err.code === 'VERSION_CONFLICT' || err.code === 'CONCURRENT_MODIFICATION') {
        await loadMatch();
      }
    } finally {
      setBusy(false);
    }
  };

  const handleUndo = async () => {
    if (!match || busy || readOnly || undoLock.current) return;
    if (!confirm('Undo the last ball? This restores the previous official state.')) return;
    undoLock.current = true;
    setBusy(true);
    setError('');
    try {
      await apiRequest('/scoring/undo', {
        method: 'POST',
        idempotencyKey: newIdempotencyKey(),
        body: JSON.stringify({ matchId, expectedVersion: match.version }),
      });
      await loadMatch();
    } catch (err: any) {
      setError(err.message || 'Undo failed');
      await loadMatch();
    } finally {
      setBusy(false);
      setTimeout(() => {
        undoLock.current = false;
      }, 800);
    }
  };

  const handleComplete = async () => {
    if (!match) return;
    setBusy(true);
    try {
      await apiRequest('/scoring/complete', {
        method: 'POST',
        idempotencyKey: newIdempotencyKey(),
        body: JSON.stringify({
          matchId,
          expectedVersion: match.version,
          winnerTeamId: winType === 'TIE' || winType === 'NO_RESULT' ? undefined : winnerTeamId,
          winMargin,
          winType,
          description: `${winType} by ${winMargin}`,
        }),
      });
      setCompleteOpen(false);
      await loadMatch();
    } catch (err: any) {
      setError(err.message || 'Failed to complete match');
    } finally {
      setBusy(false);
    }
  };

  if (loading) {
    return (
      <div className="flex-1 flex items-center justify-center text-xs text-zinc-400 p-12">
        Loading match console...
      </div>
    );
  }

  if (!match) {
    return (
      <div className="max-w-lg mx-auto p-8 text-center space-y-4">
        <p className="text-sm text-rose-400">{error || 'Match not found'}</p>
        <Button variant="secondary" onClick={() => router.push('/scorer')}>
          Back to dashboard
        </Button>
      </div>
    );
  }

  const scoreLine = (team: any) =>
    `${team.shortName} ${team.score?.runs || 0}/${team.score?.wickets || 0} (${team.score?.overs || 0}.${team.score?.balls || 0})`;

  return (
    <div className="max-w-6xl mx-auto w-full p-4 md:p-6 space-y-5">
      <div className="flex flex-col sm:flex-row sm:items-start justify-between gap-3">
        <div className="space-y-1">
          <Link
            href="/scorer"
            className="inline-flex items-center gap-1.5 text-xs text-zinc-400 hover:text-white"
          >
            <ArrowLeft className="w-3.5 h-3.5" />
            Assigned matches
          </Link>
          <h1 className="text-xl font-bold text-white tracking-tight">{match.title}</h1>
          <div className="flex flex-wrap items-center gap-2 text-xs text-zinc-400">
            <Badge
              variant={
                match.status === 'LIVE' ? 'rose' : match.status === 'COMPLETED' ? 'emerald' : 'amber'
              }
            >
              {match.status}
            </Badge>
            <span>v{match.version}</span>
            <span>·</span>
            <span>{match.venue}</span>
            <span>·</span>
            <span>Innings {match.currentInning}</span>
          </div>
        </div>
        {!readOnly && (
          <Button variant="danger" size="sm" className="gap-1.5" onClick={() => setCompleteOpen(true)}>
            <Flag className="w-3.5 h-3.5" />
            Complete Match
          </Button>
        )}
      </div>

      {/* Scoreboard */}
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
        <div className="bg-zinc-900/80 border border-zinc-800 rounded-2xl p-4">
          <div className="text-[11px] uppercase tracking-wider text-zinc-500 mb-1">Team A</div>
          <div className="text-2xl font-bold font-mono text-white">{scoreLine(match.teamA)}</div>
        </div>
        <div className="bg-zinc-900/80 border border-zinc-800 rounded-2xl p-4">
          <div className="text-[11px] uppercase tracking-wider text-zinc-500 mb-1">Team B</div>
          <div className="text-2xl font-bold font-mono text-white">{scoreLine(match.teamB)}</div>
        </div>
      </div>

      {(scoringLocked || readOnly) && (
        <div className="flex items-start gap-2 rounded-xl border border-amber-800/40 bg-amber-950/30 px-4 py-3 text-xs text-amber-200">
          <AlertTriangle className="w-4 h-4 shrink-0 mt-0.5" />
          <span>
            {readOnly
              ? 'Match is completed and locked. Only authorized Admin can correct.'
              : 'Scoring is locked until the permitted pre-match window (30 minutes before start).'}
          </span>
        </div>
      )}

      {error && (
        <div className="rounded-xl border border-rose-800/40 bg-rose-950/30 px-4 py-3 text-xs text-rose-300">
          {error}
        </div>
      )}

      {!readOnly && !scoringLocked && (
        <>
          {/* Player selectors */}
          <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
            {[
              { label: 'Striker', value: strikerId, set: setStrikerId, list: battingPlayers },
              { label: 'Non-striker', value: nonStrikerId, set: setNonStrikerId, list: battingPlayers },
              { label: 'Bowler', value: bowlerId, set: setBowlerId, list: bowlingPlayers },
            ].map((sel) => (
              <div key={sel.label}>
                <label className="block text-[11px] font-medium text-zinc-400 mb-1.5 uppercase tracking-wider">
                  {sel.label}
                </label>
                <select
                  value={sel.value}
                  onChange={(e) => sel.set(e.target.value)}
                  disabled={busy}
                  className="w-full px-3 py-2 bg-zinc-900 border border-zinc-800 rounded-xl text-sm text-white focus:outline-none focus:border-amber-500"
                >
                  <option value="">Select…</option>
                  {sel.list.map((p: any) => (
                    <option key={String(p.playerId)} value={String(p.playerId)}>
                      {p.name} ({p.role})
                    </option>
                  ))}
                </select>
              </div>
            ))}
          </div>

          {/* Runs */}
          <div className="space-y-2">
            <div className="text-[11px] font-semibold uppercase tracking-wider text-zinc-400">Runs</div>
            <div className="grid grid-cols-6 gap-2">
              {RUNS.map((r) => (
                <button
                  key={r}
                  disabled={busy}
                  onClick={() => scoreBall({ runsBatter: r })}
                  className={`h-14 rounded-xl font-bold text-lg border transition-all active:scale-95 disabled:opacity-50 ${
                    r === 4 || r === 6
                      ? 'bg-emerald-600/90 border-emerald-400/40 text-white hover:bg-emerald-500'
                      : 'bg-zinc-900 border-zinc-700 text-white hover:border-amber-500/50'
                  }`}
                >
                  {r}
                </button>
              ))}
            </div>
          </div>

          {/* Extras */}
          <div className="space-y-2">
            <div className="text-[11px] font-semibold uppercase tracking-wider text-zinc-400">Extras</div>
            <div className="flex flex-wrap gap-2">
              {EXTRAS.map((ex) => (
                <button
                  key={ex.type}
                  disabled={busy}
                  onClick={() =>
                    scoreBall({
                      runsBatter: 0,
                      runsExtra: 1,
                      extraType: ex.type,
                    })
                  }
                  className="px-3.5 py-2.5 rounded-xl text-xs font-semibold bg-cyan-950/50 border border-cyan-800/40 text-cyan-300 hover:bg-cyan-900/50 disabled:opacity-50"
                >
                  {ex.label}
                </button>
              ))}
            </div>
          </div>

          {/* Wickets */}
          <div className="space-y-2">
            <div className="text-[11px] font-semibold uppercase tracking-wider text-zinc-400">Wickets</div>
            <div className="flex flex-wrap gap-2">
              {WICKETS.map((w) => (
                <button
                  key={w.kind}
                  disabled={busy}
                  onClick={() =>
                    scoreBall({
                      runsBatter: 0,
                      isWicket: true,
                      wicketKind: w.kind,
                      playerDismissedId: strikerId,
                    })
                  }
                  className="px-3.5 py-2.5 rounded-xl text-xs font-semibold bg-rose-950/50 border border-rose-800/40 text-rose-300 hover:bg-rose-900/50 disabled:opacity-50"
                >
                  {w.label}
                </button>
              ))}
            </div>
          </div>

          {/* Commentary + Undo */}
          <div className="flex flex-col sm:flex-row gap-3 items-stretch sm:items-end">
            <div className="flex-1">
              <label className="block text-[11px] font-medium text-zinc-400 mb-1.5">
                Commentary (optional)
              </label>
              <input
                value={commentaryText}
                onChange={(e) => setCommentaryText(e.target.value)}
                placeholder="e.g. Driven through covers…"
                disabled={busy}
                className="w-full px-3.5 py-2.5 bg-zinc-900 border border-zinc-800 rounded-xl text-sm text-white placeholder-zinc-500 focus:outline-none focus:border-amber-500"
              />
            </div>
            <Button
              variant="secondary"
              className="gap-1.5 shrink-0"
              disabled={busy || !latestBalls.length}
              onClick={handleUndo}
            >
              <Undo2 className="w-4 h-4" />
              Undo Last Ball
            </Button>
          </div>
        </>
      )}

      {/* Recent balls & commentary */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
        <div className="bg-zinc-900/80 border border-zinc-800 rounded-2xl p-4">
          <h3 className="text-xs font-semibold uppercase tracking-wider text-zinc-400 mb-3">
            Recent Balls
          </h3>
          {latestBalls.length === 0 ? (
            <p className="text-xs text-zinc-500">No balls recorded yet.</p>
          ) : (
            <ul className="space-y-2">
              {latestBalls.map((b) => (
                <li
                  key={b._id}
                  className="flex items-center justify-between text-xs border-b border-zinc-800/60 pb-2 last:border-0"
                >
                  <span className="font-mono text-zinc-300">
                    {b.overNumber}.{b.ballNumber}
                  </span>
                  <span className="text-white font-semibold">
                    {b.isWicket ? `W (${b.wicketKind})` : b.extraType !== 'NONE' ? b.extraType : b.runsBatter}
                  </span>
                  <span className="text-zinc-500 truncate max-w-[40%]">
                    {b.bowlerId?.name || '—'} → {b.strikerId?.name || '—'}
                  </span>
                </li>
              ))}
            </ul>
          )}
        </div>
        <div className="bg-zinc-900/80 border border-zinc-800 rounded-2xl p-4">
          <h3 className="text-xs font-semibold uppercase tracking-wider text-zinc-400 mb-3">
            Commentary
          </h3>
          {commentary.length === 0 ? (
            <p className="text-xs text-zinc-500">No commentary yet.</p>
          ) : (
            <ul className="space-y-2 max-h-56 overflow-y-auto">
              {commentary.map((c) => (
                <li key={c._id} className="text-xs text-zinc-300 leading-relaxed">
                  <span className="font-mono text-amber-400/80 mr-2">
                    {c.overNumber}.{c.ballNumber}
                  </span>
                  {c.text}
                </li>
              ))}
            </ul>
          )}
        </div>
      </div>

      {innings.length > 0 && (
        <div className="text-xs text-zinc-500">
          Innings totals:{' '}
          {innings
            .map(
              (inn) =>
                `I${inn.inningNumber}: ${inn.totalRuns}/${inn.totalWickets} (${inn.totalOvers}.${inn.totalBalls})`
            )
            .join(' · ')}
        </div>
      )}

      <Modal isOpen={completeOpen} onClose={() => setCompleteOpen(false)} title="Complete Match">
        <div className="space-y-4">
          <p className="text-xs text-zinc-400">
            Completing locks the match. Scorer editing will be permanently disabled.
          </p>
          <div>
            <label className="block text-xs text-zinc-400 mb-1.5">Result type</label>
            <select
              value={winType}
              onChange={(e) => setWinType(e.target.value as any)}
              className="w-full px-3.5 py-2 bg-zinc-950 border border-zinc-800 rounded-xl text-sm text-white"
            >
              <option value="RUNS">Won by runs</option>
              <option value="WICKETS">Won by wickets</option>
              <option value="TIE">Tie</option>
              <option value="NO_RESULT">No result</option>
            </select>
          </div>
          {winType !== 'TIE' && winType !== 'NO_RESULT' && (
            <>
              <div>
                <label className="block text-xs text-zinc-400 mb-1.5">Winner</label>
                <select
                  value={winnerTeamId}
                  onChange={(e) => setWinnerTeamId(e.target.value)}
                  className="w-full px-3.5 py-2 bg-zinc-950 border border-zinc-800 rounded-xl text-sm text-white"
                >
                  <option value={match.teamA.teamId}>{match.teamA.name}</option>
                  <option value={match.teamB.teamId}>{match.teamB.name}</option>
                </select>
              </div>
              <div>
                <label className="block text-xs text-zinc-400 mb-1.5">Margin</label>
                <input
                  type="number"
                  min={1}
                  value={winMargin}
                  onChange={(e) => setWinMargin(Number(e.target.value))}
                  className="w-full px-3.5 py-2 bg-zinc-950 border border-zinc-800 rounded-xl text-sm text-white"
                />
              </div>
            </>
          )}
          <div className="flex justify-end gap-2">
            <Button variant="ghost" onClick={() => setCompleteOpen(false)}>
              Cancel
            </Button>
            <Button variant="danger" loading={busy} onClick={handleComplete}>
              Lock & Complete
            </Button>
          </div>
        </div>
      </Modal>
    </div>
  );
}
