"use client"

import * as React from "react"
import { useRouter } from "next/navigation"
import { Controller, type UseFormReturn } from "react-hook-form"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import { TabsContent } from "@/components/ui/tabs"
import { DialogFooter } from "@/components/ui/dialog"
import { cn } from "@/lib/utils"
import { BrandSelect } from "@/components/shared/brand-select"
import { DealTypeSelect } from "@/components/shared/deal-type-select"
import { RegionSelect } from "@/components/shared/region-select"
import { DatePicker } from "@/components/ui/date-picker"
import {
    LeadSearchCombobox,
    CustomerSearchCombobox,
} from "@/components/deals/business-deal-form-search-comboboxes"
import {
    defaultValues,
    type FormValues,
} from "@/components/deals/business-deal-form-types"
import type { Deal } from "@/api/rtk/deals-api"
import type { CustomerBackend } from "@/api/rtk/customers-api"

import { useAppDispatch, useAppSelector } from "@/store/hooks"
import {
    selectBusinessDealDialog,
    closeBusinessDealDialog,
    setBusy,
} from "@/store/slices/business-deal-dialog-slice"
import {
    useCreateBusinessDealMutation,
    useGetBusinessDealQuery,
    useUpdateBusinessDealMutation,
} from "@/api/rtk/business-deals-api"
import { useGetCustomerQuery, useGetDealQuery } from "@/api/rtk"
import { useQueryClient } from "@tanstack/react-query"
import { invalidateBusinessBoardColumnsForStages } from "@/features/business-deals/invalidate-board-columns"
import { toast } from "sonner"
import { toDateInput } from "@/components/deals/business-deal-form-utils"
import {
    isDiscoverMeetingBookedStage,
    isDiscoveryMeetingVerifiedForBusinessDeal,
} from "@/lib/deal-stage-labels"
import {
    BusinessDealAeField,
    BusinessDealAeReadOnly,
    filterIdsToTeamAes,
    useTeamAePool,
} from "@/components/deals/business-deal-ae-field"

interface BusinessDealFormProps {
    form: UseFormReturn<FormValues>
    hideCustomerLink?: boolean
}

