import { useForm } from '@inertiajs/react';
import { useEffect, useMemo } from 'react';
import type { FormEvent } from 'react';
import TaskController from '@/actions/App/Http/Controllers/Admin/TaskController';
import InputError from '@/components/input-error';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} 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 { Textarea } from '@/components/ui/textarea';

export type ProjectOption = {
    id: number;
    code: string;
    name: string;
};

export type TicketOption = {
    id: number;
    code: string;
    title: string;
    project_id: number;
};

export type UserOption = {
    id: number;
    name: string;
};

export type EnumOption = {
    value: string;
    label: string;
};

export type TaskFormValues = {
    id: number;
    code: string;
    title: string;
    description: string | null;
    project_id: number | null;
    ticket_id: number | null;
    status: string;
    priority: string;
    assigned_to: number | null;
    due_date: string | null;
    completion_percent: number;
};

type Props = {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    task?: TaskFormValues | null;
    projects: ProjectOption[];
    tickets: TicketOption[];
    users: UserOption[];
    statuses: EnumOption[];
    priorities: EnumOption[];
};

export function TaskFormModal({
    open,
    onOpenChange,
    task = null,
    projects,
    tickets,
    users,
    statuses,
    priorities,
}: Props) {
    const isEditing = task !== null;

    const form = useForm({
        title: '',
        description: '',
        project_id: '' as string | number,
        ticket_id: '' as string | number,
        status: 'todo',
        priority: 'medium',
        assigned_to: '' as string | number,
        due_date: '',
        completion_percent: 0,
    });

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

        form.setData({
            title: task?.title ?? '',
            description: task?.description ?? '',
            project_id: task?.project_id ?? '',
            ticket_id: task?.ticket_id ?? '',
            status: task?.status ?? 'todo',
            priority: task?.priority ?? 'medium',
            assigned_to: task?.assigned_to ?? '',
            due_date: task?.due_date ?? '',
            completion_percent: task?.completion_percent ?? 0,
        });
        form.clearErrors();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [open, task]);

    const ticketsForProject = useMemo(() => {
        if (form.data.project_id === '') {
            return [];
        }

        return tickets.filter(
            (ticket) => ticket.project_id === Number(form.data.project_id),
        );
    }, [tickets, form.data.project_id]);

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

        const options = {
            preserveScroll: true,
            onSuccess: () => onOpenChange(false),
        };

        form.transform((data) => ({
            title: data.title,
            description: data.description || null,
            project_id: Number(data.project_id),
            ticket_id: data.ticket_id === '' ? null : Number(data.ticket_id),
            status: data.status,
            priority: data.priority,
            assigned_to:
                data.assigned_to === '' ? null : Number(data.assigned_to),
            due_date: data.due_date || null,
            completion_percent: Number(data.completion_percent),
        }));

        if (isEditing && task) {
            form.put(TaskController.update.url(task.id), options);

            return;
        }

        form.post(TaskController.store.url(), options);
    }

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-lg">
                <DialogHeader>
                    <DialogTitle>
                        {isEditing ? 'Modifier la tâche' : 'Nouvelle tâche'}
                    </DialogTitle>
                    <DialogDescription>
                        {isEditing
                            ? `Mettre à jour la tâche ${task.code}.`
                            : 'Le code sera généré automatiquement (ex. TSK-001).'}
                    </DialogDescription>
                </DialogHeader>

                <form onSubmit={submit} className="space-y-4">
                    <div className="grid gap-2">
                        <Label htmlFor="task-title">Titre</Label>
                        <Input
                            id="task-title"
                            value={form.data.title}
                            onChange={(event) =>
                                form.setData('title', event.target.value)
                            }
                            required
                        />
                        <InputError message={form.errors.title} />
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="task-project">Projet</Label>
                        <Select
                            value={
                                form.data.project_id === ''
                                    ? undefined
                                    : String(form.data.project_id)
                            }
                            onValueChange={(value) => {
                                form.setData({
                                    ...form.data,
                                    project_id: Number(value),
                                    ticket_id: '',
                                });
                            }}
                        >
                            <SelectTrigger id="task-project">
                                <SelectValue placeholder="Sélectionner un projet" />
                            </SelectTrigger>
                            <SelectContent>
                                {projects.map((project) => (
                                    <SelectItem
                                        key={project.id}
                                        value={String(project.id)}
                                    >
                                        {project.code} — {project.name}
                                    </SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                        <InputError message={form.errors.project_id} />
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="task-ticket">Ticket lié</Label>
                        <Select
                            value={
                                form.data.ticket_id === ''
                                    ? 'none'
                                    : String(form.data.ticket_id)
                            }
                            onValueChange={(value) =>
                                form.setData(
                                    'ticket_id',
                                    value === 'none' ? '' : Number(value),
                                )
                            }
                            disabled={form.data.project_id === ''}
                        >
                            <SelectTrigger id="task-ticket">
                                <SelectValue placeholder="Aucun ticket" />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="none">Aucun ticket</SelectItem>
                                {ticketsForProject.map((ticket) => (
                                    <SelectItem
                                        key={ticket.id}
                                        value={String(ticket.id)}
                                    >
                                        {ticket.code} — {ticket.title}
                                    </SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                        <InputError message={form.errors.ticket_id} />
                    </div>

                    <div className="grid gap-4 sm:grid-cols-2">
                        <div className="grid gap-2">
                            <Label htmlFor="task-status">Statut</Label>
                            <Select
                                value={form.data.status}
                                onValueChange={(value) => {
                                    form.setData({
                                        ...form.data,
                                        status: value,
                                        completion_percent:
                                            value === 'done'
                                                ? Math.max(
                                                      form.data
                                                          .completion_percent,
                                                      100,
                                                  )
                                                : form.data.completion_percent,
                                    });
                                }}
                            >
                                <SelectTrigger id="task-status">
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {statuses.map((status) => (
                                        <SelectItem
                                            key={status.value}
                                            value={status.value}
                                        >
                                            {status.label}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            <InputError message={form.errors.status} />
                        </div>

                        <div className="grid gap-2">
                            <Label htmlFor="task-priority">Priorité</Label>
                            <Select
                                value={form.data.priority}
                                onValueChange={(value) =>
                                    form.setData('priority', value)
                                }
                            >
                                <SelectTrigger id="task-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>
                    </div>

                    <div className="grid gap-4 sm:grid-cols-2">
                        <div className="grid gap-2">
                            <Label htmlFor="task-assignee">Assigné à</Label>
                            <Select
                                value={
                                    form.data.assigned_to === ''
                                        ? 'none'
                                        : String(form.data.assigned_to)
                                }
                                onValueChange={(value) =>
                                    form.setData(
                                        'assigned_to',
                                        value === 'none' ? '' : Number(value),
                                    )
                                }
                            >
                                <SelectTrigger id="task-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="task-due-date">Échéance</Label>
                            <Input
                                id="task-due-date"
                                type="date"
                                value={form.data.due_date}
                                onChange={(event) =>
                                    form.setData('due_date', event.target.value)
                                }
                            />
                            <InputError message={form.errors.due_date} />
                        </div>
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="task-completion">
                            Complétion ({form.data.completion_percent} %)
                        </Label>
                        <Input
                            id="task-completion"
                            type="range"
                            min={0}
                            max={100}
                            step={5}
                            value={form.data.completion_percent}
                            onChange={(event) =>
                                form.setData(
                                    'completion_percent',
                                    Number(event.target.value),
                                )
                            }
                        />
                        <InputError message={form.errors.completion_percent} />
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="task-description">Description</Label>
                        <Textarea
                            id="task-description"
                            value={form.data.description}
                            onChange={(event) =>
                                form.setData('description', event.target.value)
                            }
                            rows={4}
                        />
                        <InputError message={form.errors.description} />
                    </div>

                    <DialogFooter>
                        <Button
                            type="button"
                            variant="outline"
                            onClick={() => onOpenChange(false)}
                        >
                            Annuler
                        </Button>
                        <Button type="submit" disabled={form.processing}>
                            {isEditing ? 'Enregistrer' : 'Créer'}
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}
