<script lang="ts">
    import type { ExtendedEvent, EventFight, ResponseGroups, ResponseRelation } from "@type/event.ts";
    import type { EleminationViewConfig } from "./types";
    import EventCard from "./EventCard.svelte";
    import EventFightChip from "./EventFightChip.svelte";
    import { onMount, onDestroy, tick } from "svelte";
    import { FightConnector, fightConnector } from "./connections.svelte.ts";

    const { event, config }: { event: ExtendedEvent; config: EleminationViewConfig } = $props();

    const defaultGroup: ResponseGroups = {
        id: -1,
        name: "Elimination",
        pointsPerWin: 0,
        pointsPerLoss: 0,
        pointsPerDraw: 0,
        type: "ELIMINATION_STAGE",
        points: null,
    };

    function buildStages(ev: ExtendedEvent, finalFightId: number): EventFight[][] {
        const fightMap = new Map<number, EventFight>(ev.fights.map((f) => [f.id, f]));
        const relationsByFight = new Map<number, ResponseRelation[]>();
        for (const rel of ev.relations) {
            const list = relationsByFight.get(rel.fight) ?? [];
            list.push(rel);
            relationsByFight.set(rel.fight, list);
        }

        const finalFight = fightMap.get(finalFightId);
        if (!finalFight) return [];

        const stages: EventFight[][] = [];
        let currentLayer: EventFight[] = [finalFight];
        const visited = new Set<number>([finalFight.id]);

        while (currentLayer.length) {
            stages.push(currentLayer);
            const nextLayer: EventFight[] = [];
            for (const fight of currentLayer) {
                const rels = relationsByFight.get(fight.id) ?? [];
                for (const rel of rels) {
                    if (rel.type === "FIGHT" && rel.fromFight) {
                        const src = fightMap.get(rel.fromFight.id) ?? rel.fromFight;
                        if (src && !visited.has(src.id)) {
                            visited.add(src.id);
                            nextLayer.push(src);
                        }
                    }
                }
            }
            currentLayer = nextLayer;
        }

        stages.reverse();

        return stages;
    }

    function stageName(index: number, fights: EventFight[]): string {
        const count = fights.length;
        switch (count) {
            case 1:
                return `Finale`;
            case 2:
                return "Halbfinale";
            case 4:
                return "Viertelfinale";
            case 8:
                return "Achtelfinale";
            case 16:
                return "Sechzehntelfinale";
            default:
                return `Runde ${index + 1}`;
        }
    }

    const stages = $derived(buildStages(event, config.finalFight));

    const connector = $fightConnector;

    onDestroy(() => {
        connector.clearAllConnections();
    });

    function buildConnections() {
        if (!connector) return;
        connector.clearConnections();

        for (const rel of event.relations) {
            if (rel.type !== "FIGHT" || !rel.fromFight) continue;
            const fromEl = document.getElementById(`fight-${rel.fromFight.id}`) as HTMLElement | null;
            const toEl = document.getElementById(`fight-${rel.fight}-team-${rel.team.toLowerCase()}`) as HTMLElement | null;
            if (fromEl && toEl) {
                connector.addConnection(fromEl, toEl, "#9ca3af");
            }
        }
    }

    onMount(async () => {
        await tick();
        buildConnections();
    });
</script>

{#if stages.length === 0}
    <p class="text-gray-400 italic">Keine Eliminationsdaten gefunden.</p>
{:else}
    <div class="flex gap-12">
        {#each stages as stage, index}
            <div class="flex flex-col justify-center">
                <EventCard title={stageName(index, stage)}>
                    {#each stage as fight}
                        <EventFightChip {fight} group={fight.group ?? defaultGroup} />
                    {/each}
                </EventCard>
            </div>
        {/each}
    </div>
{/if}
