"use client"

import { useRef, useState } from "react"
import { useFormContext, useController, type FieldValues, type FieldPath } from "react-hook-form"
import { useQuery, useQueryClient } from "@tanstack/react-query"
import { Building2, Loader2, PlusIcon } from "lucide-react"
import { useAuthApi } from "@/shared/useApi"
import { CUSTOMER_ROUTES } from "@garage/api"
import { Field, FieldLabel, FieldError, FieldDescription } from "@/shared/components/ui/field"
import { Button } from "@/shared/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/shared/components/ui/dialog"
import { ScrollArea } from "@/shared/components/ui/scroll-area"
import { DialogCloseContext } from "@/shared/hooks/use-dialog-close"
import {
    Combobox,
    ComboboxInput,
    ComboboxContent,
    ComboboxList,
    ComboboxItem,
    ComboboxEmpty,
} from "@/shared/components/ui/combobox"
import { CustomerForm } from "./customer-form"

// ── Customer option type (enriched for display) ──

type CustomerOption = {
    value: string
    label: string
    first_name?: string
    last_name?: string
    company_name?: string
    email?: string
    phone?: string
}

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

function extractItems(response: unknown): any[] {
    if (Array.isArray(response)) return response
    const obj = response as any
    if (Array.isArray(obj?.data?.data)) return obj.data.data
    if (Array.isArray(obj?.data)) return obj.data
    return []
}

function getInitials(opt: CustomerOption): string {
    if (opt.first_name || opt.last_name) {
        return [opt.first_name?.[0], opt.last_name?.[0]].filter(Boolean).join("").toUpperCase()
    }
    if (opt.company_name) return opt.company_name[0].toUpperCase()
    return "?"
}

// ── Props ──

export type RhfCustomerSelectFieldProps<
    TValues extends FieldValues,
    TName extends FieldPath<TValues>,
> = {
    name: TName
    label?: string
    description?: string
    required?: boolean
    disabled?: boolean
    placeholder?: string
    /** Filter customers by customer_type.name (case-insensitive). */
    customerType?: string
}

// ── Component ──

export function RhfCustomerSelectField<
    TValues extends FieldValues,
    TName extends FieldPath<TValues>,
