import { Flex, Box } from "@mantine/core";
import { Match } from "@/features/matches/types";
import { MatchCard } from "./match-card";
import { useEffect, useRef } from "react";

interface BracketProps {
  rounds: Match[][];
  orders: Record<number, number>;
  showControls?: boolean;
  groupConfig?: {
    num_groups: number;
    advance_per_group: number;
  };
  renderMatch?: (match: Match) => React.ReactNode;
  onMatchTap?: (match: Match) => void;
  selectedMatchLid?: number | null;
  nextUpMatchId?: string;
}

export const Bracket: React.FC<BracketProps> = ({
  rounds,
  orders,
  showControls,
  groupConfig,
  renderMatch,
  onMatchTap,
  selectedMatchLid,
  nextUpMatchId,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const svgRef = useRef<SVGSVGElement>(null);

  useEffect(() => {
    const updateConnectorLines = () => {
      if (!containerRef.current || !svgRef.current) return;

      const svg = svgRef.current;
      const container = containerRef.current;
      const flexContainer = container.querySelector('.bracket-flex-container') as HTMLElement;
      if (!flexContainer) return;

      svg.innerHTML = '';

      const flexRect = flexContainer.getBoundingClientRect();
      const containerRect = container.getBoundingClientRect();

      svg.style.width = `${flexContainer.scrollWidth}px`;
      svg.style.height = `${flexContainer.scrollHeight}px`;

      rounds.forEach((round, roundIndex) => {
        if (roundIndex === rounds.length - 1) return;

        const nextRound = rounds[roundIndex + 1];

        round.forEach((match, matchIndex) => {
          if (match.bye) return;

          const matchElement = container.querySelector(`[data-match-lid="${match.lid}"]`) as HTMLElement;
          if (!matchElement) return;

          const nextMatches = nextRound.filter(nextMatch =>
            !nextMatch.bye && (
              orders[nextMatch.home_from_lid] === match.order ||
              orders[nextMatch.away_from_lid] === match.order
            )
          );

          nextMatches.forEach(nextMatch => {
            const nextMatchElement = container.querySelector(`[data-match-lid="${nextMatch.lid}"]`) as HTMLElement;
            if (!nextMatchElement) return;

            const matchRect = matchElement.getBoundingClientRect();
            const nextMatchRect = nextMatchElement.getBoundingClientRect();

            const startX = matchRect.right - flexRect.left;
            const startY = matchRect.top + matchRect.height / 2 - flexRect.top;
            const endX = nextMatchRect.left - flexRect.left;
            const endY = nextMatchRect.top + nextMatchRect.height / 2 - flexRect.top;

            const midX = startX + (endX - startX) * 0.5;

            const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            const pathData = `M ${startX} ${startY} L ${midX} ${startY} L ${midX} ${endY} L ${endX} ${endY}`;

            path.setAttribute('d', pathData);
            path.setAttribute('stroke', 'var(--mantine-color-default-border)');
            path.setAttribute('stroke-width', '2');
            path.setAttribute('fill', 'none');
            path.setAttribute('stroke-linecap', 'round');
            path.setAttribute('stroke-linejoin', 'round');

            svg.appendChild(path);
          });
        });
      });
    };

    updateConnectorLines();

    const handleUpdate = () => {
      requestAnimationFrame(updateConnectorLines);
    };

    const scrollContainer = containerRef.current?.closest('.mantine-ScrollArea-viewport');
    scrollContainer?.addEventListener('scroll', handleUpdate);
    window.addEventListener('resize', handleUpdate);

    return () => {
      scrollContainer?.removeEventListener('scroll', handleUpdate);
      window.removeEventListener('resize', handleUpdate);
    };
  }, [rounds, orders]);

  return (
    <Box pos="relative" ref={containerRef}>
      <svg
        ref={svgRef}
        style={{
          position: 'absolute',
          top: 0,
          left: 0,
          width: '100%',
          height: '100%',
          pointerEvents: 'none',
          zIndex: 0,
        }}
      />
      <Flex direction="row" gap={24} justify="left" pos="relative" style={{ zIndex: 1 }} className="bracket-flex-container">
        {rounds.map((round, roundIndex) => (
          <Flex
            key={roundIndex}
            direction="column"
            align="center"
            pos="relative"
            gap={24}
            justify="space-around"
            p={24}
          >
            {round.map((match) =>
              match.bye ? (
                <div key={match.lid}></div>
              ) : (
                <div key={match.lid}>
                  {renderMatch ? (
                    renderMatch(match)
                  ) : (
                    <MatchCard
                      match={match}
                      orders={orders}
                      showControls={showControls}
                      groupConfig={groupConfig}
                      onTap={onMatchTap}
                      selected={selectedMatchLid === match.lid}
                      nextUpMatchId={nextUpMatchId}
                    />
                  )}
                </div>
              )
            )}
          </Flex>
        ))}
      </Flex>
    </Box>
  );
};