export function BusinessDealForm({ form, hideCustomerLink }: BusinessDealFormProps) {
    const dispatch = useAppDispatch()
    const router = useRouter()
    const queryClient = useQueryClient()
    const { open, mode, businessDealId, prefill, busy, activeTab } = useAppSelector(
        selectBusinessDealDialog,
    )

    const readOnly = mode === "view"
    const {
        register,
        handleSubmit,
        control,
        watch,
        reset,
        formState: { errors },
    } = form

    const linkKind = watch("linkKind")
    const watchedCustomerId = watch("customerId")
    const selectedLeadId = watch("leadId")

    const { data: existing, isLoading: loadingDeal } = useGetBusinessDealQuery(
        businessDealId ?? "",
        { skip: !open || !businessDealId || mode === "create" },
    )

    React.useEffect(() => {
        if (!open || mode === "create" || !businessDealId) return

        if (!existing) {
            reset(defaultValues)
            return
        }

        const pipelineId =
            existing.stageDetail?.pipelineId?.trim() ||
            existing.PipelineStage?.pipelineId?.trim() ||
            existing.PipelineStage?.pipeline?.id?.trim() ||
            ""
        const hasLeadLink = Boolean(existing.leadId?.trim())

        reset({
            title: existing.title ?? "",
            dealType: existing.dealType ?? "",
            linkKind: hasLeadLink ? "lead" : "customer",
            leadId: existing.leadId ?? "",
            customerId: existing.customerId ?? "",
            region: existing.region ?? "",
            pipelineId,
            pipelineStageId: existing.pipelineStageId ?? "",
            pipelineSubStageId: existing.pipelineSubStageId ?? "",
            expectedCloseDate: toDateInput(existing.expectedCloseDate),
            dealValue: existing.dealValue ?? "",
            probability:
                existing.probability != null ? String(existing.probability) : "",
            brand: existing.brand ?? "",
            notes: existing.notes ?? "",
            aeIds: existing.aeIds ?? [],
        })
    }, [open, mode, businessDealId, existing, reset])

    const [createDeal] = useCreateBusinessDealMutation()
    const [updateDeal] = useUpdateBusinessDealMutation()

    const { data: linkedCustomer, isLoading: loadingLinkedCustomer } =
        useGetCustomerQuery(watchedCustomerId?.trim() ?? "", {
            skip:
                !open ||
                !watchedCustomerId?.trim() ||
                (linkKind !== "customer" && mode === "create"),
        })

    const { data: leadPeek, isFetching: loadingLeadPeek } = useGetDealQuery(form.watch("leadId") ?? "", {
        skip:
            !open ||
            linkKind !== "lead" ||
            !form.watch("leadId")?.trim() ||
            !!prefill?.leadDisplayName?.trim() ||
            mode !== "create",
    })

    const { data: linkedLeadFull, isLoading: loadingLinkedLead } = useGetDealQuery(
        selectedLeadId?.trim() ?? "",
        {
            skip: !open || !selectedLeadId?.trim(),
        },
    )

    const { teamAeIds: orgAeIds, labelById } = useTeamAePool(null, !open)

    const lastInheritedLeadRef = React.useRef<string | null>(null)
    const lastInheritedCustomerRef = React.useRef<string | null>(null)

    React.useEffect(() => {
        if (!open) {
            lastInheritedLeadRef.current = null
            lastInheritedCustomerRef.current = null
        }
    }, [open])

    React.useEffect(() => {
        if (!open || mode !== "create" || linkKind !== "lead") return
        const id = selectedLeadId?.trim()
        if (!id) {
            lastInheritedLeadRef.current = null
            return
        }
        if (lastInheritedLeadRef.current === id) return
        if (loadingLinkedLead) return
        lastInheritedLeadRef.current = id
        const fromLead = linkedLeadFull?.aeIds?.filter(Boolean) ?? []
        if (!fromLead.length) return
        form.setValue("aeIds", filterIdsToTeamAes(fromLead, orgAeIds), {
            shouldDirty: true,
        })
    }, [
        open,
        mode,
        linkKind,
        selectedLeadId,
        linkedLeadFull?.aeIds,
        loadingLinkedLead,
        orgAeIds,
        form,
    ])

    React.useEffect(() => {
        if (!open || mode !== "create" || linkKind !== "customer") return
        const id = watchedCustomerId?.trim()
        if (!id) {
            lastInheritedCustomerRef.current = null
            return
        }
        if (lastInheritedCustomerRef.current === id) return
        if (loadingLinkedCustomer) return
        lastInheritedCustomerRef.current = id
        const amId = linkedCustomer?.assignedAmId?.trim()
        if (!amId) return
        form.setValue(
            "aeIds",
            filterIdsToTeamAes([amId], orgAeIds).length ? [amId] : [],
            { shouldDirty: true },
        )
    }, [
        open,
        mode,
        linkKind,
        watchedCustomerId,
        linkedCustomer?.assignedAmId,
        loadingLinkedCustomer,
        orgAeIds,
        form,
    ])

    const aeHelperText = React.useMemo(() => {
        if (mode !== "create") return null
        if (linkKind === "lead" && (linkedLeadFull?.aeIds?.length ?? 0) > 0) {
            return "Pre-filled from linked lead — you can change before saving."
        }
        if (linkKind === "customer" && linkedCustomer?.assignedAmId?.trim()) {
            return "Suggested from customer's Assigned AM."
        }
        return null
    }, [mode, linkKind, linkedLeadFull?.aeIds, linkedCustomer?.assignedAmId])

    // Auto-populate brand from linked lead when a lead is selected
    const leadBrand = linkedLeadFull?.brand?.trim()
    React.useEffect(() => {
        if (linkKind === "lead" && selectedLeadId && leadBrand) {
            const currentBrand = form.getValues("brand")
            if (!currentBrand?.trim()) {
                form.setValue("brand", leadBrand)
            }
        }
    }, [selectedLeadId, leadBrand, linkKind, form])

    const leadNameDisplay =
        mode !== "create" && existing?.linkedLead
            ? existing.linkedLead.customerName?.trim() ||
            existing.linkedLead.leadId ||
            ""
            : prefill?.leadDisplayName?.trim() ||
            leadPeek?.customerName?.trim() ||
            leadPeek?.leadId ||
            ""

    const customerNameDisplay = React.useMemo(() => {
        if (linkKind !== "customer") return ""
        if (linkedCustomer) {
            return (
                linkedCustomer.fullName?.trim() ||
                linkedCustomer.companyName?.trim() ||
                linkedCustomer.customerName?.trim() ||
                linkedCustomer.email?.trim() ||
                linkedCustomer.id ||
                "—"
            )
        }
        if (readOnly && existing?.linkedCustomer) {
            const lc = existing.linkedCustomer
            return (
                lc.fullName?.trim() ||
                lc.companyName?.trim() ||
                lc.customerName?.trim() ||
                lc.email?.trim() ||
                existing.customerId ||
                "—"
            )
        }
        const customerIdW = form.watch("customerId")
        if (customerIdW?.trim() && loadingLinkedCustomer) return "Loading…"
        if (customerIdW?.trim()) return customerIdW
        return "—"
    }, [
        linkKind,
        linkedCustomer,
        readOnly,
        existing,
        form.watch("customerId"),
        loadingLinkedCustomer,
    ])
    const getSavedPipelineContext = React.useCallback(
        (record: {
            pipelineStageId?: string | null
            pipelineSubStageId?: string | null
            stageDetail?: { pipelineId?: string | null } | null
            pipelineStage?: { pipeline?: { id?: string | null } | null } | null
        }) => {
            const pipelineId =
                record.stageDetail?.pipelineId?.trim() ||
                record.pipelineStage?.pipeline?.id?.trim() ||
                ""
            const stageIds = [
                record.pipelineStageId?.trim(),
                record.pipelineSubStageId?.trim(),
            ].filter(Boolean) as string[]

            return { pipelineId, stageIds }
        },
        [],
    )

    const invalidateBoardForSavedDeal = React.useCallback(
        (
            nextRecord: {
                pipelineStageId?: string | null
                pipelineSubStageId?: string | null
                stageDetail?: { pipelineId?: string | null } | null
                pipelineStage?: { pipeline?: { id?: string | null } | null } | null
            },
            previousRecord?: {
                pipelineStageId?: string | null
                pipelineSubStageId?: string | null
                stageDetail?: { pipelineId?: string | null } | null
                pipelineStage?: { pipeline?: { id?: string | null } | null } | null
            } | null,
        ) => {
            const next = getSavedPipelineContext(nextRecord)
            const previous = previousRecord ? getSavedPipelineContext(previousRecord) : null

            if (next.pipelineId) {
                invalidateBusinessBoardColumnsForStages(
                    queryClient,
                    next.pipelineId,
                    next.stageIds,
                    { invalidateCounts: true },
                )
            }

            if (
                previous?.pipelineId &&
                previous.pipelineId !== next.pipelineId
            ) {
                invalidateBusinessBoardColumnsForStages(
                    queryClient,
                    previous.pipelineId,
                    previous.stageIds,
                    { invalidateCounts: true },
                )
            }
        },
        [getSavedPipelineContext, queryClient],
    )

    const onSubmitInternal = async (values: FormValues) => {
        if (readOnly) return

        if (
            mode === "create" &&
            values.linkKind === "lead" &&
            values.leadId?.trim() &&
            loadingLinkedLead
        ) {
            toast.error("Still loading linked lead — try again in a moment.")
            return
        }

        if (
            mode === "create" &&
            values.linkKind === "lead" &&
            values.leadId?.trim() &&
            linkedLeadFull &&
            isDiscoverMeetingBookedStage(linkedLeadFull, undefined) &&
            !isDiscoveryMeetingVerifiedForBusinessDeal(linkedLeadFull)
        ) {
            const showup = linkedLeadFull.discoveryMeetingClientShowup
            toast.error(
                showup === false
                    ? "Cannot create a business deal after a no-show."
                    : "QA must verify discovery meeting attendance (client showed up) before creating a business deal.",
            )
            return
        }

        dispatch(setBusy(true))
        const probabilityNum =
            values.probability?.trim() === ""
                ? undefined
                : Number.parseInt(values.probability ?? "", 10)
        const body = {
            title: values.title.trim(),
            dealType: values.dealType?.trim() || undefined,
            leadId:
                values.linkKind === "lead"
                    ? values.leadId?.trim()
                    : undefined,
            customerId:
                values.linkKind === "customer"
                    ? values.customerId?.trim()
                    : undefined,
            region: values.region?.trim() || undefined,
            expectedCloseDate: values.expectedCloseDate?.trim() || undefined,
            dealValue: values.dealValue?.trim() || undefined,
            probability:
                probabilityNum !== undefined && !Number.isNaN(probabilityNum)
                    ? probabilityNum
                    : undefined,
            brand: values.brand?.trim() || undefined,
            aeIds: values.aeIds ?? [],
        }

        try {
            if (mode === "edit" && businessDealId) {
                const updated = await updateDeal({
                    id: businessDealId,
                    body,
                }).unwrap()
                toast.success("Business deal updated")
                invalidateBoardForSavedDeal(updated, existing ?? null)
            } else {
                const created = await createDeal({
                    ...body,
                    ...(prefill?.ownerId?.trim()
                        ? { ownerId: prefill.ownerId.trim() }
                        : {}),
                }).unwrap()
                toast.success("Business deal created")
                invalidateBoardForSavedDeal(created)
                dispatch(closeBusinessDealDialog())
                router.push("/sales-deals")
                return
            }

            dispatch(closeBusinessDealDialog())
        } catch (e: unknown) {
            const msg =
                typeof e === "object" &&
                    e !== null &&
                    "data" in e &&
                    typeof (e as { data?: { message?: string } }).data?.message ===
                    "string"
                    ? (e as { data: { message: string } }).data.message
                    : "Request failed"
            toast.error(msg)
        } finally {
            dispatch(setBusy(false))
        }
    }

    const showLeadIdField =
        mode === "create" && linkKind === "lead" && !prefill?.leadId

    const lockedCustomerFromPrefill =
        mode === "create" &&
        linkKind === "customer" &&
        Boolean(prefill?.customerId?.trim())

    const showCustomerSearchField =
        linkKind === "customer" &&
        !readOnly &&
        (mode === "create" ? !prefill?.customerId?.trim() : mode === "edit")

    return (
        <form
            onSubmit={handleSubmit(onSubmitInternal)}
            className="flex flex-col flex-1 min-h-0 overflow-hidden h-full"
        >
            <div className="flex-1 overflow-y-auto px-6 py-4">
                <TabsContent
                    value="details"
                    className="mt-0 grid grid-cols-2 gap-4 space-y-0 outline-none"
                >
                    <div className="space-y-2">
                        <Label htmlFor="bd-title">Deal title</Label>
                        <Input
                            id="bd-title"
                            disabled={readOnly || loadingDeal}
                            {...register("title")}
                        />
                        {errors.title && (
                            <p className="text-sm text-destructive">
                                {errors.title.message}
                            </p>
                        )}
                    </div>

                    <div className="space-y-2">
                        <Controller
                            name="dealType"
                            control={control}
                            render={({ field }) => (
                                <DealTypeSelect
                                    label="Deal type"
                                    value={field.value ?? ""}
                                    onValueChange={field.onChange}
                                    disabled={readOnly || loadingDeal}
                                    skip={!open}
                                    allowEmpty
                                    placeholder="Select deal type"
                                />
                            )}
                        />
                        {errors.dealType && (
                            <p className="text-sm text-destructive">
                                {errors.dealType.message}
                            </p>
                        )}
                    </div>

                    {mode === "create" ? (
                        <div className="space-y-3 col-span-2">
                            <div className="flex flex-col gap-2">
                                {!hideCustomerLink && <Label>Link deal to</Label>}
                                {!hideCustomerLink && <Controller
                                    name="linkKind"
                                    control={control}
                                    render={({ field }) => (
                                        <RadioGroup
                                            onValueChange={(val) => {
                                                field.onChange(val);
                                                if (val === "lead") {
                                                    form.setValue("customerId", "");
                                                    lastInheritedCustomerRef.current = null;
                                                } else {
                                                    form.setValue("leadId", "");
                                                    lastInheritedLeadRef.current = null;
                                                }
                                                form.setValue("aeIds", []);
                                            }}
                                            value={field.value}
                                            disabled={readOnly || loadingDeal}
                                            className="flex items-center gap-6"
                                        >
                                            <div className="flex items-center space-x-2">
                                                <RadioGroupItem value="lead" id="lk-lead" />
                                                <Label htmlFor="lk-lead" className="font-normal cursor-pointer">Lead</Label>
                                            </div>
                                            <div className="flex items-center space-x-2">
                                                <RadioGroupItem value="customer" id="lk-customer" />
                                                <Label htmlFor="lk-customer" className="font-normal cursor-pointer">Customer</Label>
                                            </div>
                                        </RadioGroup>
                                    )}
                                />}
                            </div>

                            {linkKind === "lead" ? (
                                <div className="space-y-2 pt-1">
                                    <Label htmlFor="bd-lead-search">Lead</Label>
                                    {readOnly || prefill?.leadId ? (
                                        <Input
                                            readOnly
                                            disabled
                                            className="bg-muted/50"
                                            value={leadNameDisplay}
                                        />
                                    ) : (
                                        <Controller
                                            name="leadId"
                                            control={control}
                                            render={({ field }) => (
                                                <LeadSearchCombobox
                                                    value={field.value ?? ""}
                                                    onChange={field.onChange}
                                                    disabled={readOnly || loadingDeal}
                                                    selectedDeal={linkedLeadFull ?? null}
                                                    loadingSelected={
                                                        Boolean(field.value?.trim()) &&
                                                        loadingLinkedLead
                                                    }
                                                />
                                            )}
                                        />
                                    )}
                                    {errors.leadId && (
                                        <p className="text-sm text-destructive">
                                            {errors.leadId.message}
                                        </p>
                                    )}
                                </div>
                            ) : (
                                <div className="space-y-2 pt-1">
                                    <Label htmlFor="bd-cust-search">Customer</Label>
                                    {readOnly || lockedCustomerFromPrefill ? (
                                        <>
                                            <Input
                                                readOnly
                                                disabled
                                                className="bg-muted/50"
                                                value={customerNameDisplay}
                                            />
                                            <input type="hidden" {...register("customerId")} />
                                        </>
                                    ) : showCustomerSearchField ? (
                                        <Controller
                                            name="customerId"
                                            control={control}
                                            render={({ field }) => (
                                                <CustomerSearchCombobox
                                                    value={field.value ?? ""}
                                                    onChange={field.onChange}
                                                    disabled={readOnly || loadingDeal}
                                                    selectedCustomer={linkedCustomer ?? null}
                                                    loadingSelected={
                                                        Boolean(field.value?.trim()) &&
                                                        loadingLinkedCustomer
                                                    }
                                                />
                                            )}
                                        />
                                    ) : null}
                                    {errors.customerId && (
                                        <p className="text-sm text-destructive">
                                            {errors.customerId.message}
                                        </p>
                                    )}
                                </div>
                            )}
                        </div>
                    ) : null}

                    {readOnly ? (
                        <BusinessDealAeReadOnly
                            aeIds={existing?.aeIds}
                            aes={existing?.aes}
                            labelById={labelById}
                        />
                    ) : (
                        <BusinessDealAeField
                            control={control}
                            disabled={loadingDeal}
                            helperText={aeHelperText}
                            skipQueries={!open}
                        />
                    )}

                    <div className="space-y-2 col-span-2">
                        <Controller
                            name="region"
                            control={control}
                            render={({ field }) => (
                                <RegionSelect
                                    label="Region"
                                    value={field.value ?? ""}
                                    onValueChange={field.onChange}
                                    disabled={readOnly || loadingDeal}
                                    skip={!open}
                                    allowEmpty
                                />
                            )}
                        />
                    </div>

                    <div className="space-y-2">
                        <Label htmlFor="bd-close">Expected close date</Label>
                        <Controller
                            name="expectedCloseDate"
                            control={control}
                            render={({ field }) => (
                                <DatePicker
                                    value={field.value}
                                    onChange={field.onChange}
                                    disabled={readOnly || loadingDeal}
                                    placeholder="Select date"
                                />
                            )}
                        />
                        {errors.expectedCloseDate && (
                            <p className="text-sm text-destructive">
                                {errors.expectedCloseDate.message}
                            </p>
                        )}
                    </div>

                    <div className="space-y-2">
                        <Label htmlFor="bd-value">Deal value</Label>
                        <Input
                            id="bd-value"
                            type="text"
                            inputMode="decimal"
                            disabled={readOnly || loadingDeal}
                            placeholder="0.00"
                            {...register("dealValue")}
                        />
                        {errors.dealValue && (
                            <p className="text-sm text-destructive">
                                {errors.dealValue.message}
                            </p>
                        )}
                    </div>

                    <div className="col-span-2 grid grid-cols-1 gap-4 sm:grid-cols-2">
                        <div className="space-y-2">
                            <Label htmlFor="bd-prob">Probability (%)</Label>
                            <Input
                                id="bd-prob"
                                type="number"
                                min={0}
                                max={100}
                            disabled={readOnly || loadingDeal}
                                {...register("probability")}
                            />
                            {errors.probability && (
                                <p className="text-sm text-destructive">
                                    {errors.probability.message}
                                </p>
                            )}
                        </div>

                        <div className="space-y-2">
                            <Label>Brand assignment</Label>
                            <Controller
                                name="brand"
                                control={control}
                                render={({ field }) => (
                                    <BrandSelect
                                        value={field.value ?? ""}
                                        onValueChange={field.onChange}
                                        disabled={readOnly || loadingDeal}
                                        skip={!open}
                                        allowEmpty
                                    />
                                )}
                            />
                            {errors.brand && (
                                <p className="text-sm text-destructive">
                                    {errors.brand.message}
                                </p>
                            )}
                        </div>
                    </div>
                </TabsContent>
            </div>

            {activeTab !== "import" && (
                <DialogFooter className="px-6 py-4 border-t gap-2 sm:justify-end shrink-0">
                    <Button
                        type="button"
                        variant="outline"
                        onClick={() => dispatch(closeBusinessDealDialog())}
                        disabled={busy}
                    >
                        {readOnly ? "Close" : "Cancel"}
                    </Button>
                    {!readOnly && (
                        <Button type="submit" loading={busy} disabled={loadingDeal}>
                            {mode === "edit" ? "Save" : "Create deal"}
                        </Button>
                    )}
                </DialogFooter>
            )}
        </form>
    )
}
