import { Head, router, useForm } from '@inertiajs/react';
import { ClipboardList, Plus, Trash2, X } from 'lucide-react';
import { useState } from 'react';
import { ConfirmDialog } from '@/components/confirm-dialog';
import { EmptyState } from '@/components/empty-state';
import { PageHeader } from '@/components/page-header';
import { StatusBadge } from '@/components/status-badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
    DialogTrigger,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { destroy, store, update } from '@/routes/task-templates';

type Option = { value: number | string; label: string };

type Item = {
    id?: number;
    title: string;
    sort_order: number;
    due_offset_days: number | null;
    default_assignee_role: string | null;
};

type Template = {
    id: number;
    name: string;
    applies_to: string;
    is_active: boolean;
    items_count: number;
    items: Item[];
};

type Props = {
    templates: Template[];
    options: { matterTypes: Option[]; assigneeRoles: Option[] };
};

const ANY = 'any';
const NONE = 'none';

function TemplateForm({
    options,
    existing,
    trigger,
}: {
    options: Props['options'];
    existing?: Template;
    trigger: React.ReactNode;
}) {
    const [open, setOpen] = useState(false);
    const form = useForm({
        name: existing?.name ?? '',
        applies_to: existing?.applies_to && existing.applies_to !== 'Any matter type' ? existing.applies_to : '',
        is_active: existing?.is_active ?? true,
        items: (existing?.items ?? [{ title: '', sort_order: 0, due_offset_days: null, default_assignee_role: null }]) as Item[],
    });

    const setItem = (i: number, patch: Partial<Item>) => {
        form.setData('items', form.data.items.map((it, idx) => (idx === i ? { ...it, ...patch } : it)));
    };
    const addItem = () => form.setData('items', [...form.data.items, { title: '', sort_order: form.data.items.length, due_offset_days: null, default_assignee_role: null }]);
    const removeItem = (i: number) => form.setData('items', form.data.items.filter((_, idx) => idx !== i));

    const submit = (e: React.FormEvent) => {
        e.preventDefault();
        const url = existing ? update(existing.id).url : store().url;
        const method = existing ? form.patch : form.post;
        method(url, {
            preserveScroll: true,
            onSuccess: () => {
                setOpen(false);

                if (!existing) {
form.reset();
}
            },
        });
    };

    return (
        <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>{trigger}</DialogTrigger>
            <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-2xl">
                <DialogHeader>
                    <DialogTitle>{existing ? 'Edit checklist' : 'New checklist'}</DialogTitle>
                </DialogHeader>
                <form onSubmit={submit} className="grid gap-4">
                    <div className="grid gap-2 sm:grid-cols-2">
                        <div className="grid gap-2">
                            <Label htmlFor="tpl-name">Name</Label>
                            <Input id="tpl-name" value={form.data.name} onChange={(e) => form.setData('name', e.target.value)} required />
                            {form.errors.name && <p className="text-xs text-destructive">{form.errors.name}</p>}
                        </div>
                        <div className="grid gap-2">
                            <Label htmlFor="tpl-applies">Applies to</Label>
                            <Select value={form.data.applies_to || ANY} onValueChange={(v) => form.setData('applies_to', v === ANY ? '' : v)}>
                                <SelectTrigger id="tpl-applies"><SelectValue /></SelectTrigger>
                                <SelectContent>
                                    <SelectItem value={ANY}>Any matter type</SelectItem>
                                    {options.matterTypes.map((t) => (
                                        <SelectItem key={t.value} value={String(t.value)}>{t.label}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                    </div>

                    <div className="grid gap-2">
                        <Label>Checklist items</Label>
                        <div className="space-y-2">
                            {form.data.items.map((it, i) => (
                                <div key={i} className="flex flex-wrap items-end gap-2 rounded-lg border border-border p-2">
                                    <div className="grid flex-1 gap-1">
                                        <span className="text-xs text-muted-foreground">Title</span>
                                        <Input value={it.title} onChange={(e) => setItem(i, { title: e.target.value })} required />
                                    </div>
                                    <div className="grid w-24 gap-1">
                                        <span className="text-xs text-muted-foreground">Offset (days)</span>
                                        <Input
                                            type="number"
                                            min={0}
                                            value={it.due_offset_days ?? ''}
                                            onChange={(e) => setItem(i, { due_offset_days: e.target.value === '' ? null : Number(e.target.value) })}
                                        />
                                    </div>
                                    <div className="grid w-40 gap-1">
                                        <span className="text-xs text-muted-foreground">Assignee role</span>
                                        <Select
                                            value={it.default_assignee_role ?? NONE}
                                            onValueChange={(v) => setItem(i, { default_assignee_role: v === NONE ? null : v })}
                                        >
                                            <SelectTrigger size="sm"><SelectValue /></SelectTrigger>
                                            <SelectContent>
                                                <SelectItem value={NONE}>Unassigned</SelectItem>
                                                {options.assigneeRoles.map((r) => (
                                                    <SelectItem key={r.value} value={String(r.value)}>{r.label}</SelectItem>
                                                ))}
                                            </SelectContent>
                                        </Select>
                                    </div>
                                    {form.data.items.length > 1 && (
                                        <Button type="button" size="icon" variant="ghost" onClick={() => removeItem(i)}>
                                            <X />
                                        </Button>
                                    )}
                                </div>
                            ))}
                        </div>
                        <Button type="button" size="sm" variant="secondary" onClick={addItem}>
                            <Plus /> Add item
                        </Button>
                        {form.errors.items && <p className="text-xs text-destructive">{form.errors.items}</p>}
                    </div>

                    <DialogFooter>
                        <Button type="submit" disabled={form.processing}>{existing ? 'Save changes' : 'Create checklist'}</Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}

export default function TaskTemplatesIndex({ templates, options }: Props) {
    return (
        <>
            <Head title="Task templates" />
            <div className="flex flex-col gap-6 p-4">
                <PageHeader
                    title="Task checklists"
                    subtitle="Reusable task templates applied to matters automatically or on demand."
                    action={
                        <TemplateForm options={options} trigger={<Button><Plus /> New checklist</Button>} />
                    }
                />

                {templates.length === 0 ? (
                    <Card>
                        <CardContent className="p-0">
                            <EmptyState icon={ClipboardList} title="No checklists yet" description="Create a reusable checklist like 'New Suit Filing'." />
                        </CardContent>
                    </Card>
                ) : (
                    <div className="grid gap-4 lg:grid-cols-2">
                        {templates.map((t) => (
                            <Card key={t.id}>
                                <CardHeader className="flex flex-row items-start justify-between">
                                    <div>
                                        <CardTitle className="flex items-center gap-2">
                                            {t.name}
                                            {!t.is_active && <StatusBadge tone="neutral">Inactive</StatusBadge>}
                                        </CardTitle>
                                        <p className="mt-1 text-xs text-muted-foreground">
                                            {t.applies_to} · {t.items_count} item{t.items_count === 1 ? '' : 's'}
                                        </p>
                                    </div>
                                    <div className="flex gap-1">
                                        <TemplateForm options={options} existing={t} trigger={<Button size="xs" variant="secondary">Edit</Button>} />
                                        {t.is_active && (
                                            <ConfirmDialog
                                                title={`Deactivate ${t.name}?`}
                                                description="It will no longer auto-apply or be selectable. Existing tasks are kept."
                                                confirmLabel="Deactivate"
                                                onConfirm={() => router.delete(destroy(t.id).url, { preserveScroll: true })}
                                                trigger={<Button size="xs" variant="ghost"><Trash2 /></Button>}
                                            />
                                        )}
                                    </div>
                                </CardHeader>
                                <CardContent>
                                    <ol className="list-decimal space-y-1 pl-5 text-sm text-foreground">
                                        {t.items.map((it) => (
                                            <li key={it.id ?? it.title}>
                                                {it.title}
                                                {it.due_offset_days !== null && (
                                                    <span className="text-muted-foreground"> · +{it.due_offset_days}d</span>
                                                )}
                                                {it.default_assignee_role && (
                                                    <span className="text-muted-foreground"> · {it.default_assignee_role}</span>
                                                )}
                                            </li>
                                        ))}
                                    </ol>
                                </CardContent>
                            </Card>
                        ))}
                    </div>
                )}
            </div>
        </>
    );
}
