import { defineRouteConfig } from "@medusajs/admin-sdk"
import { Container, Heading, Button, Input, Label } from "@medusajs/ui"
import { useState, useMemo } from "react"
import { useMutation, useQuery } from "@tanstack/react-query"
import { useNavigate } from "react-router-dom"
import { sdk } from "../../../lib/sdk"

const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const MIN_PASSWORD_LENGTH = 8

type RegistrationField = {
  api_key: string
  label: string
  field_type: string
  required: boolean
  placeholder?: string
  options_source?: string
}

export const config = defineRouteConfig({
  label: "Create Customer",
  nested: "/customers",
})

export default function CreateCustomerPage() {
  const navigate = useNavigate()
  const [formValues, setFormValues] = useState<Record<string, unknown>>({})
  const [error, setError] = useState<string | null>(null)
  const [successMessage, setSuccessMessage] = useState<string | null>(null)
  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({})

  const { data: fieldsData, isLoading: fieldsLoading } = useQuery({
    queryKey: ["admin", "customers", "register-fields"],
    queryFn: async () => {
      const r = await sdk.fetch("/admin/customers/register-fields")
      if (!r.ok) throw new Error("Failed to load form fields")
      return r.json() as Promise<{ fields: RegistrationField[] }>
    },
  })

  const { data: countriesData, isLoading: countriesLoading } = useQuery({
    queryKey: ["admin", "countries"],
    queryFn: async () => {
      const r = await sdk.fetch("/admin/countries")
      if (!r.ok) throw new Error("Failed to load countries")
      return r.json() as Promise<{
        countries: { iso_2: string; display_name: string }[]
      }>
    },
  })

  const fields = fieldsData?.fields ?? []
  const countryOptions = countriesData?.countries ?? []

  const setValue = (apiKey: string, value: unknown) => {
    setFormValues((prev) => ({ ...prev, [apiKey]: value }))
    setFieldErrors((prev) => ({ ...prev, [apiKey]: "" }))
  }

  /** Always blank by default: no pre-filled values from config or elsewhere. */
  const getValue = (apiKey: string) => {
    const v = formValues[apiKey]
    if (v === undefined || v === null) return ""
    return String(v)
  }

  const validate = (): Record<string, string> => {
    const err: Record<string, string> = {}
    const email = String(getValue("email") ?? "").trim()
    const password = String(formValues["password"] ?? "")
    const confirmPassword = String(formValues["confirm_password"] ?? "")
    const fullName = String(getValue("full_name") ?? "").trim()
    const country = String(getValue("country") ?? "").trim().toLowerCase().slice(0, 2)

    for (const field of fields) {
      if (!field.required) continue
      if (field.field_type === "checkbox") {
        const v = formValues[field.api_key]
        if (v !== true && v !== "true") {
          err[field.api_key] = `${field.label} is required.`
        }
        continue
      }
      if (field.field_type === "password" || field.field_type === "confirm_password") continue
      const str = String(getValue(field.api_key) ?? "").trim()
      if (!str) err[field.api_key] = `${field.label} is required.`
    }

    if (email && !EMAIL_REGEX.test(email)) {
      err.email = "Enter a valid email address."
    }
    if (fullName.length > 0 && fullName.length < 2) {
      err.full_name = "Full name must be at least 2 characters."
    }
    if (country.length > 0 && country.length !== 2) {
      err.country = "Country must be a 2-letter code."
    }
    if (countryOptions.length > 0 && country && !countryOptions.some((c) => c.iso_2 === country)) {
      err.country = "Select a valid country."
    }
    if (password.length > 0 && password.length < MIN_PASSWORD_LENGTH) {
      err.password = `Password must be at least ${MIN_PASSWORD_LENGTH} characters.`
    }
    if (password !== confirmPassword) {
      err.confirm_password = "Password and Confirm Password do not match."
    }

    return err
  }

  const buildPayload = useMemo(() => {
    const body: Record<string, unknown> = {}
    for (const field of fields) {
      const val = formValues[field.api_key]
      if (field.field_type === "checkbox") {
        body[field.api_key] = val === true || val === "true"
      } else if (val !== undefined && val !== null) {
        const str = String(val).trim()
        body[field.api_key] = str || null
      }
    }
    body.password = formValues["password"] ?? ""
    body.confirm_password = formValues["confirm_password"] ?? ""
    return body
  }, [fields, formValues])

  const create = useMutation({
    mutationFn: async () => {
      setError(null)
      const err = validate()
      setFieldErrors(err)
      if (Object.keys(err).length > 0) {
        throw new Error(Object.values(err)[0])
      }
      const body = { ...buildPayload }
      if (body.email && typeof body.email === "string") {
        body.email = body.email.toLowerCase()
      }
      if (body.country && typeof body.country === "string") {
        body.country = body.country.slice(0, 2).toLowerCase()
      }

      const r = await sdk.fetch("/admin/customers/register", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      })
      const text = await r.text()
      if (!r.ok) {
        let msg = text
        try {
          const j = JSON.parse(text)
          if (j.message) msg = j.message
        } catch {
          /* ignore */
        }
        throw new Error(msg)
      }
      return text ? JSON.parse(text) : {}
    },
    onSuccess: () => {
      setSuccessMessage("Customer created successfully.")
      setTimeout(() => navigate("/customers"), 1500)
    },
    onError: (e: Error) => {
      setError(e.message)
      setFieldErrors({})
    },
  })

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    setError(null)
    const err = validate()
    setFieldErrors(err)
    if (Object.keys(err).length > 0) return
    create.mutate()
  }

  const renderField = (field: RegistrationField) => {
    const value = getValue(field.api_key)
    const err = fieldErrors[field.api_key]
    const requiredLabel = field.required ? " *" : ""

    if (field.field_type === "checkbox") {
      const raw = formValues[field.api_key]
      const checked = raw === true || raw === "true"
      return (
        <div key={field.api_key} className="min-w-0">
          <div className="flex items-center gap-2">
            <input
              type="checkbox"
              id={`reg-${field.api_key}`}
              checked={checked}
              onChange={(e) => setValue(field.api_key, e.target.checked)}
              className="rounded"
            />
            <Label htmlFor={`reg-${field.api_key}`}>
              {field.label}{requiredLabel}
            </Label>
          </div>
          {err && <p className="text-red-600 text-xs mt-1">{err}</p>}
        </div>
      )
    }

    if (field.field_type === "select" && field.options_source === "countries") {
      return (
        <div key={field.api_key} className="min-w-0">
          <Label>{field.label}{requiredLabel}</Label>
          <select
            value={String(value ?? "")}
            onChange={(e) => setValue(field.api_key, e.target.value)}
            className="border rounded px-2 py-1.5 w-full bg-ui-bg-field"
            disabled={countriesLoading}
          >
            <option value="">
              {countriesLoading ? "Loading…" : field.placeholder ?? "Select"}
            </option>
            {countryOptions.map((c) => (
              <option key={c.iso_2} value={c.iso_2}>
                {c.display_name || c.iso_2}
              </option>
            ))}
          </select>
          {err && <p className="text-red-600 text-xs mt-1">{err}</p>}
        </div>
      )
    }

    if (field.field_type === "password" || field.field_type === "confirm_password") {
      return (
        <div key={field.api_key} className="min-w-0">
          <Label>{field.label}{requiredLabel}</Label>
          <Input
            type="password"
            value={String(value ?? "")}
            onChange={(e) => setValue(field.api_key, e.target.value)}
            placeholder={field.placeholder}
            className="w-full"
            autoComplete="new-password"
          />
          {err && <p className="text-red-600 text-xs mt-1">{err}</p>}
        </div>
      )
    }

    if (field.field_type === "email") {
      return (
        <div key={field.api_key} className="min-w-0">
          <Label>{field.label}{requiredLabel}</Label>
          <Input
            type="email"
            value={String(value ?? "")}
            onChange={(e) => setValue(field.api_key, e.target.value)}
            placeholder={field.placeholder}
            className="w-full"
            autoComplete="off"
          />
          {err && <p className="text-red-600 text-xs mt-1">{err}</p>}
        </div>
      )
    }

    return (
      <div key={field.api_key} className="min-w-0">
        <Label>{field.label}{requiredLabel}</Label>
        <Input
          value={String(value ?? "")}
          onChange={(e) => setValue(field.api_key, e.target.value)}
          placeholder={field.placeholder}
          className="w-full"
        />
        {err && <p className="text-red-600 text-xs mt-1">{err}</p>}
      </div>
    )
  }

  return (
    <Container className="px-3 sm:px-4">
      <Heading level="h1" className="mb-4 sm:mb-6 text-xl sm:text-2xl">
        Create Customer
      </Heading>
      <form
        onSubmit={handleSubmit}
        className="flex flex-col gap-4 w-full max-w-md"
        autoComplete="off"
      >
        {successMessage && (
          <div className="p-3 rounded bg-green-100 text-green-800 text-sm">
            {successMessage}
          </div>
        )}
        {error && (
          <div className="p-3 rounded bg-red-100 text-red-800 text-sm">
            {error}
          </div>
        )}
        {fieldsLoading && (
          <p className="text-ui-fg-muted text-sm">Loading form…</p>
        )}
        {!fieldsLoading && fields.length === 0 && (
          <p className="text-ui-fg-muted text-sm">No registration fields configured.</p>
        )}
        {!fieldsLoading && fields.map((f) => renderField(f))}
        <div className="flex flex-col sm:flex-row gap-2">
          <Button
            type="submit"
            disabled={create.isPending || fieldsLoading || countriesLoading}
            className="w-full sm:w-auto"
          >
            Create Customer
          </Button>
          <Button
            type="button"
            variant="secondary"
            onClick={() => navigate("/customers")}
            disabled={create.isPending}
            className="w-full sm:w-auto"
          >
            Cancel
          </Button>
        </div>
      </form>
    </Container>
  )
}
