"use client"

import { AlertTriangle, Plus, Save } from "lucide-react"

import { Button } from "@/shared/components/ui/button"
import { Alert, AlertTitle } from "@/shared/components/ui/alert"
import { FieldGroup } from "@/shared/components/ui/field"
import {
    Rhform,
    RhfTextField,
    RhfTextareaField,
    RhfSelectField,
    RhfAsyncSelectField,
    RhfDateField,
} from "@/shared/components/form"
import { toast } from "sonner"
import { useAuthApi } from "@/shared/useApi"
import { useResourceForm } from "@/shared/hooks/use-resource-form"
import { useFormMutation } from "@/shared/hooks/use-form-mutation"
import { toRelation, toId } from "@/shared/lib/utils"

import { taskFormSchema, type TaskFormValues } from "./task.schema"
import { TASK_ROUTES, TASK_TYPE_ROUTES, TASK_SECTION_ROUTES, EMPLOYEE_ROUTES, DEPARTMENT_ROUTES, JOB_CARD_ROUTES } from "@garage/api"
import { TaskStatus, TaskPriority } from "@garage/api"
import { TaskTypeCrudDialog } from "./task-type-crud-dialog"
import { TaskSectionCrudDialog } from "./task-section-crud-dialog"

// ── Constants ──

const STATUS_OPTIONS = TaskStatus.map((s) => ({
    value: s,
    label: s.charAt(0).toUpperCase() + s.slice(1),
}))

const PRIORITY_OPTIONS = TaskPriority.map((p,i) => ({
    value: i,
    label: p.charAt(0).toUpperCase() + p.slice(1),
}))

const STORE_OBJECT = { getOptionValue: (o: any) => o, getOptionLabel: (o: any) => o.label }

// ── Props ──

export type TaskFormProps = {
    resourceId?: string | null
    initialData?: unknown
    onSuccess?: () => void
}

// ── Default values ──

const DEFAULT_VALUES: TaskFormValues = {
    subject: "",
    description: "",
    task_type: null,
    task_section: null,
    owner: null,
    department: null,
    priority: "medium",
    due_date: "",
    status: "pending",
    job_card: null,
}

// ── Mapping helpers ──

function mapToFormValues(data: unknown): TaskFormValues {
    const d = (data as any)?.data ?? data ?? {}

    return {
        subject: d.subject || "",
        description: d.description || "",
        task_type: toRelation(d.task_type_id, d.task_type?.title),
        task_section: toRelation(d.task_section_id, d.task_section?.title),
        owner: toRelation(
            d.owner_id,
            d.owner ? `${d.owner.first_name ?? ""} ${d.owner.last_name ?? ""}`.trim() : undefined,
        ),
        department: toRelation(d.department_id, d.department?.name),
        priority: d.priority || "medium",
        due_date: d.due_date ? d.due_date.split("T")[0] : "",
        status: d.status || "pending",
        job_card: toRelation(d.job_card_id, d.job_card?.title),
    }
}

function mapFormToPayload(values: TaskFormValues) {
    return {
        subject: values.subject,
        description: values.description || undefined,
        task_type_id: toId(values.task_type),
        task_section_id: toId(values.task_section),
        owner_id: toId(values.owner),
        department_id: toId(values.department),
        priority: values.priority || undefined,
        due_date: values.due_date || undefined,
        status: values.status || undefined,
        job_card_id: toId(values.job_card),
    }
}

// ── Component ──

