import { router } from '@inertiajs/react';
import { CheckSquare, Loader2 } from 'lucide-react';
import React, { useState } from 'react';
import { toast } from 'sonner';

import { RequiredProofField } from '@/components/tasks/RequiredProofField';
import { Button } from '@/components/ui/button';
import { DateTimePicker } from '@/components/ui/datetime-picker';
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 { Textarea } from '@/components/ui/textarea';
import { useYupValidation } from '@/hooks/use-yup-validation';
import { mainTaskFormSchema } from '@/lib/validation/task';
import { store } from '@/routes/tasks/tasks';

interface CreateTaskSheetProps {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    projects: {
        id: string;
        name: string;
        divisionId: string;
        members: { id: string; name: string; role?: string }[];
    }[];
    defaultProjectId?: string;
    divisionId?: string;
    divisionMembers?: { id: string; name: string; role?: string }[];
    withoutProject?: boolean;
    onSuccess?: () => void;
}

/**
 * Nilai awal form, dipakai saat komponen lahir dan tiap kali sheet dibuka
 * ulang. Ditaruh di luar komponen supaya keduanya membaca satu sumber yang
 * sama — sebelumnya bentuk objek ini ditulis ulang di tiga tempat.
 */
function buildInitialFormData({
    defaultProjectId,
    projects,
    withoutProject,
}: {
    defaultProjectId?: string;
    projects: { id: string }[];
    withoutProject: boolean;
}) {
    return {
        title: '',
        description: '',
        projectId: withoutProject
            ? ''
            : defaultProjectId || (projects.length === 1 ? projects[0].id : ''),
        priorityLevel: '2',
        dueDate: '',
        assigneeId: '',
        requiredProofType: 'file',
    };
}

