import { Head, setLayoutProps } from '@inertiajs/react';
import { useEffect, useMemo, useState } from 'react';
import { CategoryActionsMenu } from '@/components/categories/category-actions-menu';
import { CategoryFormDialog } from '@/components/categories/category-form-dialog';
import {
    createAppColumnHelper,
    DataTable,
    DataTableColumnHeader,
} from '@/components/data-table';
import type { useServerTable } from '@/components/data-table/use-server-table';
import { Button } from '@/components/ui/button';
import { expense, income } from '@/routes/categories';
import type {
    CategoriesIndexProps,
    CategoryRow,
    CategoryType,
} from '@/types/category';
import { categoryPageTitle, categoryTypeLabel } from '@/types/category';

const columnHelper = createAppColumnHelper<CategoryRow>();

type CategoryTableColumns = Parameters<
    typeof useServerTable<CategoryRow>
>[0]['columns'];

function indexUrlForType(categoryType: CategoryType) {
    switch (categoryType) {
        case 'income':
            return income.url;
        case 'expense':
            return expense.url;
    }
}

function indexRouteForType(categoryType: CategoryType) {
    switch (categoryType) {
        case 'income':
            return income;
        case 'expense':
            return expense;
    }
}

export default function CategoriesIndex({
    categories,
    query,
    categoryType,
    parents,
}: CategoriesIndexProps) {
    const [createOpen, setCreateOpen] = useState(false);
    const [editingCategory, setEditingCategory] = useState<CategoryRow | null>(
        null,
    );

    const columns = useMemo(() => {
        return [
            columnHelper.accessor('name', {
                header: ({ column }) => (
                    <DataTableColumnHeader title="Name" column={column} />
                ),
                cell: ({ row }) => (
                    <div className="flex items-center gap-2">
                        <span
                            className="size-3 shrink-0 rounded-full border"
                            style={{
                                backgroundColor:
                                    row.original.color ?? 'transparent',
                            }}
                        />
                        <span>{row.original.name}</span>
                    </div>
                ),
                enableSorting: true,
            }),
            columnHelper.display({
                id: 'parent',
                header: 'Parent',
                cell: ({ row }) => row.original.parent?.name ?? '—',
            }),
            columnHelper.accessor('icon', {
                header: 'Icon',
                cell: ({ getValue }) => getValue() ?? '—',
                enableSorting: false,
            }),
            columnHelper.display({
                id: 'actions',
                header: 'Actions',
                cell: ({ row }) => (
                    <CategoryActionsMenu
                        category={row.original}
                        onEdit={() => setEditingCategory(row.original)}
                    />
                ),
            }),
        ] as CategoryTableColumns;
    }, []);

    const indexRoute = indexRouteForType(categoryType);
    const pageTitle = categoryPageTitle(categoryType);

    useEffect(() => {
        setLayoutProps({
            breadcrumbs: [
                {
                    title: pageTitle,
                    href: indexRoute(),
                },
            ],
        });
    }, [indexRoute, pageTitle]);

    return (
        <>
            <Head title={pageTitle} />

            <div className="flex h-full flex-1 flex-col gap-4 p-4">
                <div className="flex items-center justify-between">
                    <div>
                        <h1 className="text-2xl font-semibold tracking-tight">
                            {pageTitle}
                        </h1>
                        <p className="text-sm text-muted-foreground">
                            Manage your{' '}
                            {categoryTypeLabel(categoryType).toLowerCase()}{' '}
                            categories.
                        </p>
                    </div>
                    <Button onClick={() => setCreateOpen(true)}>
                        Create Category
                    </Button>
                </div>

                <DataTable
                    columns={columns}
                    paginator={categories}
                    query={query}
                    url={(params) => indexUrlForType(categoryType)(params)}
                    reload={['categories', 'query', 'parents']}
                />
            </div>

            <CategoryFormDialog
                open={createOpen}
                onOpenChange={setCreateOpen}
                categoryType={categoryType}
                parents={parents}
            />

            <CategoryFormDialog
                open={editingCategory !== null}
                onOpenChange={(open) => {
                    if (!open) {
                        setEditingCategory(null);
                    }
                }}
                categoryType={categoryType}
                parents={parents}
                category={editingCategory}
            />
        </>
    );
}
