import { useForm } from '@inertiajs/react';
import { Plus, Trash2 } from 'lucide-react';
import { useMemo, type FormEvent } from 'react';
import ProjectController from '@/actions/App/Http/Controllers/Admin/ProjectController';
import InputError from '@/components/input-error';
import { MultiSelect } from '@/components/multi-select';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
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';
import { cn, formatCurrency } from '@/lib/utils';

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

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

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

export type MilestoneLine = {
    title: string;
    due_date: string;
    is_completed: boolean;
};

export type ProjectFormData = {
    id: number;
    code: string;
    name: string;
    description: string | null;
    status: string;
    customer_id: number | null;
    start_date: string;
    end_date: string;
    budget: string | number;
    progress_percent: number;
    is_active: boolean;
    team_member_ids: number[];
    milestones: MilestoneLine[];
};

type Props = {
    customers: CustomerOption[];
    users: UserOption[];
    statuses: StatusOption[];
    project?: ProjectFormData | null;
    onCancel: () => void;
};

function emptyMilestone(): MilestoneLine {
    return { title: '', due_date: '', is_completed: false };
}

function computeProgress(milestones: MilestoneLine[]): number {
    if (milestones.length === 0) {
        return 0;
    }

    const completed = milestones.filter((m) => m.is_completed).length;

    return Math.round((completed / milestones.length) * 100);
}

