"use client"

import * as React from "react"
import * as yup from "yup"
import { yupResolver } from "@hookform/resolvers/yup"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import {
  Dialog,
  DialogContent,
  DialogTitle,
} from "@/components/ui/dialog"
import { ReactSelect } from "@/components/ui/react-select"
import { Building2, Mail, Phone, User, MapPin, Link as LinkIcon, Calendar, MessageSquare } from "lucide-react"
import { DatePicker } from "@/components/ui/date-picker"
import { toast } from "sonner"
import { useCreateCustomerMutation, useUpdateCustomerMutation, type CreateCustomerBody, type CustomerBackend } from "@/api/rtk/customers-api"
import { useGetRolesQuery, useGetUserQuery, useGetUsersQuery } from "@/api/rtk"
import type { ApiUser } from "@/api/users/types"
import { pickRoleIdFromOrgRoles } from "@/components/deals/contributor-user-picker"
import { BrandSelect } from "@/components/shared/brand-select"
import { AccountTierSelect } from "@/components/shared/account-tier-select"
import { useForm, Controller } from "react-hook-form"
import useFormPersist from "react-hook-form-persist"
import { cn } from "@/lib/utils"
import { FormSectionHeading } from "./customer-details-shared"

const COUNTRIES = ["US", "UK", "CA", "AU", "DE", "FR", "IN", "Other"] as const

const websiteOptional = yup
  .string()
  .trim()
  .default("")
  .test("website-url", "Enter a valid URL (e.g. https://company.com)", (value) => {
    if (!value) return true
    const candidate = /^https?:\/\//i.test(value) ? value : `https://${value}`
    try {
      new URL(candidate)
      return true
    } catch {
      return false
    }
  })

const addCustomerFormSchema = yup
  .object({
    fullName: yup
      .string()
      .trim()
      .required("Full name is required")
      .max(200, "Full name is too long"),
    companyName: yup.string().trim().max(200, "Company name is too long").default(""),
    email: yup
      .string()
      .trim()
      .required("Email is required")
      .email("Enter a valid email")
      .max(254, "Email is too long"),
    phone: yup
      .string()
      .trim()
      .required("Phone is required")
      .min(3, "Phone is too short")
      .max(40, "Phone is too long"),
    addressUsa: yup.string().trim().max(500, "US address is too long").default(""),
    addressIntl: yup.string().trim().max(500, "International address is too long").default(""),
    postalCode: yup.string().trim().max(32, "Postal code is too long").default(""),
    website: websiteOptional,
    country: yup
      .string()
      .trim()
      .required("Country is required")
      .oneOf([...COUNTRIES], "Select a valid country"),
    brand: yup.string().trim().required("Brand is required").max(120, "Brand is too long"),
    assignedAmId: yup.string().trim().max(64).default(""),
    accountTier: yup.string().trim().max(120).default(""),
    contractExpiryDate: yup.string().trim().max(32).default(""),
    npsScore: yup
      .number()
      .optional()
      .min(0, "NPS must be at least 0")
      .max(10, "NPS must be at most 10"),
    npsDate: yup.string().trim().max(32).default(""),
    notes: yup.string().trim().max(10000, "Notes are too long").default(""),
  })
  .required() as yup.ObjectSchema<CreateCustomerBody>

function FieldError({ message }: { message?: string }) {
  if (!message) return null
  return <p className="text-[11px] text-red-600 mt-1 font-medium">{message}</p>
}

function FieldLabel({ children, required }: { children: React.ReactNode; required?: boolean }) {
  return (
    <label className="block text-[10px] font-bold text-gray-400 uppercase tracking-[0.09em] font-['Lexend_Deca'] mb-1.5 select-none">
      {children}
      {required && <span className="text-red-500 ml-0.5">*</span>}
    </label>
  )
}



export interface AddCustomerModalProps {
  isOpen: boolean
  onClose: () => void
  onSuccess?: () => void
  /** When set, dialog works in edit mode: same UI, prefill from customer, submit = update */
  editCustomer?: CustomerBackend | null
}