>({
    name,
    label = "Customer",
    description,
    required,
    disabled,
    placeholder = "Search by name, company, or phone...",
    customerType,
}: RhfCustomerSelectFieldProps<TValues, TName>) {
    const api = useAuthApi()
    const anchorRef = useRef<HTMLDivElement>(null)
    const [inputValue, setInputValue] = useState("")
    const [isCreateOpen, setIsCreateOpen] = useState(false)
    const queryClient = useQueryClient()

    const { control } = useFormContext<TValues>()
    const {
        field,
        fieldState: { error },
    } = useController({ name, control, disabled })

    const { data: options = [], isLoading } = useQuery<CustomerOption[]>({
        queryKey: [CUSTOMER_ROUTES.INDEX, "customer-select", customerType ?? "all"],
        queryFn: async () => {
            const res = await api.customers.list()
            const items = extractItems(res)
            const filtered = customerType
                ? items.filter((item: any) =>
                      item.customer_type?.name?.toLowerCase() === customerType.toLowerCase(),
                  )
                : items
            return filtered.map(buildCustomerOption)
        },
        staleTime: 5 * 60 * 1000,
    })

    const filtered = inputValue
        ? options.filter((c) =>
              [c.first_name, c.last_name, c.company_name, c.email, c.phone]
                  .filter(Boolean)
                  .join(" ")
                  .toLowerCase()
                  .includes(inputValue.toLowerCase()),
          )
        : options

    const handleCreateSuccess = (data?: any) => {
        const item = data?.data ?? data
        if (!item?.id) {
            setIsCreateOpen(false)
            return
        }
        const newOption = buildCustomerOption(item)
        const key = [CUSTOMER_ROUTES.INDEX, "customer-select", customerType ?? "all"]

        queryClient.setQueryData<CustomerOption[]>(key, (prev = []) =>
            prev.some((o) => o.value === newOption.value) ? prev : [newOption, ...prev],
        )
        field.onChange(newOption)
        setIsCreateOpen(false)
    }

    const combobox = (
        <div ref={anchorRef}>
                <Combobox
                    value={field.value}
                    onValueChange={(val: CustomerOption | CustomerOption[] | null) => {
                        const single = Array.isArray(val) ? val[0] ?? null : val
                        field.onChange(
                            single ? { value: single.value, label: single.label } : null,
                        )
                    }}
                    disabled={field.disabled}
                    onInputValueChange={(val: string, { reason }: { reason: string }) => {
                        if (reason === "input-change") setInputValue(val)
                    }}
                    isItemEqualToValue={(item: CustomerOption, val: any) =>
                        item?.value === val?.value
                    }
                >
                    <ComboboxInput
                        placeholder={placeholder}
                        showClear={!!field.value}
                        onBlur={field.onBlur}
                        aria-invalid={!!error || undefined}
                    />
                    <ComboboxContent anchor={anchorRef}>
                        <ComboboxList className='overflow-auto'>
                            {isLoading && (
                                <div className="flex items-center justify-center py-6">
                                    <Loader2 className="size-4 animate-spin text-muted-foreground" />
                                </div>
                            )}

                            {!isLoading &&
                                filtered.map((opt) => (
                                    <ComboboxItem key={opt.value} value={opt}>
                                        <div className="flex items-center gap-3 py-0.5 w-full min-w-0">
                                            {/* Avatar circle with initials */}
                                            <div className="flex size-9 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary border border-border text-sm font-medium">
                                                {getInitials(opt)}
                                            </div>

                                            {/* Identity */}
                                            <div className="flex min-w-0 flex-1 flex-col gap-0.5">
                                                <span className="truncate text-sm font-medium leading-none">
                                                    {opt.label}
                                                </span>
                                                <div className="flex items-center gap-2 min-w-0">
                                                    {opt.company_name && opt.label !== opt.company_name && (
                                                        <span className="flex items-center gap-1 truncate text-xs text-muted-foreground">
                                                            <Building2 className="size-3 shrink-0" />
                                                            {opt.company_name}
                                                        </span>
                                                    )}
                                                    {opt.phone && (
                                                        <span className="text-xs text-muted-foreground truncate">
                                                            {opt.phone}
                                                        </span>
                                                    )}
                                                </div>
                                            </div>
                                        </div>
                                    </ComboboxItem>
                                ))}

                            {!isLoading && filtered.length === 0 && (
                                <ComboboxEmpty>No customers found</ComboboxEmpty>
                            )}
                        </ComboboxList>
                    </ComboboxContent>
                </Combobox>
            </div>
    )

    return (
        <Field data-invalid={!!error?.message || undefined}>
            {label && (
                <div className="flex items-center justify-between">
                    <FieldLabel>
                        {label}
                        {required && <span className="text-destructive ms-0.5">*</span>}
                    </FieldLabel>
                    <Button
                        type="button"
                        size="icon"
                        variant="ghost"
                        className="h-5 w-5"
                        onClick={() => setIsCreateOpen(true)}
                        title={`Add new ${label}`}
                    >
                        <PlusIcon className="h-3.5 w-3.5" />
                    </Button>
                </div>
            )}
            {combobox}
            {description && <FieldDescription>{description}</FieldDescription>}
            {error?.message && <FieldError>{error.message}</FieldError>}

            <Dialog open={isCreateOpen} onOpenChange={(v) => { if (!v) setIsCreateOpen(false) }}>
                <DialogContent className="min-w-xl">
                    <DialogHeader>
                        <DialogTitle className="text-2xl font-bold">
                            Add {label}
                        </DialogTitle>
                    </DialogHeader>
                    <ScrollArea className="max-h-[80vh] px-4">
                        <DialogCloseContext.Provider value={() => setIsCreateOpen(false)}>
                            <CustomerForm onSuccess={handleCreateSuccess} />
                        </DialogCloseContext.Provider>
                    </ScrollArea>
                </DialogContent>
            </Dialog>
        </Field>
    )
}
