// frontend/src/components/Bracket/BracketView.tsx

import React, { useEffect, useRef, useState } from 'react';
import { ZoomIn, ZoomOut } from 'lucide-react';
import { type MatchData } from '../../types';
import Podium from "../Tournament/Podium";
import MatchCard from "./MatchCard";

interface BracketViewProps {
    matches: MatchData[];
    onMatchClick: (match: MatchData) => void;
}

export default function BracketView({ matches, onMatchClick }: BracketViewProps) {
    const containerRef = useRef<HTMLDivElement>(null);
    const [lines, setLines] = useState<React.ReactElement[]>([]);
    const [zoom, setZoom] = useState<number>(1);
    const [contentSize, setContentSize] = useState({ width: 0, height: 0 });

    useEffect(() => {
        const draw = () => {
            if (!containerRef.current) return;

            // Measure the unscaled bracket size to fix scrollbars later
            setContentSize({
                width: containerRef.current.scrollWidth,
                height: containerRef.current.scrollHeight
            });

            const container = containerRef.current.getBoundingClientRect();
            const newLines: React.ReactElement[] = [];

            matches.forEach(m => {
                if (m.winner_next_match_id) {
                    const sEl = document.getElementById(`match-${m.id}`);
                    const eEl = document.getElementById(`match-${m.winner_next_match_id}`);
                    if (sEl && eEl) {
                        const r1 = sEl.getBoundingClientRect(), r2 = eEl.getBoundingClientRect();

                        const sx = (r1.right - container.left) / zoom;
                        const sy = (r1.top + r1.height / 2 - container.top) / zoom;
                        const ex = (r2.left - container.left) / zoom;
                        const ey = (r2.top + r2.height / 2 - container.top) / zoom;
                        const c1 = sx + (ex - sx) / 2;

                        newLines.push(
                            <path key={`w-${m.id}`} d={`M ${sx} ${sy} C ${c1} ${sy}, ${c1} ${ey}, ${ex} ${ey}`} className="stroke-zinc-400/70 dark:stroke-zinc-700/70 print:stroke-zinc-400! fill-none stroke-[2px]" />
                        );
                    }
                }

                if (m.loser_next_match_id) {
                    const targetMatch = matches.find(x => x.id === m.loser_next_match_id);
                    if (targetMatch && targetMatch.bracket === 'Finals') {
                        const sEl = document.getElementById(`match-${m.id}`);
                        const eEl = document.getElementById(`match-${targetMatch.id}`);
                        if (sEl && eEl) {
                            const r1 = sEl.getBoundingClientRect(), r2 = eEl.getBoundingClientRect();

                            const sx = (r1.right - container.left) / zoom;
                            const sy = (r1.top + r1.height / 2 - container.top) / zoom;
                            const ex = (r2.left - container.left) / zoom;
                            const ey = (r2.top + r2.height / 2 - container.top) / zoom;
                            const c1 = sx + (ex - sx) / 2;

                            newLines.push(
                                <path key={`l-${m.id}`} strokeDasharray="6 6" d={`M ${sx} ${sy} C ${c1} ${sy}, ${c1} ${ey}, ${ex} ${ey}`} className="stroke-zinc-300 dark:stroke-zinc-700 print:stroke-zinc-400! fill-none stroke-[1.5px]" />
                            );
                        }
                    }
                }
            });
            setLines(newLines);
        };

        const t = setTimeout(draw, 50);
        window.addEventListener('resize', draw);

        const handlePrint = () => { draw(); setTimeout(draw, 100); };
        const mql = window.matchMedia('print');
        mql.addEventListener('change', handlePrint);
        window.addEventListener('beforeprint', handlePrint);
        window.addEventListener('afterprint', draw);

        return () => {
            clearTimeout(t);
            window.removeEventListener('resize', draw);
            mql.removeEventListener('change', handlePrint);
            window.removeEventListener('beforeprint', handlePrint);
            window.removeEventListener('afterprint', draw);
        };
    }, [matches, zoom]);

    const renderRound = (list: MatchData[]) => {
        const rounds: Record<number, MatchData[]> = {};
        list.forEach(m => (rounds[m.round] = rounds[m.round] || []).push(m));

        const roundKeys = Object.keys(rounds).map(Number).sort((a, b) => a - b);

        return roundKeys.map((r) => {
            const matchesInRound = rounds[r];
            matchesInRound.sort((a, b) => a.number - b.number);
            return (
                <div key={r} className="flex flex-col gap-10 z-10 w-64 shrink-0 justify-around">
                    {matchesInRound.map(m => <MatchCard key={m.id} match={m} onClick={onMatchClick} />)}
                </div>
            );
        });
    };

    const isDoubleElim = matches.some(m => m.bracket === 'Loser');
    const wb = matches.filter(m => m.bracket === 'Winner');
    const lb = matches.filter(m => m.bracket === 'Loser');
    const finals = matches.filter(m => m.bracket === 'Finals');

    const displayWb = [...wb];
    const displayFinals = [...finals];

    if (!isDoubleElim && displayWb.length > 0) {
        const maxRound = Math.max(...displayWb.map(m => m.round));
        const gfIndex = displayWb.findIndex(m => m.round === maxRound);

        if (gfIndex !== -1) {
            const gfMatch = displayWb.splice(gfIndex, 1)[0];
            displayFinals.unshift(gfMatch);
        }
    }

    return (
        <div className="relative w-full h-full flex flex-col overflow-hidden bg-zinc-50 dark:bg-zinc-950 print:bg-white!">

            {/* FLOATING ZOOM CONTROLS (Moved to top-6 to completely avoid theme button) */}
            <div className="absolute top-6 right-6 flex flex-col gap-3 z-50 print:hidden">
                <button
                    onClick={() => setZoom(z => Math.min(1, z + 0.1))}
                    disabled={zoom >= 1}
                    className="p-3 bg-white dark:bg-zinc-800 rounded-full shadow-lg shadow-black/5 border border-zinc-200 dark:border-zinc-700 text-zinc-600 dark:text-zinc-300 disabled:opacity-30 hover:text-orange-500 hover:border-orange-500 transition active:scale-90"
                    title="Zoom In"
                >
                    <ZoomIn size={20} strokeWidth={2.5} />
                </button>
                <button
                    onClick={() => setZoom(z => Math.max(0.3, z - 0.1))}
                    disabled={zoom <= 0.3}
                    className="p-3 bg-white dark:bg-zinc-800 rounded-full shadow-lg shadow-black/5 border border-zinc-200 dark:border-zinc-700 text-zinc-600 dark:text-zinc-300 disabled:opacity-30 hover:text-orange-500 hover:border-orange-500 transition active:scale-90"
                    title="Zoom Out"
                >
                    <ZoomOut size={20} strokeWidth={2.5} />
                </button>
            </div>

            <div className="flex-1 overflow-auto bg-[radial-gradient(var(--color-zinc-300)_1px,transparent_1px)] dark:bg-[radial-gradient(var(--color-zinc-800)_1px,transparent_1px)] bg-size-[20px_20px] print:bg-none!">
                <style>
                    {`@media print { 
                        @page { size: landscape; margin: 0.5cm; }
                        body { -webkit-print-color-adjust: exact; print-color-adjust: exact; background: white !important; }
                    }`}
                </style>

                {/* SIZER WRAPPER (Dynamically scales width/height to fix the scrollbar ghost space) */}
                <div style={{
                    width: contentSize.width ? `${contentSize.width * zoom}px` : 'max-content',
                    height: contentSize.height ? `${contentSize.height * zoom}px` : 'max-content'
                }}>
                    {/* SCALING WRAPPER */}
                    <div
                        className="origin-top-left print:transform-none! w-max h-max"
                        style={{ transform: `scale(${zoom})` }}
                    >
                        {/* Added pt-16 md:pt-20 to ensure absolute titles aren't clipped
                        */}
                        <div ref={containerRef} className="relative min-w-max min-h-full pt-16 md:pt-20 px-6 md:px-12 pb-40 md:pb-32 flex gap-12 md:gap-20 items-center">
                            <svg className="absolute inset-0 w-full h-full pointer-events-none z-0 print:overflow-visible">
                                {lines}
                            </svg>

                            <div className="flex flex-col gap-24">
                                <div className="relative">
                                    <div className="absolute -top-8 left-0 text-[10px] font-black uppercase tracking-[0.2em] text-zinc-400 print:text-black!">Winners Bracket</div>
                                    <div className="flex gap-20">{renderRound(displayWb)}</div>
                                </div>
                                {isDoubleElim && (
                                    <div className="relative pt-8 border-t border-dashed border-zinc-300 dark:border-zinc-800 print:border-zinc-400!">
                                        <div className="absolute top-4 left-0 text-[10px] font-black uppercase tracking-[0.2em] text-zinc-400 print:text-black!">Losers Bracket</div>
                                        <div className="flex gap-20 mt-4">{renderRound(lb)}</div>
                                    </div>
                                )}
                            </div>

                            <div className="flex flex-col justify-center gap-6 z-10">
                                {displayFinals.length > 0 && (
                                    <div className="relative flex flex-col gap-6">
                                        <div className="absolute -top-10 left-1/2 -translate-x-1/2 text-[10px] font-black uppercase bg-orange-100 dark:bg-orange-900/30 text-orange-600 print:bg-transparent! print:border-black! print:text-black! px-4 py-1.5 rounded-full border border-orange-200 dark:border-orange-800 shadow-sm whitespace-nowrap">
                                            Championship
                                        </div>
                                        {displayFinals.map(m => <MatchCard key={m.id} match={m} onClick={onMatchClick} />)}
                                    </div>
                                )}
                            </div>
                            <div className="flex flex-col justify-center gap-6 z-10">
                                <Podium matches={matches} />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
}