export function ProjectForm({
    customers,
    users,
    statuses,
    project = null,
    onCancel,
}: Props) {
    const isEditing = project !== null;

    const form = useForm({
        name: project?.name ?? '',
        description: project?.description ?? '',
        status: project?.status ?? statuses[0]?.value ?? '',
        customer_id: project?.customer_id ? String(project.customer_id) : '',
        start_date: project?.start_date ?? '',
        end_date: project?.end_date ?? '',
        budget: project ? String(project.budget) : '',
        is_active: project?.is_active ?? true,
        team_member_ids: project?.team_member_ids ?? [],
        milestones:
            project?.milestones.map((m) => ({
                title: m.title,
                due_date: m.due_date ?? '',
                is_completed: m.is_completed,
            })) ?? [],
    });

    const progressPreview = useMemo(
        () => computeProgress(form.data.milestones),
        [form.data.milestones],
    );

    function addMilestone() {
        form.setData('milestones', [...form.data.milestones, emptyMilestone()]);
    }

    function updateMilestone(
        index: number,
        field: keyof MilestoneLine,
        value: string | boolean,
    ) {
        const next = [...form.data.milestones];
        next[index] = { ...next[index], [field]: value };
        form.setData('milestones', next);
    }

    function removeMilestone(index: number) {
        form.setData(
            'milestones',
            form.data.milestones.filter((_, i) => i !== index),
        );
    }

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

        const milestones = form.data.milestones
            .filter((m) => m.title.trim() !== '')
            .map((m, index) => ({
                title: m.title.trim(),
                due_date: m.due_date || null,
                is_completed: m.is_completed,
                sort_order: index,
            }));

        form.transform((data) => ({
            ...data,
            customer_id: data.customer_id ? Number(data.customer_id) : null,
            milestones,
        }));

        if (isEditing && project) {
            form.put(ProjectController.update.url(project.id));
            return;
        }

        form.post(ProjectController.store.url());
    }

    return (
        <form onSubmit={submit} className="max-w-3xl space-y-8">
            {isEditing && project && (
                <div className="grid gap-2">
                    <Label>Code</Label>
                    <Input
                        value={project.code}
                        disabled
                        readOnly
                        className="font-mono"
                    />
                </div>
            )}

            <div className="grid gap-4 sm:grid-cols-2">
                <div className="grid gap-2 sm:col-span-2">
                    <Label htmlFor="project-name">Nom</Label>
                    <Input
                        id="project-name"
                        value={form.data.name}
                        onChange={(e) => form.setData('name', e.target.value)}
                        required
                        autoFocus
                    />
                    <InputError message={form.errors.name} />
                </div>

                <div className="grid gap-2 sm:col-span-2">
                    <Label htmlFor="project-description">Description</Label>
                    <Textarea
                        id="project-description"
                        rows={3}
                        value={form.data.description ?? ''}
                        onChange={(e) =>
                            form.setData('description', e.target.value)
                        }
                    />
                    <InputError message={form.errors.description} />
                </div>

                <div className="grid gap-2">
                    <Label htmlFor="project-status">Statut</Label>
                    <Select
                        value={form.data.status || undefined}
                        onValueChange={(value) =>
                            form.setData('status', value)
                        }
                    >
                        <SelectTrigger id="project-status" className="w-full">
                            <SelectValue placeholder="Choisir un statut…" />
                        </SelectTrigger>
                        <SelectContent>
                            {statuses.map((status) => (
                                <SelectItem
                                    key={status.value}
                                    value={status.value}
                                >
                                    {status.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                    <InputError message={form.errors.status} />
                </div>

                <label className="flex items-end gap-2 pb-2 text-sm">
                    <Checkbox
                        checked={form.data.is_active}
                        onCheckedChange={(checked) =>
                            form.setData('is_active', checked === true)
                        }
                    />
                    <span>Actif</span>
                </label>

                <div className="grid gap-2 sm:col-span-2">
                    <Label htmlFor="project-customer">Client</Label>
                    <Select
                        value={form.data.customer_id || 'none'}
                        onValueChange={(value) =>
                            form.setData(
                                'customer_id',
                                value === 'none' ? '' : value,
                            )
                        }
                    >
                        <SelectTrigger id="project-customer" className="w-full">
                            <SelectValue placeholder="Aucun client" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="none">Aucun client</SelectItem>
                            {customers.map((customer) => (
                                <SelectItem
                                    key={customer.id}
                                    value={String(customer.id)}
                                >
                                    {customer.name}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                    <InputError message={form.errors.customer_id} />
                </div>

                <div className="grid gap-2">
                    <Label htmlFor="project-start">Date de début</Label>
                    <Input
                        id="project-start"
                        type="date"
                        value={form.data.start_date}
                        onChange={(e) =>
                            form.setData('start_date', e.target.value)
                        }
                        required
                    />
                    <InputError message={form.errors.start_date} />
                </div>

                <div className="grid gap-2">
                    <Label htmlFor="project-end">Date de fin</Label>
                    <Input
                        id="project-end"
                        type="date"
                        value={form.data.end_date}
                        onChange={(e) =>
                            form.setData('end_date', e.target.value)
                        }
                        required
                    />
                    <InputError message={form.errors.end_date} />
                </div>

                <div className="grid gap-2">
                    <Label htmlFor="project-budget">Budget</Label>
                    <Input
                        id="project-budget"
                        type="number"
                        step="0.01"
                        min="0"
                        value={form.data.budget}
                        onChange={(e) =>
                            form.setData('budget', e.target.value)
                        }
                        required
                    />
                    <InputError message={form.errors.budget} />
                </div>

                <div className="grid gap-2">
                    <Label>Avancement</Label>
                    <div className="space-y-2 rounded-md border p-3">
                        <p className="text-right text-sm font-medium tabular-nums">
                            {progressPreview} %
                        </p>
                        <div className="bg-muted h-2 overflow-hidden rounded-full">
                            <div
                                className={cn(
                                    'bg-primary h-full transition-all',
                                )}
                                style={{
                                    width: `${progressPreview}%`,
                                }}
                            />
                        </div>
                        {form.data.budget && (
                            <p className="text-muted-foreground text-xs">
                                Budget saisi :{' '}
                                {formatCurrency(form.data.budget)}
                            </p>
                        )}
                    </div>
                </div>
            </div>

            <div className="space-y-3">
                <Label htmlFor="project-team">Équipe assignée</Label>
                <MultiSelect
                    id="project-team"
                    options={users.map((user) => ({
                        value: String(user.id),
                        label: user.name,
                    }))}
                    value={form.data.team_member_ids.map(String)}
                    onChange={(values) =>
                        form.setData(
                            'team_member_ids',
                            values.map((value) => Number(value)),
                        )
                    }
                    placeholder="Choisir des membres…"
                />
                <InputError message={form.errors.team_member_ids} />
            </div>

            <div className="space-y-4">
                <div className="flex items-center justify-between">
                    <Label>Jalons</Label>
                    <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={addMilestone}
                    >
                        <Plus />
                        Ajouter un jalon
                    </Button>
                </div>

                {form.data.milestones.length === 0 ? (
                    <p className="text-muted-foreground text-sm">
                        Aucun jalon. L’avancement restera à 0 %.
                    </p>
                ) : (
                    <div className="space-y-3">
                        {form.data.milestones.map((milestone, index) => (
                            <div
                                key={index}
                                className="grid gap-3 rounded-md border p-4 sm:grid-cols-[1fr_auto_auto_auto]"
                            >
                                <div className="grid gap-2">
                                    <Label htmlFor={`milestone-title-${index}`}>
                                        Titre
                                    </Label>
                                    <Input
                                        id={`milestone-title-${index}`}
                                        value={milestone.title}
                                        onChange={(e) =>
                                            updateMilestone(
                                                index,
                                                'title',
                                                e.target.value,
                                            )
                                        }
                                    />
                                    <InputError
                                        message={
                                            form.errors[
                                                `milestones.${index}.title` as keyof typeof form.errors
                                            ]
                                        }
                                    />
                                </div>
                                <div className="grid gap-2">
                                    <Label htmlFor={`milestone-due-${index}`}>
                                        Échéance
                                    </Label>
                                    <Input
                                        id={`milestone-due-${index}`}
                                        type="date"
                                        value={milestone.due_date}
                                        onChange={(e) =>
                                            updateMilestone(
                                                index,
                                                'due_date',
                                                e.target.value,
                                            )
                                        }
                                    />
                                </div>
                                <label className="flex items-end gap-2 pb-2 text-sm">
                                    <Checkbox
                                        checked={milestone.is_completed}
                                        onCheckedChange={(checked) =>
                                            updateMilestone(
                                                index,
                                                'is_completed',
                                                checked === true,
                                            )
                                        }
                                    />
                                    <span>Terminé</span>
                                </label>
                                <div className="flex items-end pb-1">
                                    <Button
                                        type="button"
                                        variant="ghost"
                                        size="icon"
                                        onClick={() => removeMilestone(index)}
                                        aria-label="Supprimer le jalon"
                                    >
                                        <Trash2 className="text-destructive" />
                                    </Button>
                                </div>
                            </div>
                        ))}
                    </div>
                )}
                <InputError message={form.errors.milestones} />
            </div>

            <div className="flex gap-3">
                <Button type="submit" disabled={form.processing}>
                    {isEditing ? 'Enregistrer' : 'Créer'}
                </Button>
                <Button type="button" variant="outline" onClick={onCancel}>
                    Annuler
                </Button>
            </div>
        </form>
    );
}
