import { useForm } from '@inertiajs/react';
import { useEffect } from 'react';
import type { FormEvent } from 'react';
import TicketController from '@/actions/App/Http/Controllers/Admin/TicketController';
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 UserOption = {
    id: number;
    name: string;
};

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

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

type Props = {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    ticket?: TicketFormValues | null;
    projects: ProjectOption[];
    users: UserOption[];
    statuses: EnumOption[];
    priorities: EnumOption[];
    categories: EnumOption[];
};

export function TicketFormModal({
    open,
    onOpenChange,
    ticket = null,
    projects,
    users,
    statuses,
    priorities,
    categories,
}: Props) {
    const isEditing = ticket !== null;

    const form = useForm({
        title: '',
        description: '',
        project_id: '' as string | number,
        status: 'open',
        priority: 'medium',
        category: 'request',
        assigned_to: '' as string | number,
        due_date: '',
    });

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

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

    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),
            status: data.status,
            priority: data.priority,
            category: data.category,
            assigned_to:
                data.assigned_to === '' ? null : Number(data.assigned_to),
            due_date: data.due_date || null,
        }));

        if (isEditing && ticket) {
            form.put(TicketController.update.url(ticket.id), options);

            return;
        }

        form.post(TicketController.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 le ticket' : 'Nouveau ticket'}
                    </DialogTitle>
                    <DialogDescription>
                        {isEditing
                            ? `Mettre à jour le ticket ${ticket.code}.`
                            : 'Le code sera généré automatiquement (ex. TKT-001).'}
                    </DialogDescription>
                </DialogHeader>

                <form onSubmit={submit} className="space-y-4">
                    <div className="grid gap-2">
                        <Label htmlFor="ticket-title">Titre</Label>
                        <Input
                            id="ticket-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="ticket-project">Projet</Label>
                        <Select
                            value={
                                form.data.project_id === ''
                                    ? undefined
                                    : String(form.data.project_id)
                            }
                            onValueChange={(value) =>
                                form.setData('project_id', Number(value))
                            }
                        >
                            <SelectTrigger id="ticket-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="ticket-category">Catégorie</Label>
                        <Select
                            value={form.data.category}
                            onValueChange={(value) =>
                                form.setData('category', value)
                            }
                        >
                            <SelectTrigger id="ticket-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>

                    <div className="grid gap-4 sm:grid-cols-2">
                        <div className="grid gap-2">
                            <Label htmlFor="ticket-status">Statut</Label>
                            <Select
                                value={form.data.status}
                                onValueChange={(value) =>
                                    form.setData('status', value)
                                }
                            >
                                <SelectTrigger id="ticket-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="ticket-priority">Priorité</Label>
                            <Select
                                value={form.data.priority}
                                onValueChange={(value) =>
                                    form.setData('priority', value)
                                }
                            >
                                <SelectTrigger id="ticket-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-2">
                        <Label htmlFor="ticket-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="ticket-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="ticket-due-date">Échéance</Label>
                        <Input
                            id="ticket-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 className="grid gap-2">
                        <Label htmlFor="ticket-description">Description</Label>
                        <Textarea
                            id="ticket-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>
    );
}
