"use client"

import { z } from "zod"
import { parseAsInteger, parseAsString, parseAsBoolean } from "nuqs"
import { toRelation, toId, type RelationFieldValue } from "@/shared/lib/utils"
import {
    RhfAsyncSelectField,
    RhfDateField,
    RhfCheckboxField,
    RhfSelectField,
} from "@/shared/components/form"
import { useAuthApi } from "@/shared/useApi"
import {
    CUSTOMER_ROUTES,
    EMPLOYEE_ROUTES,
    DEPARTMENT_ROUTES,
    VEHICLE_ROUTES,
    LABEL_ROUTES,
    INSURANCE_TYPE_ROUTES,
    JobCardStatus,
} from "@garage/api"
import { formatEnum } from "@/shared/utils/formatters"
import { Separator } from "@/shared/components/ui/separator"
import type { UseFilterParamsOptions } from "@/shared/hooks/use-filter-params"

// ── Schema ──

const relationField = z.object({ value: z.string(), label: z.string() }).nullable().optional()

const jobCardFilterSchema = z.object({
    customer_id: relationField,
    insurer_id: relationField,
    vehicle_id: relationField,
    department_id: relationField,
    sales_person_id: relationField,
    primary_technician_id: relationField,
    service_writer_id: relationField,
    label_ids: z.string().optional(),
    check_in_date: z.string().optional(),
    check_out_date: z.string().optional(),
    delivery_date: z.string().optional(),
    start_date: z.string().optional(),
    end_date: z.string().optional(),
    convert_invoice: z.boolean().optional(),
    has_start_or_delivery_date: z.boolean().optional(),
    has_start_date: z.boolean().optional(),
    has_delivery_date: z.boolean().optional(),
    has_both_dates: z.boolean().optional(),
})

type JobCardFilterValues = z.infer<typeof jobCardFilterSchema>

// ── Defaults ──

const defaultValues: JobCardFilterValues = {
    customer_id: null,
    insurer_id: null,
    vehicle_id: null,
    department_id: null,
    sales_person_id: null,
    primary_technician_id: null,
    service_writer_id: null,
    label_ids: "",
    check_in_date: "",
    check_out_date: "",
    delivery_date: "",
    start_date: "",
    end_date: "",
    convert_invoice: false,
    has_start_or_delivery_date: false,
    has_start_date: false,
    has_delivery_date: false,
    has_both_dates: false,
}

// ── nuqs Parsers ──

const paramsParsers = {
    customer_id: parseAsInteger,
    insurer_id: parseAsInteger,
    vehicle_id: parseAsInteger,
    department_id: parseAsInteger,
    sales_person_id: parseAsInteger,
    primary_technician_id: parseAsInteger,
    service_writer_id: parseAsInteger,
    label_ids: parseAsString,
    check_in_date: parseAsString,
    check_out_date: parseAsString,
    delivery_date: parseAsString,
    start_date: parseAsString,
    end_date: parseAsString,
    convert_invoice: parseAsBoolean,
    has_start_or_delivery_date: parseAsBoolean,
    has_start_date: parseAsBoolean,
    has_delivery_date: parseAsBoolean,
    has_both_dates: parseAsBoolean,
}

// ── Mappers ──

function mapParamsToFormValues(params: Record<string, any>): Partial<JobCardFilterValues> {
    return {
        customer_id: params.customer_id ? toRelation(params.customer_id) : null,
        insurer_id: params.insurer_id ? toRelation(params.insurer_id) : null,
        vehicle_id: params.vehicle_id ? toRelation(params.vehicle_id) : null,
        department_id: params.department_id ? toRelation(params.department_id) : null,
        sales_person_id: params.sales_person_id ? toRelation(params.sales_person_id) : null,
        primary_technician_id: params.primary_technician_id ? toRelation(params.primary_technician_id) : null,
        service_writer_id: params.service_writer_id ? toRelation(params.service_writer_id) : null,
        label_ids: params.label_ids ?? "",
        check_in_date: params.check_in_date ?? "",
        check_out_date: params.check_out_date ?? "",
        delivery_date: params.delivery_date ?? "",
        start_date: params.start_date ?? "",
        end_date: params.end_date ?? "",
        convert_invoice: params.convert_invoice ?? false,
        has_start_or_delivery_date: params.has_start_or_delivery_date ?? false,
        has_start_date: params.has_start_date ?? false,
        has_delivery_date: params.has_delivery_date ?? false,
        has_both_dates: params.has_both_dates ?? false,
    }
}

function mapFormValuesToParams(values: JobCardFilterValues): Record<string, any> {
    return {
        customer_id: toId(values.customer_id as RelationFieldValue) ?? null,
        insurer_id: toId(values.insurer_id as RelationFieldValue) ?? null,
        vehicle_id: toId(values.vehicle_id as RelationFieldValue) ?? null,
        department_id: toId(values.department_id as RelationFieldValue) ?? null,
        sales_person_id: toId(values.sales_person_id as RelationFieldValue) ?? null,
        primary_technician_id: toId(values.primary_technician_id as RelationFieldValue) ?? null,
        service_writer_id: toId(values.service_writer_id as RelationFieldValue) ?? null,
        label_ids: values.label_ids || null,
        check_in_date: values.check_in_date || null,
        check_out_date: values.check_out_date || null,
        delivery_date: values.delivery_date || null,
        start_date: values.start_date || null,
        end_date: values.end_date || null,
        convert_invoice: values.convert_invoice || null,
        has_start_or_delivery_date: values.has_start_or_delivery_date || null,
        has_start_date: values.has_start_date || null,
        has_delivery_date: values.has_delivery_date || null,
        has_both_dates: values.has_both_dates || null,
    }
}