const defaultForm: CreateCustomerBody = {
  fullName: "",
  companyName: "",
  email: "",
  phone: "",
  addressUsa: "",
  addressIntl: "",
  postalCode: "",
  website: "",
  country: "",
  brand: "",
  assignedAmId: "",
  accountTier: "",
  contractExpiryDate: "",
  npsScore: undefined,
  npsDate: "",
  notes: "",
}

function customerToForm(c: CustomerBackend): CreateCustomerBody {
  return {
    fullName: c.fullName ?? c.customerName ?? "",
    companyName: c.companyName ?? "",
    email: c.email ?? "",
    phone: c.phone ?? "",
    addressUsa: c.addressUsa ?? "",
    addressIntl: c.addressIntl ?? "",
    postalCode: c.postalCode ?? "",
    website: c.website ?? "",
    country: c.country ?? "",
    brand: c.brand ?? "",
    assignedAmId: c.assignedAmId ?? "",
    accountTier: c.accountTier ?? "",
    contractExpiryDate: c.contractExpiryDate ?? "",
    npsScore: c.npsScore ?? undefined,
    npsDate: c.npsDate ?? "",
    notes: c.notes ?? "",
  }
}

export function AddCustomerModal({ isOpen, onClose, onSuccess, editCustomer }: AddCustomerModalProps) {
  const isEdit = Boolean(editCustomer?.id)
  const {
    control,
    handleSubmit,
    reset,
    setValue,
    watch,
    register,
    formState: { errors },
  } = useForm<CreateCustomerBody>({
    defaultValues: defaultForm,
    resolver: yupResolver(addCustomerFormSchema),
    mode: "onSubmit",
    reValidateMode: "onChange",
  })

  // Persistence: only for new customers, not when editing
  useFormPersist("add-customer-form", {
    watch,
    setValue,
    storage: typeof window !== 'undefined' ? window.localStorage : undefined,
    exclude: isEdit ? Object.keys(defaultForm) : [] // Don't persist if editing
  })

  const [createCustomer, { isLoading: isCreating }] = useCreateCustomerMutation()
  const [updateCustomer, { isLoading: isUpdating }] = useUpdateCustomerMutation()
  const isLoading = isCreating || isUpdating

  const { data: orgRoles = [] } = useGetRolesQuery(undefined, { skip: !isOpen })
  const amRoleId = React.useMemo(
    () =>
      pickRoleIdFromOrgRoles(orgRoles, [
        "am",
        "account manager",
        "AM",
        "Account Manager",
      ]),
    [orgRoles],
  )
  const { data: usersResponse } = useGetUsersQuery(
    { limit: 100, ...(amRoleId ? { roleId: amRoleId } : {}) },
    { skip: !isOpen },
  )
  const usersList = usersResponse?.data

  const assigneeId = editCustomer?.assignedAmId?.trim() ?? ""
  const assigneeAlreadyListed =
    !assigneeId || (usersList ?? []).some((u) => u.id === assigneeId)
  const { data: assigneeUser } = useGetUserQuery(assigneeId, {
    skip: !isOpen || !isEdit || assigneeAlreadyListed || !assigneeId,
  })

  const amUsersForSelect = React.useMemo(() => {
    const base = (usersList ?? []).filter((u) => u.name?.toLowerCase() !== "admin")
    const out: ApiUser[] = [...base]
    const link = editCustomer?.assignedAm
    const id = editCustomer?.assignedAmId?.trim()
    if (id && link?.name && !out.some((u) => u.id === id)) {
      out.unshift({ id, name: link.name, email: link.email ?? "" })
    }
    if (assigneeUser && !out.some((u) => u.id === assigneeUser.id)) {
      out.unshift(assigneeUser)
    }
    return out
  }, [usersList, assigneeUser, editCustomer?.assignedAmId, editCustomer?.assignedAm])

  const countryOptions = React.useMemo(
    () => COUNTRIES.map((c) => ({ value: c, label: c })),
    [],
  )

  const amUserOptions = React.useMemo(
    () => amUsersForSelect.map((u) => ({ value: u.id, label: u.name })),
    [amUsersForSelect],
  )

  React.useEffect(() => {
    if (!isOpen) return
    if (editCustomer) {
      reset(customerToForm(editCustomer))
    } else {
      // If NOT editing, we don't reset to default because we want to see persisted data
      // useFormPersist will populate it from localStorage
    }
  }, [isOpen, editCustomer, reset])

  const onFormSubmit = async (data: CreateCustomerBody) => {
    const payload = {
      ...data,
      fullName: data.fullName.trim(),
      companyName: data.companyName?.trim() || undefined,
      email: data.email.trim(),
      phone: data.phone.trim(),
      addressUsa: data.addressUsa?.trim() || undefined,
      addressIntl: data.addressIntl?.trim() || undefined,
      postalCode: data.postalCode?.trim() || undefined,
      website: data.website?.trim() || undefined,
      country: data.country.trim(),
      brand: data.brand.trim(),
      assignedAmId: data.assignedAmId?.trim() || undefined,
      accountTier: data.accountTier?.trim() || undefined,
      contractExpiryDate: data.contractExpiryDate?.trim() || undefined,
      npsScore: data.npsScore != null ? Number(data.npsScore) : undefined,
      npsDate: data.npsDate?.trim() || undefined,
      notes: data.notes?.trim() || undefined,
    }

    try {
      if (isEdit && editCustomer?.id) {
        await updateCustomer({ id: editCustomer.id, updates: payload }).unwrap()
        toast.success("Customer updated successfully")
      } else {
        await createCustomer(payload).unwrap()
        toast.success("Customer created successfully")
        // Clear persistence on success
        if (typeof window !== 'undefined') {
          window.localStorage.removeItem("add-customer-form")
        }
        reset(defaultForm)
      }
      onSuccess?.()
      onClose()
    } catch (err: unknown) {
      const msg = err && typeof err === "object" && "data" in err && typeof (err as { data?: { message?: string } }).data?.message === "string"
        ? (err as { data: { message: string } }).data.message
        : (isEdit ? "Failed to update customer" : "Failed to create customer")
      toast.error(msg)
    }
  }

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="sm:max-w-[1200px] w-[96vw] max-h-[90vh] p-0 overflow-hidden animate-in zoom-in-95 duration-200">
        <div className="relative overflow-hidden">
          <div className="absolute inset-0 bg-linear-to-br from-[#6C63FF] via-[#7C74FF] to-[#9B8FFF] opacity-100" />
          <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top_right,rgba(255,255,255,0.12),transparent_60%)]" />
          <div className="relative px-7 py-5 flex items-start justify-between gap-4">
            <div className="flex items-center gap-4 min-w-0">
              <div className="h-12 w-12 rounded-xl bg-white/15 border border-white/25 backdrop-blur-sm flex items-center justify-center shrink-0 shadow-inner">
                <Building2 size={22} className="text-white/90" />
              </div>
              <div className="min-w-0">
                <DialogTitle className="text-[20px] font-extrabold text-white font-['Lexend'] leading-tight">
                  {isEdit ? "Edit Customer" : "Add Customer"}
                </DialogTitle>
                <p className="text-[12px] text-white/75 font-medium mt-1">
                  {isEdit ? "Update customer record (Schema 4.1)" : "Create a new customer record (Schema 4.1)"}
                </p>
              </div>
            </div>
          </div>
        </div>

        <form
          onSubmit={handleSubmit(onFormSubmit, () =>
            toast.error("Please fix the highlighted fields"),
          )}
        >
          <div className="overflow-y-auto max-h-[calc(90vh-200px)] scrollbar-themed px-7 py-6 space-y-6">
            <section>
              <FormSectionHeading icon={<User size={14} />}>Contact</FormSectionHeading>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div className="sm:col-span-2">
                  <FieldLabel required>Full name</FieldLabel>
                  <Input
                    className={cn(
                      "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl",
                      errors.fullName && "border-red-500 focus-visible:ring-red-200",
                    )}
                    {...register("fullName")}
                    placeholder="Primary contact full name"
                  />
                  <FieldError message={errors.fullName?.message} />
                </div>
                <div>
                  <FieldLabel>Company name</FieldLabel>
                  <Input
                    className={cn(
                      "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl",
                      errors.companyName && "border-red-500 focus-visible:ring-red-200",
                    )}
                    {...register("companyName")}
                    placeholder="Client's company / trading name"
                  />
                  <FieldError message={errors.companyName?.message} />
                </div>
                <div>
                  <FieldLabel required>Email</FieldLabel>
                  <div className="relative">
                    <Mail size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
                    <Input
                      type="email"
                      className={cn(
                        "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl pl-9",
                        errors.email && "border-red-500 focus-visible:ring-red-200",
                      )}
                      {...register("email")}
                      placeholder="Primary email"
                    />
                  </div>
                  <FieldError message={errors.email?.message} />
                </div>
                <div>
                  <FieldLabel required>Phone</FieldLabel>
                  <div className="relative">
                    <Phone size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
                    <Input
                      className={cn(
                        "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl pl-9",
                        errors.phone && "border-red-500 focus-visible:ring-red-200",
                      )}
                      {...register("phone")}
                      placeholder="Primary phone"
                    />
                  </div>
                  <FieldError message={errors.phone?.message} />
                </div>
              </div>
            </section>

            <section>
              <FormSectionHeading icon={<MapPin size={14} />}>Address &amp; Location</FormSectionHeading>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div>
                  <FieldLabel>US address</FieldLabel>
                  <Input
                    className={cn(
                      "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl",
                      errors.addressUsa && "border-red-500 focus-visible:ring-red-200",
                    )}
                    {...register("addressUsa")}
                    placeholder="US address"
                  />
                  <FieldError message={errors.addressUsa?.message} />
                </div>
                <div>
                  <FieldLabel>International address</FieldLabel>
                  <Input
                    className={cn(
                      "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl",
                      errors.addressIntl && "border-red-500 focus-visible:ring-red-200",
                    )}
                    {...register("addressIntl")}
                    placeholder="CA/UK/other"
                  />
                  <FieldError message={errors.addressIntl?.message} />
                </div>
                <div>
                  <FieldLabel>Postal code</FieldLabel>
                  <Input
                    className={cn(
                      "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl",
                      errors.postalCode && "border-red-500 focus-visible:ring-red-200",
                    )}
                    {...register("postalCode")}
                    placeholder="Postal code"
                  />
                  <FieldError message={errors.postalCode?.message} />
                </div>
                <div>
                  <FieldLabel required>Country</FieldLabel>
                  <Controller
                    name="country"
                    control={control}
                    render={({ field, fieldState }) => (
                      <div>
                        <ReactSelect
                          value={field.value ?? ""}
                          onValueChange={field.onChange}
                          options={countryOptions}
                          placeholder="Select country"
                          allowEmpty
                          triggerClassName={cn(
                            "h-10 min-h-10 bg-gray-50 border-gray-200 rounded-xl text-[13px]",
                            fieldState.error && "border-red-500",
                          )}
                          contentClassName="rounded-xl"
                        />
                        <FieldError message={fieldState.error?.message} />
                      </div>
                    )}
                  />
                </div>
                <div className="sm:col-span-2">
                  <FieldLabel>Website</FieldLabel>
                  <div className="relative">
                    <LinkIcon size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
                    <Input
                      type="url"
                      className={cn(
                        "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl pl-9",
                        errors.website && "border-red-500 focus-visible:ring-red-200",
                      )}
                      {...register("website")}
                      placeholder="https://company.com"
                    />
                  </div>
                  <FieldError message={errors.website?.message} />
                </div>
              </div>
            </section>

            <section>
              <FormSectionHeading icon={<Building2 size={14} />}>Brand &amp; Assignment</FormSectionHeading>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div>
                  <Controller
                    name="brand"
                    control={control}
                    render={({ field, fieldState }) => (
                      <div>
                        <BrandSelect
                          value={field.value ?? ""}
                          onValueChange={field.onChange}
                          label="Brand"
                          required
                          placeholder="Select brand"
                          allowEmpty
                          skip={!isOpen}
                          triggerClassName={cn(
                            "h-10 bg-gray-50 border-gray-200 rounded-xl text-[13px]",
                            fieldState.error && "border-red-500",
                          )}
                        />
                        <FieldError message={fieldState.error?.message} />
                      </div>
                    )}
                  />
                </div>
                <div>
                  <FieldLabel>Assigned AM</FieldLabel>
                  <Controller
                    name="assignedAmId"
                    control={control}
                    render={({ field, fieldState }) => (
                      <div>
                        <ReactSelect
                          value={field.value ?? ""}
                          onValueChange={field.onChange}
                          options={amUserOptions}
                          placeholder="Select AM"
                          allowEmpty
                          triggerClassName={cn(
                            "h-10 min-h-10 bg-gray-50 border-gray-200 rounded-xl text-[13px]",
                            fieldState.error && "border-red-500",
                          )}
                          contentClassName="rounded-xl"
                        />
                        <FieldError message={fieldState.error?.message} />
                      </div>
                    )}
                  />
                </div>
                <div>
                  <Controller
                    name="accountTier"
                    control={control}
                    render={({ field, fieldState }) => (
                      <div>
                        <AccountTierSelect
                          value={field.value ?? ""}
                          onValueChange={field.onChange}
                          label="Account tier"
                          placeholder="Select account tier"
                          allowEmpty
                          skip={!isOpen}
                          triggerClassName={cn(
                            "h-10 bg-gray-50 border-gray-200 rounded-xl text-[13px]",
                            fieldState.error && "border-red-500",
                          )}
                        />
                        <FieldError message={fieldState.error?.message} />
                      </div>
                    )}
                  />
                </div>
              </div>
            </section>

            <section>
              <FormSectionHeading icon={<Calendar size={14} />}>Contract &amp; NPS</FormSectionHeading>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div>
                  <FieldLabel>Contract expiry date</FieldLabel>
                  <Controller
                    name="contractExpiryDate"
                    control={control}
                    render={({ field }) => (
                      <DatePicker
                        value={field.value}
                        onChange={field.onChange}
                        triggerClassName="h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl"
                      />
                    )}
                  />
                </div>
                <div>
                  <FieldLabel>NPS score (0–10)</FieldLabel>
                  <Input
                    type="number"
                    min={0}
                    max={10}
                    className={cn(
                      "h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl",
                      errors.npsScore && "border-red-500 focus-visible:ring-red-200",
                    )}
                    {...register("npsScore", {
                      setValueAs: (v) => {
                        if (v === "" || v === null || v === undefined) return undefined
                        const n = Number(v)
                        return Number.isFinite(n) ? n : undefined
                      },
                    })}
                    placeholder="0–10"
                  />
                  <FieldError message={errors.npsScore?.message} />
                </div>
                <div>
                  <FieldLabel>NPS date</FieldLabel>
                  <Controller
                    name="npsDate"
                    control={control}
                    render={({ field }) => (
                      <DatePicker
                        value={field.value}
                        onChange={field.onChange}
                        triggerClassName="h-10 text-[14px] bg-gray-50 border-gray-200 rounded-xl"
                      />
                    )}
                  />
                </div>
              </div>
            </section>


            <section>
              <FormSectionHeading icon={<MessageSquare size={14} />}>Notes</FormSectionHeading>
              <Textarea
                className={cn(
                  "min-h-[80px] text-[14px] bg-gray-50 border-gray-200 rounded-xl resize-y",
                  errors.notes && "border-red-500 focus-visible:ring-red-200",
                )}
                {...register("notes")}
                placeholder="Relationship intelligence: champions, sceptics, sensitivities"
              />
              <FieldError message={errors.notes?.message} />
            </section>
          </div>

          <div className="border-t border-gray-100 px-7 py-4 flex items-center justify-end gap-3 bg-gray-50/50">
            <Button type="button" variant="outline" size="md" onClick={onClose} disabled={isLoading}>
              Cancel
            </Button>
            <Button type="submit" size="md" disabled={isLoading}>
              {isLoading ? (isEdit ? "Saving..." : "Creating...") : (isEdit ? "Save changes" : "Create Customer")}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  )
}
