import { router } from '@inertiajs/react';
import { ChevronRight, Lock, Pencil, Plus, Trash2 } from 'lucide-react';
import { useMemo, useState } from 'react';
import ChartOfAccountController from '@/actions/App/Http/Controllers/Admin/ChartOfAccountController';
import { ConfirmDialog } from '@/components/confirm-dialog';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Collapsible,
    CollapsibleContent,
    CollapsibleTrigger,
} from '@/components/ui/collapsible';
import { cn } from '@/lib/utils';

export type ChartOfAccountRow = {
    id: number;
    code: string;
    label: string;
    class: number;
    account_type: string;
    normal_balance: string;
    parent_id: number | null;
    is_system: boolean;
    is_postable: boolean;
    is_active: boolean;
};

type TreeNode = ChartOfAccountRow & { children: TreeNode[] };

function buildTree(accounts: ChartOfAccountRow[]): TreeNode[] {
    const nodesById = new Map<number, TreeNode>();

    for (const account of accounts) {
        nodesById.set(account.id, { ...account, children: [] });
    }

    const roots: TreeNode[] = [];

    for (const node of nodesById.values()) {
        if (node.parent_id === null) {
            roots.push(node);
            continue;
        }

        const parent = nodesById.get(node.parent_id);

        if (parent) {
            parent.children.push(node);
        } else {
            roots.push(node);
        }
    }

    return roots;
}

function AccountTypeBadge({ type }: { type: string }) {
    const labels: Record<string, string> = {
        asset: 'Actif',
        liability: 'Passif',
        equity: 'Capitaux propres',
        revenue: 'Produit',
        expense: 'Charge',
    };

    return (
        <Badge variant="outline" className="text-xs font-normal">
            {labels[type] ?? type}
        </Badge>
    );
}

function TreeNodeRow({
    node,
    depth,
    onCreateChild,
    onEdit,
    canCreate,
    canUpdate,
    canDelete,
}: {
    node: TreeNode;
    depth: number;
    onCreateChild: (parent: TreeNode) => void;
    onEdit: (node: TreeNode) => void;
    canCreate: boolean;
    canUpdate: boolean;
    canDelete: boolean;
}) {
    const [open, setOpen] = useState(depth === 0);
    const hasChildren = node.children.length > 0;

    return (
        <div>
            <Collapsible open={open} onOpenChange={setOpen}>
                <div
                    className={cn(
                        'group flex items-center gap-2 rounded-md px-2 py-1.5 hover:bg-muted/50',
                        !node.is_active && 'opacity-50',
                    )}
                    style={{ paddingLeft: `${depth * 1.5 + 0.5}rem` }}
                >
                    <CollapsibleTrigger asChild>
                        <button
                            type="button"
                            className={cn(
                                'flex size-5 shrink-0 items-center justify-center rounded hover:bg-muted',
                                !hasChildren && 'invisible',
                            )}
                        >
                            <ChevronRight
                                className={cn(
                                    'size-3.5 transition-transform',
                                    open && 'rotate-90',
                                )}
                            />
                        </button>
                    </CollapsibleTrigger>

                    <span className="font-mono text-sm font-medium tabular-nums">
                        {node.code}
                    </span>
                    <span
                        className={cn(
                            'flex-1 truncate text-sm',
                            !node.is_postable && 'text-muted-foreground italic',
                        )}
                    >
                        {node.label}
                    </span>

                    {!node.is_postable && (
                        <Badge
                            variant="secondary"
                            className="text-xs font-normal"
                        >
                            Structurel
                        </Badge>
                    )}
                    <AccountTypeBadge type={node.account_type} />
                    {node.is_system ? (
                        <Badge
                            variant="outline"
                            className="gap-1 text-xs font-normal text-muted-foreground"
                        >
                            <Lock className="size-3" />
                            Système
                        </Badge>
                    ) : (
                        <Badge className="text-xs font-normal">
                            Personnalisé
                        </Badge>
                    )}

                    <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100">
                        {canCreate && (
                            <Button
                                type="button"
                                variant="ghost"
                                size="icon"
                                className="size-7"
                                aria-label={`Ajouter un sous-compte sous ${node.code}`}
                                onClick={() => onCreateChild(node)}
                            >
                                <Plus className="size-3.5" />
                            </Button>
                        )}
                        {canUpdate && !node.is_system && (
                            <Button
                                type="button"
                                variant="ghost"
                                size="icon"
                                className="size-7"
                                aria-label={`Modifier ${node.code}`}
                                onClick={() => onEdit(node)}
                            >
                                <Pencil className="size-3.5" />
                            </Button>
                        )}
                        {canDelete && !node.is_system && !hasChildren && (
                            <ConfirmDialog
                                trigger={
                                    <Button
                                        type="button"
                                        variant="ghost"
                                        size="icon"
                                        className="size-7 text-destructive hover:text-destructive"
                                        aria-label={`Supprimer ${node.code}`}
                                    >
                                        <Trash2 className="size-3.5" />
                                    </Button>
                                }
                                title={`Supprimer le compte ${node.code} ?`}
                                description="Cette action est irréversible."
                                confirmLabel="Supprimer"
                                onConfirm={() => {
                                    router.delete(
                                        ChartOfAccountController.destroy.url(
                                            node.id,
                                        ),
                                        { preserveScroll: true },
                                    );
                                }}
                            />
                        )}
                    </div>
                </div>

                {hasChildren && (
                    <CollapsibleContent>
                        {node.children.map((child) => (
                            <TreeNodeRow
                                key={child.id}
                                node={child}
                                depth={depth + 1}
                                onCreateChild={onCreateChild}
                                onEdit={onEdit}
                                canCreate={canCreate}
                                canUpdate={canUpdate}
                                canDelete={canDelete}
                            />
                        ))}
                    </CollapsibleContent>
                )}
            </Collapsible>
        </div>
    );
}

export function ChartOfAccountTree({
    accounts,
    onCreateChild,
    onEdit,
    canCreate,
    canUpdate,
    canDelete,
}: {
    accounts: ChartOfAccountRow[];
    onCreateChild: (parent: ChartOfAccountRow) => void;
    onEdit: (account: ChartOfAccountRow) => void;
    canCreate: boolean;
    canUpdate: boolean;
    canDelete: boolean;
}) {
    const tree = useMemo(() => buildTree(accounts), [accounts]);

    if (tree.length === 0) {
        return (
            <p className="rounded-lg border border-dashed py-8 text-center text-sm text-muted-foreground">
                Aucun compte dans le plan comptable.
            </p>
        );
    }

    return (
        <div className="rounded-xl border p-2">
            {tree.map((node) => (
                <TreeNodeRow
                    key={node.id}
                    node={node}
                    depth={0}
                    onCreateChild={onCreateChild}
                    onEdit={onEdit}
                    canCreate={canCreate}
                    canUpdate={canUpdate}
                    canDelete={canDelete}
                />
            ))}
        </div>
    );
}