export function TaskForm({ resourceId, initialData, onSuccess }: TaskFormProps) {
    const api = useAuthApi()

    const { form, isEditing } = useResourceForm<TaskFormValues, any>({
        schema: taskFormSchema,
        defaultValues: DEFAULT_VALUES,
        resourceId,
        initialData,
        mapToFormValues,
        queryKey: [TASK_ROUTES.BY_ID, resourceId],
    })

    const { mutate, error, isPending } = useFormMutation(form, {
        mutationFn: (values: TaskFormValues) => {
            const payload = mapFormToPayload(values)
            const promise = isEditing && resourceId
                ? api.tasks.update(resourceId, payload as any)
                : api.tasks.create(payload as any)
            toast.promise(promise, {
                loading: isEditing ? "Updating task..." : "Creating task...",
                success: isEditing ? "Task updated successfully" : "Task created successfully",
                error: isEditing ? "Failed to update task" : "Failed to create task",
            })
            return promise
        },
        onSuccess: () => {
            form.reset()
            onSuccess?.()
        },
    })

    return (
        <Rhform form={form} onSubmit={(values) => mutate(values)} className="space-y-6">
            {error && (
                <Alert variant="destructive">
                    <AlertTriangle className="h-4 w-4" />
                    <AlertTitle>
                        {isEditing ? "Failed to update task" : "Failed to create task"}
                    </AlertTitle>
                </Alert>
            )}

            <FieldGroup>
                <RhfTextField
                    name="subject"
                    label="Subject"
                    placeholder="e.g. Inspect brake pads"
                    required
                />
                <RhfTextareaField
                    name="description"
                    label="Description"
                    placeholder="Optional description..."
                />
            </FieldGroup>

            <FieldGroup>
                <div className="grid grid-cols-2 gap-4">
                    {/* Task Type with inline CRUD */}
                    <div>
                        <div className="flex items-center justify-between mb-1">
                            <span className="text-sm font-medium">Task Type</span>
                            <TaskTypeCrudDialog />
                        </div>
                        <RhfAsyncSelectField
                            name="task_type"
                            label=""
                            placeholder="Select task type..."
                            queryKey={[TASK_TYPE_ROUTES.INDEX]}
                            listFn={() => api.taskTypes.list()}
                            mapOption={(item: any) => ({ value: String(item.id), label: item.title })}
                            {...STORE_OBJECT}
                        />
                    </div>

                    {/* Task Section with inline CRUD */}
                    <div>
                        <div className="flex items-center justify-between mb-1">
                            <span className="text-sm font-medium">Task Section</span>
                            <TaskSectionCrudDialog />
                        </div>
                        <RhfAsyncSelectField
                            name="task_section"
                            label=""
                            placeholder="Select task section..."
                            queryKey={[TASK_SECTION_ROUTES.INDEX]}
                            listFn={() => api.taskSections.list()}
                            mapOption={(item: any) => ({ value: String(item.id), label: item.title })}
                            {...STORE_OBJECT}
                        />
                    </div>
                </div>
            </FieldGroup>

            <FieldGroup>
                <div className="grid grid-cols-2 gap-4">
                    <RhfAsyncSelectField
                        name="owner"
                        label="Assigned To"
                        placeholder="Select employee..."
                        queryKey={[EMPLOYEE_ROUTES.INDEX]}
                        listFn={() => api.employees.list()}
                        mapOption={(item: any) => ({
                            value: String(item.id),
                            label: `${item.first_name ?? ""} ${item.last_name ?? ""}`.trim(),
                        })}
                        {...STORE_OBJECT}
                    />

                    <RhfAsyncSelectField
                        name="department"
                        label="Department"
                        placeholder="Select department..."
                        queryKey={[DEPARTMENT_ROUTES.INDEX]}
                        listFn={() => api.departments.list()}
                        mapOption={(item: any) => ({ value: String(item.id), label: item.name })}
                        {...STORE_OBJECT}
                    />
                </div>

                <div className="grid grid-cols-2 gap-4">
                    <RhfSelectField
                        name="priority"
                        label="Priority"
                        placeholder="Select priority..."
                        options={PRIORITY_OPTIONS as any}
                    />

                    <RhfSelectField
                        name="status"
                        label="Status"
                        placeholder="Select status..."
                        options={STATUS_OPTIONS}
                    />
                </div>

                <div className="grid grid-cols-2 gap-4">
                    <RhfDateField name="due_date" label="Due Date" />

                    <RhfAsyncSelectField
                        name="job_card"
                        label="Job Card"
                        placeholder="Select job card..."
                        queryKey={[JOB_CARD_ROUTES.INDEX]}
                        listFn={() => api.jobCards.list()}
                        mapOption={(item: any) => ({
                            value: String(item.id),
                            label: item.title || `#${item.id}`,
                        })}
                        {...STORE_OBJECT}
                    />
                </div>
            </FieldGroup>

            <Button type="submit" disabled={isPending} className="w-full">
                {isEditing ? <Save className="h-4 w-4" /> : <Plus className="h-4 w-4" />}
                {isPending
                    ? isEditing ? "Updating..." : "Creating..."
                    : isEditing ? "Update Task" : "Add Task"}
            </Button>
        </Rhform>
    )
}
