<!--
  -   This file is a part of the SteamWar software.
  -
  -   Copyright (C) 2025 SteamWar.de-Serverteam
  -
  -   This program is free software: you can redistribute it and/or modify
  -   it under the terms of the GNU Affero General Public License as published by
  -   the Free Software Foundation, either version 3 of the License, or
  -   (at your option) any later version.
  -
  -   This program is distributed in the hope that it will be useful,
  -   but WITHOUT ANY WARRANTY; without even the implied warranty of
  -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  -   GNU Affero General Public License for more details.
  -
  -   You should have received a copy of the GNU Affero General Public License
  -   along with this program.  If not, see <https://www.gnu.org/licenses/>.
  -->

<script lang="ts">
    import FightEditRow from "./FightEditRow.svelte";

    import type { EventFightEdit, ExtendedEvent } from "@type/event";
    import { createSvelteTable, FlexRender } from "@components/ui/data-table";
    import { type ColumnFiltersState, getCoreRowModel, getFilteredRowModel, getGroupedRowModel, getSortedRowModel, type RowSelectionState, type SortingState } from "@tanstack/table-core";
    import { columns } from "./columns";
    import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@components/ui/table";
    import { Checkbox } from "@components/ui/checkbox";
    import { Menubar, MenubarContent, MenubarItem, MenubarGroup, MenubarGroupHeading, MenubarMenu, MenubarTrigger, MenubarSub, MenubarSubTrigger, MenubarSubContent } from "@components/ui/menubar";
    import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@components/ui/dialog";
    import FightEdit from "@components/moderator/components/FightEdit.svelte";
    import { Button } from "@components/ui/button";
    import { eventRepo } from "@components/repo/event";
    import GroupEditDialog from "./GroupEditDialog.svelte";
    import GroupResultsDialog from "./GroupResultsDialog.svelte";
    import type { ResponseGroups } from "@type/event";
    import { EditIcon, GroupIcon, LinkIcon } from "lucide-svelte";
    import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@components/ui/dropdown-menu";

    let { data = $bindable() }: { data: ExtendedEvent } = $props();

    let fights = $state(data.fights);
    let groups = $state(data.groups);

    let sorting = $state<SortingState>([]);
    let columnFilters = $state<ColumnFiltersState>([]);
    let selection = $state<RowSelectionState>({});

    const table = createSvelteTable({
        get data() {
            return fights;
        },
        initialState: {
            columnOrder: ["auswahl", "begegnung", "group"],
        },
        state: {
            get sorting() {
                return sorting;
            },
            get columnFilters() {
                return columnFilters;
            },
            get grouping() {
                return ["group"];
            },
            get rowSelection() {
                return selection;
            },
        },
        onSortingChange: (updater) => {
            if (typeof updater === "function") {
                sorting = updater(sorting);
            } else {
                sorting = updater;
            }
        },
        onColumnFiltersChange: (updater) => {
            if (typeof updater === "function") {
                columnFilters = updater(columnFilters);
            } else {
                columnFilters = updater;
            }
        },
        onRowSelectionChange: (updater) => {
            if (typeof updater === "function") {
                selection = updater(selection);
            } else {
                selection = updater;
            }
        },
        columns,
        getCoreRowModel: getCoreRowModel(),
        getSortedRowModel: getSortedRowModel(),
        getFilteredRowModel: getFilteredRowModel(),
        getGroupedRowModel: getGroupedRowModel(),
        groupedColumnMode: "remove",
        getRowId: (row) => row.id.toString(),
    });

    let createOpen = $state(false);
    let editGroupOpen = $state(false);
    let selectedGroup: ResponseGroups | null = $state(null);
    let groupResultsOpen = $state(false);
    let selectedGroupForResults: ResponseGroups | null = $state(null);

    async function handleSave(fight: EventFightEdit) {
        await $eventRepo.createFight(data.event.id.toString(), {
            ...fight,
            blueTeam: fight.blueTeam.id,
            redTeam: fight.redTeam.id,
        });

        reload();
        createOpen = false;
    }

    function openGroupEditDialog(group: ResponseGroups) {
        selectedGroup = group;
        editGroupOpen = true;
    }

    function openGroupResultsDialog(group: ResponseGroups) {
        selectedGroupForResults = group;
        groupResultsOpen = true;
    }

    async function reload() {
        fights = await $eventRepo.listFights(data.event.id.toString());
    }
</script>

