"use client";

import { useEffect, useMemo, useState } from "react";
import { useForm, SubmitHandler, Controller } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";
import DynamicInput from "@/components/input";
import {
  Button,
  Input,
  Select,
  SelectItem,
  type Selection,
} from "@heroui/react";
import { useLocale, useTranslations } from "next-intl";
import {
  defaultCountries,
  FlagImage,
  parseCountry,
} from "react-international-phone";
import { arabicCountries } from "@/config/arabCountries";
import { useAppToast } from "@/app/[lang]/providers";
import { API_BASE_URL } from "@/lib/axios";

type ContactFormValues = {
  fullName: string;
  email: string;
  phone: string;
  topic: string;
  contactPref: string;
  message: string;
};

type CountryCodeOption = {
  iso2: string;
  dialCode: string;
  name: string;
};

export default function ContactForm() {
  const t = useTranslations("CONTACT_PAGE");
  const lang = useLocale();
  const isArabic = lang === "ar";
  const toast = useAppToast();

  const [submitting, setSubmitting] = useState(false);
  const [selectedCountryIso, setSelectedCountryIso] = useState("sa");
  const [localPhone, setLocalPhone] = useState("");
  const [topicOptions, setTopicOptions] = useState<
    { value: string; label: string }[]
  >([{ value: "", label: t("topics.choose") }]);

  const BASE_URL = API_BASE_URL;
  const requiredText = isArabic ? "مطلوب" : "is required";
  const invalidText = isArabic ? "غير صالح" : "is invalid";

  const contactFormSchema = Yup.object().shape({
    fullName: Yup.string().required(`${t("form_fullname")} ${requiredText}`),
    contactPref: Yup.string().required(
      `${t("form_best_contact")} ${requiredText}`,
    ),
    email: Yup.string()
      .ensure()
      .when("contactPref", {
        is: (v: string) => v === "email",
        then: (schema) =>
          schema
            .required(`${t("form_email")} ${requiredText}`)
            .email(`${t("form_email")} ${invalidText}`),
        otherwise: (schema) => schema.ensure(),
      }),
    phone: Yup.string()
      .ensure()
      .when("contactPref", {
        is: (v: string) => ["sms", "phone", "whatsapp"].includes(v),
        then: (schema) => schema.required(`${t("form_phone")} ${requiredText}`),
        otherwise: (schema) => schema.ensure(),
      }),
    topic: Yup.string().required(`${t("form_topic")} ${requiredText}`),
    message: Yup.string().required(`${t("form_message")} ${requiredText}`),
  });

  const { control, handleSubmit, reset, setValue, watch } =
    useForm<ContactFormValues>({
      resolver: yupResolver(contactFormSchema),
      defaultValues: {
        fullName: "",
        email: "",
        phone: "",
        topic: "",
        contactPref: "whatsapp",
        message: "",
      },
    });

  const watchedPhone = watch("phone") || "";

  const countryCodeOptions: CountryCodeOption[] = useMemo(
    () =>
      (isArabic ? arabicCountries : defaultCountries).map((country) => {
        const parsed = parseCountry(country);
        return {
          iso2: parsed.iso2,
          dialCode: parsed.dialCode,
          name: parsed.name,
        };
      }),
    [isArabic],
  );

  const contactMethods = useMemo(
    () => [
      { value: "whatsapp", label: t("contact_methods.whatsapp") },
      { value: "phone", label: t("contact_methods.phone") },
      { value: "sms", label: t("contact_methods.sms") },
      { value: "email", label: t("contact_methods.email") },
    ],
    [t],
  );

  const getDialCodeByIso = (iso2: string) =>
    countryCodeOptions.find((option) => option.iso2 === iso2)?.dialCode ||
    "966";

  const setPhoneWithDialCode = (iso2: string, local: string) => {
    const cleaned = local.replace(/\D/g, "");
    if (!cleaned) {
      setValue("phone", "", {
        shouldDirty: true,
        shouldValidate: true,
      });
      return;
    }

    const dial = getDialCodeByIso(iso2);
    setValue("phone", `+${dial}${cleaned}`, {
      shouldDirty: true,
      shouldValidate: true,
    });
  };

  const handleCountryCodeChange = (keys: Selection) => {
    const selected = (Array.from(keys).at(0) as string | undefined) || "sa";
    setSelectedCountryIso(selected);
    setPhoneWithDialCode(selected, localPhone);
  };

  const handleLocalPhoneChange = (value: string) => {
    const cleaned = value.replace(/\D/g, "");
    setLocalPhone(cleaned);
    setPhoneWithDialCode(selectedCountryIso, cleaned);
  };

  useEffect(() => {
    const digits = String(watchedPhone).replace(/\D/g, "");
    if (!digits) {
      if (selectedCountryIso !== "sa") setSelectedCountryIso("sa");
      if (localPhone !== "") setLocalPhone("");
      return;
    }

    const sortedOptions = [...countryCodeOptions].sort(
      (a, b) => b.dialCode.length - a.dialCode.length,
    );
    const matched = sortedOptions.find((option) =>
      digits.startsWith(option.dialCode),
    );

    if (matched) {
      const nextLocal = digits.slice(matched.dialCode.length);
      if (selectedCountryIso !== matched.iso2)
        setSelectedCountryIso(matched.iso2);
      if (localPhone !== nextLocal) setLocalPhone(nextLocal);
      return;
    }

    if (localPhone !== digits) setLocalPhone(digits);
  }, [watchedPhone, countryCodeOptions, selectedCountryIso, localPhone]);

  useEffect(() => {
    async function loadSubjects() {
      try {
        const res = await fetch(`${BASE_URL}/user/contact-us-subjects`, {
          headers: {
            Accept: "application/json",
            lang,
          },
        });

        if (!res.ok) return;

        const json = await res.json();
        const root = json.data ?? json;
        const items = (root.data ?? root) as { id: string; name: string }[];

        const options = [
          { value: "", label: t("topics.choose") },
          ...items.map((item) => ({ value: item.id, label: item.name })),
        ];

        setTopicOptions(options);
      } catch (error) {
        console.error("Failed to load contact subjects", error);
      }
    }

    if (BASE_URL) {
      loadSubjects();
    }
  }, [BASE_URL, lang, t]);

  const onSubmit: SubmitHandler<ContactFormValues> = async (data) => {
    if (!BASE_URL) return;

    try {
      setSubmitting(true);

      const formData = new FormData();
      formData.append("name", data.fullName);
      if (data.email) formData.append("email", data.email);
      if (data.phone) formData.append("phone", data.phone);
      if (data.topic) formData.append("contact_subject_id", data.topic);

      formData.append("message_body", data.message);
      formData.append("contact_method", data.contactPref);

      const response = await fetch(`${BASE_URL}/user/contact-us`, {
        method: "POST",
        headers: {
          Accept: "application/json",
          lang,
        },
        body: formData,
      });

      if (!response.ok) {
        console.error("Contact form submission failed", await response.text());
        return;
      }
      toast.success(t("form_success"));
      reset();
      setSelectedCountryIso("sa");
      setLocalPhone("");
      setValue("phone", "");
      window.scrollTo({ top: 0, behavior: "smooth" });
    } catch (error) {
      console.error("Error submitting contact form", error);
    } finally {
      setSubmitting(false);
    }
  };

  const phoneInputDir: "rtl" | "ltr" = localPhone
    ? "ltr"
    : isArabic
      ? "rtl"
      : "ltr";
  const phoneInputAlignClass = localPhone
    ? "text-left"
    : isArabic
      ? "text-right"
      : "text-left";

  return (
    <section
      className="rounded-xl border border-[#0f5132]/10 bg-white shadow-[0_10px_30px_rgba(15,81,50,0.08)] p-5 sm:p-6"
      dir={isArabic ? "rtl" : "ltr"}
    >
      <h2 className="text-xl sm:text-2xl font-extrabold text-[#0f5132]">
        {t("form_title")}
      </h2>
      <p className="text-slate-600 mt-1 mb-5">{t("form_description")}</p>

      <form
        onSubmit={handleSubmit(onSubmit)}
        className="grid grid-cols-1 md:grid-cols-2 gap-4"
      >
        <Controller
          name="fullName"
          control={control}
          render={({ field, fieldState }) => (
            <DynamicInput
              field={field}
              fieldState={fieldState}
              label={t("form_fullname")}
              placeholder={t("form_fullname_placeholder")}
              type="text"
              className="w-full"
              isDisabled={submitting}
            />
          )}
        />

        <Controller
          name="email"
          control={control}
          render={({ field, fieldState }) => (
            <DynamicInput
              field={field}
              fieldState={fieldState}
              label={t("form_email")}
              placeholder={t("form_email_placeholder")}
              className="w-full"
              isDisabled={submitting}
            />
          )}
        />

        <Controller
          name="phone"
          control={control}
          render={({ fieldState }) => (
            <div className="flex flex-col gap-1">
              <label className="text-xs font-medium text-primaryText py-1">
                {t("form_phone")}
              </label>

              <div className="flex items-center gap-2">
                <Input
                  type="tel"
                  inputMode="numeric"
                  aria-label={t("form_phone")}
                  placeholder={t("form_phone")}
                  value={localPhone}
                  onValueChange={handleLocalPhoneChange}
                  variant="bordered"
                  size="sm"
                  dir={phoneInputDir}
                  isDisabled={submitting}
                  className="flex-1"
                  classNames={{
                    inputWrapper:
                      "h-11 rounded-xl border border-slate-200 bg-white shadow-none data-[focus=true]:border-[#0f5132]",
                    input: `text-sm text-slate-800 [unicode-bidi:plaintext] ${phoneInputAlignClass}`,
                  }}
                />

                <div className="min-w-[150px] shrink-0  ">
                  <Select
                    aria-label={t("form_phone")}
                    selectedKeys={[selectedCountryIso]}
                    onSelectionChange={handleCountryCodeChange}
                    disallowEmptySelection
                    variant="bordered"
                    size="sm"
                    isDisabled={submitting}
                    className="w-full"
                    renderValue={(items) => {
                      const selectedKey = String(items[0]?.key || "");
                      const selected = countryCodeOptions.find(
                        (option) => option.iso2 === selectedKey,
                      );

                      if (!selected) return null;

                      return (
                        <div className="flex items-center gap-2">
                          <FlagImage
                            iso2={selected.iso2}
                            size={16}
                            className="shrink-0 rounded-sm"
                          />
                          <span className="text-sm font-semibold text-slate-700">
                            +{selected.dialCode}
                          </span>
                        </div>
                      );
                    }}
                    classNames={{
                      trigger:
                        "h-11 rounded-xl border border-slate-200 bg-white shadow-none data-[open=true]:border-[#0f5132] data-[focus=true]:border-[#0f5132]",
                      value: "text-sm font-medium text-slate-700",
                      popoverContent: "rounded-xl border border-slate-200",
                    }}
                  >
                    {countryCodeOptions.map((item) => (
                      <SelectItem
                        key={item.iso2}
                        textValue={`${item.name} +${item.dialCode}`}
                      >
                        <div className="flex items-center gap-2 min-w-0">
                          <FlagImage
                            iso2={item.iso2}
                            size={16}
                            className="shrink-0 rounded-sm"
                          />
                          <span className="text-sm font-medium truncate">
                            {item.name}
                          </span>
                          <span className="ms-auto text-xs text-slate-500">
                            +{item.dialCode}
                          </span>
                        </div>
                      </SelectItem>
                    ))}
                  </Select>
                </div>
              </div>

              {fieldState.error?.message ? (
                <small className="p-1 text-red-500 text-sm">
                  {fieldState.error.message}
                </small>
              ) : null}
            </div>
          )}
        />

        <Controller
          name="topic"
          control={control}
          render={({ field, fieldState }) => (
            <DynamicInput
              field={field}
              fieldState={fieldState}
              label={t("form_topic")}
              type="select"
              options={topicOptions}
              className="bg-white justify-end flex"
              isDisabled={submitting}
            />
          )}
        />

        <Controller
          name="contactPref"
          control={control}
          render={({ field, fieldState }) => (
            <div className="md:col-span-2">
              <label className="block text-sm font-medium text-gray-700 mb-2">
                {t("form_best_contact")}
              </label>

              <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
                {contactMethods.map((item) => {
                  const checked = field.value === item.value;
                  return (
                    <label
                      key={item.value}
                      className={`relative flex items-center gap-3 rounded-xl border px-3 py-2 cursor-pointer transition-all ${
                        checked
                          ? "border-[#0f5132] bg-[#0f5132]/5 text-[#0f5132]"
                          : "border-gray-200 hover:border-[#0f5132]/40"
                      }`}
                    >
                      <input
                        type="radio"
                        value={item.value}
                        checked={checked}
                        onChange={() => field.onChange(item.value)}
                        className="sr-only"
                        disabled={submitting}
                      />
                      <span
                        className={`w-4 h-4 rounded-full border-2 flex items-center justify-center ${
                          checked ? "border-[#0f5132]" : "border-gray-300"
                        }`}
                      >
                        <span
                          className={`w-2 h-2 rounded-full bg-[#0f5132] transition-opacity ${
                            checked ? "opacity-100" : "opacity-0"
                          }`}
                        />
                      </span>
                      <span className="text-sm font-medium">{item.label}</span>
                    </label>
                  );
                })}
              </div>

              {fieldState.error?.message ? (
                <small className="p-1 text-red-500 text-sm block">
                  {fieldState.error.message}
                </small>
              ) : null}
            </div>
          )}
        />

        <Controller
          name="message"
          control={control}
          render={({ field, fieldState }) => (
            <DynamicInput
              field={field}
              fieldState={fieldState}
              label={t("form_message")}
              placeholder={t("form_message_placeholder")}
              type="textarea"
              className="md:col-span-2"
              isDisabled={submitting}
            />
          )}
        />

        <div
          className={`md:col-span-2 flex flex-wrap gap-3 ${
            isArabic ? "justify-start" : "justify-end"
          }`}
        >
          <Button
            type="button"
            variant="bordered"
            className="px-5 py-3 rounded-xl border border-gray-300 hover:bg-gray-50"
            onClick={() => {
              reset();
              setSelectedCountryIso("sa");
              setLocalPhone("");
              setValue("phone", "");
            }}
            isDisabled={submitting}
          >
            {t("form_clear")}
          </Button>

          <Button
            type="submit"
            className="px-6 py-3 rounded-xl text-white bg-primary hover:bg-primary/85"
            isDisabled={submitting}
          >
            {t("form_send")}
          </Button>
        </div>
      </form>
    </section>
  );
}