// ── Filter Config (for useFilterParams) ──

export const jobCardFilterConfig: UseFilterParamsOptions<JobCardFilterValues> = {
    schema: jobCardFilterSchema,
    defaultValues,
    paramsParsers,
    mapParamsToFormValues,
    mapFormValuesToParams,
}

// ── Filter Fields Component ──

function SectionLabel({ children }: { children: React.ReactNode }) {
    return <p className="text-sm font-medium text-muted-foreground pt-2">{children}</p>
}

export function JobCardFilterFields() {
    const api = useAuthApi()

    const employeeMapOption = (item: any) => ({
        value: String(item.id),
        label: [item.first_name, item.last_name].filter(Boolean).join(" ") || `Employee #${item.id}`,
    })

    const customerMapOption = (item: any) => {
        const name = [item.first_name, item.last_name].filter(Boolean).join(" ")
        return {
            value: String(item.id),
            label: name || item.company_name || `Customer #${item.id}`,
        }
    }

    const vehicleMapOption = (item: any) => ({
        value: String(item.id),
        label: [item.year, item.make, item.model].filter(Boolean).join(" ") || `Vehicle #${item.id}`,
    })

    return (
        <>
            {/* ── Relations ── */}
            <SectionLabel>Relations</SectionLabel>

            <RhfAsyncSelectField
                name="customer_id"
                label="Customer"
                queryKey={[CUSTOMER_ROUTES.INDEX]}
                listFn={() => api.customers.list( )}
                mapOption={customerMapOption}
                placeholder="All customers"
            />

            <RhfAsyncSelectField
                name="vehicle_id"
                label="Vehicle"
                queryKey={[VEHICLE_ROUTES.INDEX]}
                listFn={() => api.vehicles.list( )}
                mapOption={vehicleMapOption}
                placeholder="All vehicles"
            />

            <RhfAsyncSelectField
                name="insurer_id"
                label="Insurance Type"
                queryKey={[INSURANCE_TYPE_ROUTES.INDEX]}
                listFn={() => api.insuranceTypes.list( )}
                mapOption={(item: any) => ({ value: String(item.id), label: item.title ?? item.name ?? `#${item.id}` })}
                placeholder="All insurers"
            />

            <RhfAsyncSelectField
                name="department_id"
                label="Department"
                queryKey={[DEPARTMENT_ROUTES.INDEX]}
                listFn={() => api.departments.list( )}
                mapOption={(item: any) => ({ value: String(item.id), label: item.title ?? item.name ?? `#${item.id}` })}
                placeholder="All departments"
            />

            <Separator />
            <SectionLabel>Assigned Staff</SectionLabel>

            <RhfAsyncSelectField
                name="sales_person_id"
                label="Sales Person"
                queryKey={[EMPLOYEE_ROUTES.INDEX, "sales_person"]}
                listFn={() => api.employees.list( )}
                mapOption={employeeMapOption}
                placeholder="All sales persons"
            />

            <RhfAsyncSelectField
                name="primary_technician_id"
                label="Primary Technician"
                queryKey={[EMPLOYEE_ROUTES.INDEX, "technician"]}
                listFn={() => api.employees.list( )}
                mapOption={employeeMapOption}
                placeholder="All technicians"
            />

            <RhfAsyncSelectField
                name="service_writer_id"
                label="Service Writer"
                queryKey={[EMPLOYEE_ROUTES.INDEX, "service_writer"]}
                listFn={() => api.employees.list( )}
                mapOption={employeeMapOption}
                placeholder="All service writers"
            />

            {/* ── Dates ── */}
            <Separator />
            <SectionLabel>Dates</SectionLabel>

            <div className="grid grid-cols-2 gap-3">
                <RhfDateField name="check_in_date" label="Check-in Date" />
                <RhfDateField name="check_out_date" label="Check-out Date" />
            </div>

            <RhfDateField name="delivery_date" label="Delivery Date" />

            <div className="grid grid-cols-2 gap-3">
                <RhfDateField name="start_date" label="Start Date" />
                <RhfDateField name="end_date" label="End Date" />
            </div>

            {/* ── Flags ── */}
            <Separator />
            <SectionLabel>Flags</SectionLabel>

            <RhfCheckboxField name="convert_invoice" label="Convert to Invoice" />
            <RhfCheckboxField name="has_start_or_delivery_date" label="Has Start or Delivery Date" />
            <RhfCheckboxField name="has_start_date" label="Has Start Date" />
            <RhfCheckboxField name="has_delivery_date" label="Has Delivery Date" />
            <RhfCheckboxField name="has_both_dates" label="Has Both Dates" />
        </>
    )
}
