import { Link, useForm } from '@inertiajs/react';
import { ExternalLink } from 'lucide-react';
import type { FormEvent } from 'react';
import { useEffect } from 'react';
import KanbanController from '@/actions/App/Http/Controllers/Admin/KanbanController';
import InputError from '@/components/input-error';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    Sheet,
    SheetContent,
    SheetDescription,
    SheetFooter,
    SheetHeader,
    SheetTitle,
} from '@/components/ui/sheet';
import { show as taskShow } from '@/routes/admin/tasks';
import { show as ticketShow } from '@/routes/admin/tickets';

type UserOption = { id: number; name: string };
type EnumOption = { value: string; label: string };

export type KanbanSheetItem = {
    id: number;
    code: string;
    title: string;
    type: 'task' | 'ticket';
    status: string;
    priority: string;
    assigned_to: number | null;
    due_date: string | null;
    completion_percent?: number;
    category?: string;
};

type Props = {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    item: KanbanSheetItem | null;
    users: UserOption[];
    priorities: EnumOption[];
    categories?: EnumOption[];
    canUpdate: boolean;
};

export function KanbanItemSheet({
    open,
    onOpenChange,
    item,
    users,
    priorities,
    categories = [],
    canUpdate,
}: Props) {
    const form = useForm({
        due_date: '',
        assigned_to: '' as string | number,
        priority: 'medium',
        completion_percent: 0,
        category: 'request',
    });

    useEffect(() => {
        if (!open || !item) {
            return;
        }

        form.setData({
            due_date: item.due_date ?? '',
            assigned_to: item.assigned_to ?? '',
            priority: item.priority,
            completion_percent: item.completion_percent ?? 0,
            category: item.category ?? 'request',
        });
        form.clearErrors();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [open, item]);

    function submit(event: FormEvent) {
        event.preventDefault();

        if (!item || !canUpdate) {
            return;
        }

        const payload =
            item.type === 'task'
                ? {
                      due_date: form.data.due_date || null,
                      assigned_to:
                          form.data.assigned_to === ''
                              ? null
                              : Number(form.data.assigned_to),
                      priority: form.data.priority,
                      completion_percent: Number(form.data.completion_percent),
                  }
                : {
                      due_date: form.data.due_date || null,
                      assigned_to:
                          form.data.assigned_to === ''
                              ? null
                              : Number(form.data.assigned_to),
                      priority: form.data.priority,
                      category: form.data.category,
                  };

        form.transform(() => payload);

        const url =
            item.type === 'task'
                ? KanbanController.updateTaskKanban.url(item.id)
                : KanbanController.updateTicketKanban.url(item.id);

        form.patch(url, {
            preserveScroll: true,
            onSuccess: () => onOpenChange(false),
        });
    }

    return (
        <Sheet open={open} onOpenChange={onOpenChange}>
            <SheetContent side="right" className="sm:max-w-md">
                <SheetHeader>
                    <SheetTitle>
                        {item?.title ?? 'Édition rapide'}
                    </SheetTitle>
                    <SheetDescription>
                        {item
                            ? `${item.code} — planification légère`
                            : 'Sélectionnez une carte'}
                    </SheetDescription>
                    {item && (
                        <Button
                            variant="link"
                            size="sm"
                            className="h-auto w-fit px-0"
                            asChild
                        >
                            <Link
                                href={
                                    item.type === 'task'
                                        ? taskShow(item.id)
                                        : ticketShow(item.id)
                                }
                            >
                                Voir le détail complet
                                <ExternalLink />
                            </Link>
                        </Button>
                    )}
                </SheetHeader>

                {item && (
                    <form
                        onSubmit={submit}
                        className="flex flex-1 flex-col gap-4 px-4 pb-4"
                    >
                        <div className="grid gap-2">
                            <Label htmlFor="kanban-due-date">Échéance</Label>
                            <Input
                                id="kanban-due-date"
                                type="date"
                                value={form.data.due_date}
                                disabled={!canUpdate}
                                onChange={(event) =>
                                    form.setData(
                                        'due_date',
                                        event.target.value,
                                    )
                                }
                            />
                            <InputError message={form.errors.due_date} />
                        </div>

                        <div className="grid gap-2">
                            <Label htmlFor="kanban-assignee">Assigné à</Label>
                            <Select
                                value={
                                    form.data.assigned_to === ''
                                        ? 'none'
                                        : String(form.data.assigned_to)
                                }
                                disabled={!canUpdate}
                                onValueChange={(value) =>
                                    form.setData(
                                        'assigned_to',
                                        value === 'none' ? '' : Number(value),
                                    )
                                }
                            >
                                <SelectTrigger id="kanban-assignee">
                                    <SelectValue placeholder="Non assigné" />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="none">
                                        Non assigné
                                    </SelectItem>
                                    {users.map((user) => (
                                        <SelectItem
                                            key={user.id}
                                            value={String(user.id)}
                                        >
                                            {user.name}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            <InputError message={form.errors.assigned_to} />
                        </div>

                        <div className="grid gap-2">
                            <Label htmlFor="kanban-priority">Priorité</Label>
                            <Select
                                value={form.data.priority}
                                disabled={!canUpdate}
                                onValueChange={(value) =>
                                    form.setData('priority', value)
                                }
                            >
                                <SelectTrigger id="kanban-priority">
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {priorities.map((priority) => (
                                        <SelectItem
                                            key={priority.value}
                                            value={priority.value}
                                        >
                                            {priority.label}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            <InputError message={form.errors.priority} />
                        </div>

                        {item.type === 'task' && (
                            <div className="grid gap-2">
                                <Label htmlFor="kanban-progress">
                                    Avancement (%)
                                </Label>
                                <Input
                                    id="kanban-progress"
                                    type="number"
                                    min={0}
                                    max={100}
                                    value={form.data.completion_percent}
                                    disabled={!canUpdate}
                                    onChange={(event) =>
                                        form.setData(
                                            'completion_percent',
                                            Number(event.target.value),
                                        )
                                    }
                                />
                                <InputError
                                    message={form.errors.completion_percent}
                                />
                            </div>
                        )}

                        {item.type === 'ticket' && categories.length > 0 && (
                            <div className="grid gap-2">
                                <Label htmlFor="kanban-category">
                                    Catégorie
                                </Label>
                                <Select
                                    value={form.data.category}
                                    disabled={!canUpdate}
                                    onValueChange={(value) =>
                                        form.setData('category', value)
                                    }
                                >
                                    <SelectTrigger id="kanban-category">
                                        <SelectValue />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {categories.map((category) => (
                                            <SelectItem
                                                key={category.value}
                                                value={category.value}
                                            >
                                                {category.label}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                <InputError message={form.errors.category} />
                            </div>
                        )}

                        {canUpdate && (
                            <SheetFooter className="px-0">
                                <Button
                                    type="button"
                                    variant="outline"
                                    onClick={() => onOpenChange(false)}
                                >
                                    Annuler
                                </Button>
                                <Button
                                    type="submit"
                                    disabled={form.processing}
                                >
                                    Enregistrer
                                </Button>
                            </SheetFooter>
                        )}
                    </form>
                )}
            </SheetContent>
        </Sheet>
    );
}
