"use client";

import { useMemo, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { ChevronDown } from "lucide-react";

import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
} from "@/components/ui/select";
import { localeHeadingClass, localeBodyClass } from "@/lib/locale-fonts";
import { getServiceOptionsForCategory } from "@/services/api/categories";
import { submitQuoteRequest } from "@/services/api/quote";

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

const PHONE_REGEX = /^(?=(?:\D*\d){1,15}\D*$)\+?\d(?: ?\d)*$/;

function normalizeOptions(options) {
  return (options ?? []).map((option) =>
    typeof option === "string" ? { label: option, value: option } : option,
  );
}

function FormSelect({
  label,
  required,
  value,
  onChange,
  options,
  placeholder,
  variant = "bordered", // "bordered" | "pill"
  disabled = false,
  error,
  className = "",
}) {
  const [open, setOpen] = useState(false);
  const normalized = useMemo(() => normalizeOptions(options), [options]);
  const selectedLabel = normalized.find((opt) => opt.value === value)?.label;

  return (
    <div className="flex flex-col gap-1.5">
      {label ? (
        <span className="text-sm text-neutral-500">
          {label}
          {required ? " *" : ""}
        </span>
      ) : null}
      <Select
        value={value}
        onValueChange={onChange}
        open={open}
        onOpenChange={setOpen}
        disabled={disabled}
      >
        <SelectTrigger
          className={cn(
            "h-12 w-full bg-white px-4 text-sm text-[#3E4155] shadow-none focus:ring-0",
            variant === "pill"
              ? "rounded-full"
              : "rounded-2xl border border-[#C5C9D6]",
            error && "border-destructive",
            className,
          )}
        >
          <span className={cn(!selectedLabel && "text-neutral-400")}>
            {selectedLabel || placeholder}
          </span>
          <ChevronDown
            className={cn(
              "h-5 w-5 shrink-0 text-[#3E4155] transition-transform duration-200",
              open && "rotate-180",
            )}
          />
        </SelectTrigger>
        <SelectContent className="rounded-2xl bg-white p-1 shadow-lg">
          {normalized.map((option) => (
            <SelectItem
              key={option.value}
              value={option.value}
              className="hover:bg-primary focus:bg-primary cursor-pointer rounded-xl py-2.5 text-sm text-[#3E4155] focus:text-white"
            >
              {option.label}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
      {error && (
        <p className="text-destructive text-xs" role="alert">
          {error}
        </p>
      )}
    </div>
  );
}

export default function QuoteFormClient({
  locale,
  t,
  businessTypeOptions = [],
  categories = [],
  onSubmitQuote,
}) {
  "use no memo";

  const [submitState, setSubmitState] = useState("idle"); // "idle" | "submitting" | "success" | "error"

  const fields = useMemo(
    () =>
      t.form.reduce((acc, field) => {
        acc[field.name] = field;
        return acc;
      }, {}),
    [t.form],
  );

  const schema = useMemo(
    () =>
      z
        .object({
          businessName: fields.businessName?.required
            ? z.string().min(1, t.feedback.required)
            : z.string().optional().default(""),
          businessType: z.string().optional().default(""),
          services: z.string().optional().default(""),
          numberOfLocations: fields.numberOfLocations?.required
            ? z.string().min(1, t.feedback.required)
            : z.string().optional().default(""),
          additionalInfo: z.string().optional().default(""),
          contactMethod: z.enum(["email", "phone"]),
          phone: z.string().optional().default(""),
          email: z.string().optional().default(""),
          monthlyBookingsCount: fields.businessName?.required
            ? z.string().min(1, t.feedback.required)
            : z.string().optional().default(""),
        })
        .superRefine((data, ctx) => {
          const email = data.email.trim();
          const phone = data.phone.trim();

          if (data.contactMethod === "email") {
            if (!email) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: t.feedback.required,
                path: ["email"],
              });
            } else if (!EMAIL_REGEX.test(email)) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: t.feedback.invalidEmail,
                path: ["email"],
              });
            }
          } else {
            if (!phone) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: t.feedback.required,
                path: ["phone"],
              });
            } else if (!PHONE_REGEX.test(phone)) {
              ctx.addIssue({
                code: z.ZodIssueCode.custom,
                message: t.feedback.invalidPhone,
                path: ["phone"],
              });
            }
          }
        }),
    [fields, t.feedback],
  );

  const {
    register,
    control,
    handleSubmit,
    watch,
    setValue,
    reset,
    formState: { errors, isSubmitting },
  } = useForm({
    resolver: zodResolver(schema),
    defaultValues: {
      businessName: "",
      businessType: "",
      services: "",
      numberOfLocations: "",
      additionalInfo: "",
      contactMethod: "email",
      phone: "",
      email: "",
      monthlyBookingsCount: "",
    },
  });

  const contactMethod = watch("contactMethod");
  const businessType = watch("businessType");

  const serviceOptions = useMemo(
    () => getServiceOptionsForCategory(categories, businessType),
    [categories, businessType],
  );

  const handleBusinessTypeChange = (value, onChange) => {
    onChange(value);
    setValue("services", "", { shouldValidate: false });
  };

  const onSubmit = async (values) => {
    console.log("values", values);
    setSubmitState("submitting");
    try {
      if (onSubmitQuote) {
        await onSubmitQuote(values);
      } else {
        await submitQuoteRequest(values);
      }
      setSubmitState("success");
      reset();
    } catch (error) {
      console.error("Quote submission failed:", error);
      setSubmitState("error");
    }
  };

  return (
    <div className="flex w-full flex-col items-center justify-center px-5 py-10 md:py-20 lg:px-20 xl:px-45">
      <div className="mb-8 text-center">
        <h2
          className={cn(
            "mt-6 text-center text-3xl tracking-[0.04em] text-neutral-700 uppercase",
            localeHeadingClass(locale),
          )}
        >
          {t.title}
        </h2>
        <p
          className={cn(
            "mt-3 text-lg font-medium text-black",
            localeBodyClass(locale),
          )}
        >
          {t.description}
        </p>
      </div>

      <form
        onSubmit={handleSubmit(onSubmit)}
        noValidate
        className={cn("w-full max-w-7xl p-6", localeBodyClass(locale))}
      >
        <div className="grid grid-cols-1 gap-x-10 gap-y-6 md:grid-cols-2">
          {/* Left column */}
          <div className="flex flex-col gap-6">
            <Field
              label={fields.businessName?.label}
              required={fields.businessName?.required}
              error={errors.businessName?.message}
            >
              <Input
                {...register("businessName")}
                placeholder={fields.businessName?.placeholder}
                aria-invalid={!!errors.businessName}
              />
            </Field>

            <div className="grid grid-cols-2 gap-4">
              <Controller
                control={control}
                name="businessType"
                render={({ field }) => (
                  <FormSelect
                    label={fields.businessType?.label}
                    placeholder={fields.businessType?.label}
                    value={field.value}
                    onChange={(value) =>
                      handleBusinessTypeChange(value, field.onChange)
                    }
                    options={businessTypeOptions}
                  />
                )}
              />

              <Controller
                control={control}
                name="services"
                render={({ field }) => (
                  <FormSelect
                    label={fields.services?.label}
                    placeholder={fields.services?.label}
                    value={field.value}
                    onChange={field.onChange}
                    options={serviceOptions}
                    disabled={!businessType}
                  />
                )}
              />
            </div>

            <Field
              label={fields.numberOfLocations?.label}
              required={fields.numberOfLocations?.required}
              error={errors.numberOfLocations?.message}
            >
              <Input
                {...register("numberOfLocations")}
                inputMode="numeric"
                placeholder={fields.numberOfLocations?.placeholder}
                aria-invalid={!!errors.numberOfLocations}
              />
            </Field>

            <Field label={fields.additionalInfo?.label}>
              <Textarea
                {...register("additionalInfo")}
                placeholder={fields.additionalInfo?.placeholder}
                rows={5}
              />
            </Field>
          </div>

          {/* Right column */}
          <div className="flex flex-col gap-6">
            <Field className="h-15" label={fields.contactMethod?.label}>
              <Controller
                control={control}
                name="contactMethod"
                render={({ field }) => (
                  <RadioGroup
                    value={field.value}
                    onValueChange={field.onChange}
                    className="flex items-center gap-6"
                  >
                    {fields.contactMethod?.options?.map((option) => (
                      <label
                        key={option.value}
                        className="flex cursor-pointer items-center gap-2 text-sm"
                      >
                        <RadioGroupItem value={option.value} />
                        {option.label}
                      </label>
                    ))}
                  </RadioGroup>
                )}
              />
            </Field>

            <div className="grid grid-cols-2 gap-4">
              <Field
                label={fields.phone?.label}
                required={contactMethod === "phone"}
                error={errors.phone?.message}
              >
                <Input
                  {...register("phone")}
                  placeholder="+374"
                  disabled={contactMethod !== "phone"}
                  aria-invalid={!!errors.phone}
                />
              </Field>

              <Field
                label={fields.email?.label}
                required={contactMethod === "email"}
                error={errors.email?.message}
              >
                <Input
                  {...register("email")}
                  type="email"
                  disabled={contactMethod !== "email"}
                  aria-invalid={!!errors.email}
                />
              </Field>
            </div>

            <Field
              label={fields.monthlyBookingsCount?.label}
              required={fields.businessName?.required}
            >
              <Input
                {...register("monthlyBookingsCount")}
                inputMode="numeric"
                placeholder={fields.monthlyBookingsCount?.placeholder}
              />
            </Field>
          </div>
        </div>

        <div className="mt-8 flex flex-col items-start gap-3">
          <Button type="submit" disabled={isSubmitting} className="min-w-40">
            {isSubmitting ? "..." : t.submitText}
          </Button>

          {submitState === "success" && (
            <p className="text-sm text-green-600" role="status">
              {t.feedback.success}
            </p>
          )}
          {submitState === "error" && (
            <p className="text-destructive text-sm" role="alert">
              {t.feedback.required}
            </p>
          )}
        </div>
      </form>
    </div>
  );
}

function Field({ label, required, error, children, className }) {
  return (
    <div className={cn("flex flex-col gap-1.5", className)}>
      {label && (
        <Label>
          {label}
          {required && <span className="text-destructive"> *</span>}
        </Label>
      )}
      {children}
      {error && (
        <p className="text-destructive text-xs" role="alert">
          {error}
        </p>
      )}
    </div>
  );
}