<Dialog bind:open={createOpen}>
    <DialogContent>
        <DialogHeader>
            <DialogTitle>Fight Erstellen</DialogTitle>
            <DialogDescription>Hier kannst du einen neuen Fight erstellen</DialogDescription>
        </DialogHeader>
        <FightEdit fight={null} teams={data.teams} event={data.event} groups={data.groups} onSave={handleSave}>
            {#snippet actions(dirty, submit)}
                <DialogFooter>
                    <Button disabled={!dirty} onclick={submit}>Speichern</Button>
                </DialogFooter>
            {/snippet}
        </FightEdit>
    </DialogContent>
</Dialog>

{#if selectedGroup}
    <GroupEditDialog bind:open={editGroupOpen} group={selectedGroup} event={data.event} bind:groups />
{/if}

{#if selectedGroupForResults}
    <GroupResultsDialog bind:open={groupResultsOpen} group={selectedGroupForResults} teams={data.teams} {fights} />
{/if}

<div class="flex items-center justify-between">
    <Menubar>
        <MenubarMenu>
            <MenubarTrigger>Mehrfach Bearbeiten</MenubarTrigger>
            <MenubarContent>
                <MenubarItem disabled>Gruppe Ändern</MenubarItem>
                <MenubarItem disabled>Startzeit Verschieben</MenubarItem>
                <MenubarItem disabled>Spectate Port Ändern</MenubarItem>
            </MenubarContent>
        </MenubarMenu>
        <MenubarMenu>
            <MenubarTrigger>Erstellen</MenubarTrigger>
            <MenubarContent>
                <MenubarItem onclick={() => (createOpen = true)}>Fight Erstellen</MenubarItem>
                <MenubarGroup>
                    <MenubarGroupHeading>Generatoren</MenubarGroupHeading>
                    <MenubarItem disabled>Gruppenphase</MenubarItem>
                    <MenubarItem disabled>K.O. Phase</MenubarItem>
                </MenubarGroup>
            </MenubarContent>
        </MenubarMenu>
        <MenubarMenu>
            <MenubarTrigger disabled={!groups.length}>Gruppen</MenubarTrigger>
            <MenubarContent>
                {#each groups as group (group.id)}
                    <MenubarSub>
                        <MenubarSubTrigger>
                            {group.name}
                        </MenubarSubTrigger>
                        <MenubarSubContent>
                            <MenubarItem onclick={() => openGroupEditDialog(group)}>Bearbeiten</MenubarItem>
                            <MenubarItem onclick={() => openGroupResultsDialog(group)}>Gruppen Ergebnisse</MenubarItem>
                        </MenubarSubContent>
                    </MenubarSub>
                {/each}
            </MenubarContent>
        </MenubarMenu>
    </Menubar>
    <Button variant="outline" class="ml-4" onclick={reload}>Neu laden</Button>
</div>

<Table>
    <TableHeader>
        {#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
            <TableRow>
                {#each headerGroup.headers as header (header.id)}
                    <TableHead>
                        {#if !header.isPlaceholder}
                            <FlexRender content={header.column.columnDef.header} context={header.getContext()} />
                        {/if}
                    </TableHead>
                {/each}
            </TableRow>
        {/each}
    </TableHeader>
    <TableBody>
        {#each table.getRowModel().rows as groupRow (groupRow.id)}
            {#if groupRow.getIsGrouped()}
                {@const group = groups.find((g) => g.id == groupRow.getValue("group"))}
                <TableRow class="font-bold">
                    <TableCell colspan={columns.length - 1}>
                        <Checkbox
                            checked={groupRow.getIsSelected()}
                            indeterminate={groupRow.getIsSomeSelected() && !groupRow.getIsSelected()}
                            onCheckedChange={() => groupRow.toggleSelected()}
                            class="mr-4"
                        />
                        {group?.name ?? "Keine Gruppe"}
                    </TableCell>
                    <TableCell class="text-right">
                        <Button variant="ghost" size="icon" onclick={() => openGroupEditDialog(group)}>
                            <EditIcon />
                        </Button>
                        <Button variant="ghost" size="icon" onclick={() => openGroupResultsDialog(group)}>
                            <GroupIcon />
                        </Button>
                        <DropdownMenu>
                            <DropdownMenuTrigger>
                                <Button variant="ghost" size="icon">
                                    <LinkIcon />
                                </Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent>
                                <DropdownMenuItem
                                    onclick={() => navigator.clipboard.writeText(`<group-table data-event="${data.event.id}"${group ? ` data-group="${group?.id}"` : ""}> </group-table>`)}
                                    >Punkte Tabelle</DropdownMenuItem
                                >
                                <DropdownMenuItem
                                    onclick={() => navigator.clipboard.writeText(`<fight-table data-event="${data.event.id}"${group ? ` data-group="${group?.id}"` : ""}> </group-table>`)}
                                    >Kampf Tabelle</DropdownMenuItem
                                >
                            </DropdownMenuContent>
                        </DropdownMenu>
                    </TableCell>
                </TableRow>
                {#each groupRow.subRows as row (row.id)}
                    <TableRow data-state={row.getIsSelected() && "selected"}>
                        {#each row.getVisibleCells() as cell (cell.id)}
                            <TableCell>
                                <FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
                            </TableCell>
                        {/each}
                        <TableCell class="text-right">
                            <FightEditRow fight={row.original} teams={data.teams} bind:groups event={data.event} onupdate={(update) => (fights = fights.map((v) => (v.id === update.id ? update : v)))}
                            ></FightEditRow>
                        </TableCell>
                    </TableRow>
                {/each}
            {:else}
                <TableRow data-state={groupRow.getIsSelected() && "selected"}>
                    {#each groupRow.getVisibleCells() as cell (cell.id)}
                        <TableCell>
                            <FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
                        </TableCell>
                    {/each}
                </TableRow>
            {/if}
        {:else}
            <TableRow>
                <TableCell colspan={columns.length} class="h-24 text-center">No results.</TableCell>
            </TableRow>
        {/each}
    </TableBody>
</Table>