export function CreateTaskSheet({
    open,
    onOpenChange,
    projects,
    defaultProjectId,
    divisionId,
    divisionMembers = [],
    withoutProject = false,
    onSuccess,
}: CreateTaskSheetProps) {
    const [processing, setProcessing] = useState(false);
    const [formData, setFormData] = useState(() =>
        buildInitialFormData({ defaultProjectId, projects, withoutProject }),
    );

    const { errors, validateField, clearError, validate, resetErrors } =
        useYupValidation(mainTaskFormSchema, formData);

    // Komponen ini selalu ter-mount (TaskList merendernya tanpa syarat), jadi
    // menutup sheet lewat Cancel, Escape, atau klik overlay tidak membuang apa
    // pun — dulu isian lama muncul lagi saat sheet dibuka berikutnya. Reset
    // dilakukan di sini, bukan saat menutup, supaya isi sheet tidak berkedip
    // selama animasi keluar.
    const wasOpenRef = React.useRef(false);

    React.useEffect(() => {
        // Hanya pada transisi tertutup → terbuka. Deps di bawah ikut berubah
        // tiap kali halaman induk re-render (`projects` selalu array baru), dan
        // tanpa penjaga ini ketikan user akan terhapus di tengah pengisian.
        if (open && !wasOpenRef.current) {
            setFormData(
                buildInitialFormData({
                    defaultProjectId,
                    projects,
                    withoutProject,
                }),
            );
            resetErrors();
        }

        wasOpenRef.current = open;
    }, [open, defaultProjectId, projects, withoutProject, resetErrors]);

    // Viewer tidak pernah bisa ditugaskan task — server menolaknya dengan 422,
    // jadi jangan tawarkan.
    const assigneeOptions = (
        withoutProject
            ? divisionMembers
            : projects.find((p) => String(p.id) === String(formData.projectId))
                  ?.members || []
    ).filter((member) => member.role !== 'viewer');

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();

        if (!validate()) {
            return;
        }

        const selectedProject = withoutProject
            ? null
            : projects.find((p) => String(p.id) === String(formData.projectId));

        if (!withoutProject && !selectedProject) {
            toast.error('Please select a project first');

            return;
        }

        const resolvedDivisionId = withoutProject
            ? divisionId
            : selectedProject?.divisionId;

        if (!resolvedDivisionId) {
            toast.error('No division is available for this task yet');

            return;
        }

        router.post(
            store().url,
            {
                division_id: resolvedDivisionId,
                project_id: withoutProject ? null : formData.projectId,
                name: formData.title,
                description: formData.description,
                due_date: formData.dueDate,
                priority_level: parseInt(formData.priorityLevel) || 1,
                required_proof_type: formData.requiredProofType,
                assignee_ids: formData.assigneeId ? [formData.assigneeId] : [],
            },
            {
                onBefore: () => setProcessing(true),
                onFinish: () => setProcessing(false),
                onSuccess: () => {
                    toast.success('Task created');
                    onOpenChange(false);
                    setFormData(
                        buildInitialFormData({
                            defaultProjectId,
                            projects,
                            withoutProject,
                        }),
                    );
                    resetErrors();
                    onSuccess?.();
                },
                onError: (errors) => {
                    console.error('Validation errors:', errors);
                    toast.error(
                        Object.values(errors)[0] ||
                            'Failed to create task. Please review your input.',
                    );
                },
            },
        );
    };

    return (
        <Sheet open={open} onOpenChange={onOpenChange}>
            <SheetContent
                className="flex h-full w-full flex-col gap-0 overflow-hidden bg-background p-0 sm:max-w-3xl"
                hideClose
            >
                <form
                    onSubmit={handleSubmit}
                    className="flex h-full flex-col space-y-0"
                    noValidate
                >
                    <SheetHeader className="border-b p-6 text-left">
                        <SheetTitle className="flex items-center gap-2">
                            <CheckSquare className="h-4 w-4" />
                            Create Task
                        </SheetTitle>
                        <SheetDescription>
                            {withoutProject
                                ? 'Plan a division task outside any project.'
                                : 'Plan your next move and project workflow.'}
                        </SheetDescription>
                    </SheetHeader>

                    <div className="flex-1 space-y-4 overflow-y-auto p-6">
                        {/* Project Selection */}
                        {!withoutProject && projects.length > 1 && (
                            <div className="space-y-2">
                                <Label id="create-task-project-label">
                                    Project
                                </Label>
                                <Select
                                    value={formData.projectId}
                                    onValueChange={(val) =>
                                        setFormData({
                                            ...formData,
                                            projectId: val,
                                            assigneeId: '', // Reset assignee when project changes
                                        })
                                    }
                                >
                                    <SelectTrigger
                                        className="w-full"
                                        aria-labelledby="create-task-project-label"
                                    >
                                        <SelectValue placeholder="Select project" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {projects.map((p) => (
                                            <SelectItem
                                                key={p.id}
                                                value={p.id.toString()}
                                            >
                                                {p.name}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                            </div>
                        )}

                        {/* Assignee Selection */}
                        <div className="space-y-2">
                            <Label id="create-task-assignee-label">
                                Assign To
                            </Label>
                            <Select
                                value={formData.assigneeId}
                                onValueChange={(val) =>
                                    setFormData({
                                        ...formData,
                                        assigneeId: val,
                                    })
                                }
                                disabled={
                                    withoutProject
                                        ? divisionMembers.length === 0
                                        : !formData.projectId
                                }
                            >
                                <SelectTrigger
                                    className="w-full"
                                    aria-labelledby="create-task-assignee-label"
                                >
                                    <SelectValue
                                        placeholder={
                                            withoutProject
                                                ? 'Select a division member'
                                                : formData.projectId
                                                  ? 'Select an assignee'
                                                  : 'Select a project first'
                                        }
                                    />
                                </SelectTrigger>
                                <SelectContent>
                                    {assigneeOptions.map((m) => (
                                        <SelectItem
                                            key={m.id}
                                            value={m.id.toString()}
                                        >
                                            {m.name}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>

                        {/* Task Title */}
                        <div className="space-y-2">
                            <Label htmlFor="title">Task Title</Label>
                            <Input
                                id="title"
                                placeholder="Name the task briefly, e.g. Send invoice to client"
                                value={formData.title}
                                onChange={(e) => {
                                    setFormData({
                                        ...formData,
                                        title: e.target.value,
                                    });
                                    clearError('title');
                                }}
                                onBlur={() => validateField('title')}
                                required
                            />
                            {errors.title && (
                                <p className="text-xs text-destructive">
                                    {errors.title}
                                </p>
                            )}
                        </div>

                        {/* Description */}
                        <div className="space-y-2">
                            <Label htmlFor="description">Description</Label>
                            <Textarea
                                id="description"
                                placeholder="Describe the work here — steps, notes, or anything the assignee needs to know"
                                value={formData.description}
                                onChange={(e) =>
                                    setFormData({
                                        ...formData,
                                        description: e.target.value,
                                    })
                                }
                                className="min-h-30 resize-none"
                            />
                        </div>

                        {/* Priority Selection */}
                        <div className="space-y-2">
                            <Label id="create-task-priority-label">
                                Priority
                            </Label>
                            <Select
                                value={formData.priorityLevel}
                                onValueChange={(val) =>
                                    setFormData({
                                        ...formData,
                                        priorityLevel: val,
                                    })
                                }
                            >
                                <SelectTrigger
                                    className="w-full"
                                    aria-labelledby="create-task-priority-label"
                                >
                                    <SelectValue placeholder="Select priority" />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="1">Low</SelectItem>
                                    <SelectItem value="2">Medium</SelectItem>
                                    <SelectItem value="3">High</SelectItem>
                                    <SelectItem value="4">Urgent</SelectItem>
                                </SelectContent>
                            </Select>
                        </div>

                        {/* Deadline */}
                        <div className="space-y-2">
                            <Label id="create-task-deadline-label">
                                Deadline
                                {formData.assigneeId && (
                                    <span
                                        className="text-destructive"
                                        aria-hidden="true"
                                    >
                                        {' '}
                                        *
                                    </span>
                                )}
                            </Label>
                            <DateTimePicker
                                ariaLabelledBy="create-task-deadline-label"
                                ariaDescribedBy={
                                    errors.dueDate
                                        ? 'create-task-deadline-error'
                                        : undefined
                                }
                                ariaInvalid={Boolean(errors.dueDate)}
                                value={formData.dueDate}
                                onChange={(val) => {
                                    setFormData({
                                        ...formData,
                                        dueDate: val,
                                    });
                                    clearError('dueDate');
                                }}
                                placeholder="Pick a deadline date & time"
                            />
                            {errors.dueDate && (
                                <p
                                    id="create-task-deadline-error"
                                    aria-live="polite"
                                    className="text-xs text-destructive"
                                >
                                    {errors.dueDate}
                                </p>
                            )}
                        </div>

                        <RequiredProofField
                            value={formData.requiredProofType}
                            onChange={(requiredProofType) => {
                                setFormData({
                                    ...formData,
                                    requiredProofType,
                                });
                                clearError('requiredProofType');
                            }}
                            error={errors.requiredProofType}
                        />
                    </div>

                    <SheetFooter className="border-t p-6">
                        <div className="flex w-full gap-3 sm:justify-end">
                            <Button
                                type="button"
                                variant="outline"
                                onClick={() => onOpenChange(false)}
                                className="flex-1 sm:flex-none"
                                disabled={processing}
                            >
                                Cancel
                            </Button>
                            <Button
                                type="submit"
                                disabled={processing}
                                className="flex-1 sm:flex-none"
                            >
                                {processing ? (
                                    <>
                                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                                        Creating...
                                    </>
                                ) : (
                                    'Create Task'
                                )}
                            </Button>
                        </div>
                    </SheetFooter>
                </form>
            </SheetContent>
        </Sheet>
    );
}
