"use client";
import { useEffect, useState } from "react";
import { z } from "zod";
import { Controller, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import InputForm from "@/modules/ui/form/input-form";
import { useAddressStore } from "@/zustand/addressStore";
import { Dropdown as SelectDropdown } from "@/modules/ui/select-dropdown";
import addressService from "@/lib/services/address";
import { useAuth } from "@/lib/context/auth-context";
import AddressValidationNote from "@/modules/common/address/address-validation-note";
import AmbiguousAddressList from "@/modules/common/address/ambiguous-address-list";
import {
  AmbiguousAddressModal,
  CountryModel,
  StateModel,
} from "@/lib/types/models/address";

const addressSchema = z.object({
  name: z.string().nonempty("Name is required"),
  companyName: z.string().optional().or(z.literal("")),
  addressLine1: z.string().nonempty("Address Line 1 is required"),
  addressLine2: z.string().optional().or(z.literal("")),
  country: z.string().nonempty("Country is required"),
  state: z.string().nonempty("State is required"),
  city: z.string().nonempty("City is required"),
  zipcode: z
    .string()
    .nonempty("Zipcode is required")
    .regex(/^\d{5}(-\d{4})?$/, "Invalid Zipcode format"),
  contactNo: z
    .string()
    .nonempty("Contact number is required")
    .regex(/^[0-9]{10}$/, "Contact number must be 10 digits"),
});

type AddressFormData = z.infer<typeof addressSchema>;

export default function AddressForm() {
  const { setShowModal, addressList, setAddress, editAddress, setEditAddress } =
    useAddressStore();
  const { user } = useAuth();
  const [ambiguousAddress, setAmbiguousAddress] = useState<AmbiguousAddressModal[]>([]);
  const [countries, setCountries] = useState<CountryModel[]>([]);
  const [states, setStates] = useState<StateModel[]>([]);
  const [isSubmitting, setIsSubmitting] = useState(false);

  const getEmptyValues = (countryList = countries): AddressFormData => ({
    name: "",
    companyName: "",
    addressLine1: "",
    addressLine2: "",
    country: countryList[0]?.name || "",
    state: "",
    city: "",
    zipcode: "",
    contactNo: "",
  });

  const {
    register,
    handleSubmit,
    control,
    reset,
    watch,
    getValues,
    setValue,
    formState: { errors },
  } = useForm<AddressFormData>({
    resolver: zodResolver(addressSchema),
    defaultValues: getEmptyValues(),
  });

  const selectedCountry = watch("country");

  // Fetch active countries on mount
  useEffect(() => {
    addressService.getCountries().then((res) => {
      const list: CountryModel[] = res?.data || [];
      setCountries(list);
    });
  }, []);

  // Sync form when editAddress changes or countries load
  useEffect(() => {
    if (countries.length === 0) return;

    if (editAddress) {
      const matchedCountry = countries.find(
        (c: CountryModel) =>
          c.name.toLowerCase() === (editAddress.country || "").toLowerCase() ||
          c.iso2.toUpperCase() === (editAddress.country || "").toUpperCase() ||
          c.iso2.toUpperCase() === (editAddress.countryCode || "").toUpperCase()
      );
      reset({
        name: editAddress.name || "",
        companyName: editAddress.companyName || "",
        addressLine1: editAddress.addressLine1 || "",
        addressLine2: editAddress.addressLine2 || "",
        country: matchedCountry?.name || editAddress.country || "",
        state: editAddress.state || editAddress.stateProvinceCode || "",
        city: editAddress.city || "",
        zipcode: editAddress.zipcode || "",
        contactNo: editAddress.contactNo || "",
      });
    } else {
      reset(getEmptyValues(countries));
    }
  }, [editAddress, countries, reset]);

  // Fetch states dynamically based on selected country's _id
  useEffect(() => {
    if (!selectedCountry || countries.length === 0) {
      setStates([]);
      return;
    }

    const countryObj = countries.find(
      (c) =>
        c.name.toLowerCase() === selectedCountry.toLowerCase() ||
        c.iso2.toUpperCase() === selectedCountry.toUpperCase() ||
        c._id === selectedCountry
    );

    if (!countryObj?._id) return;

    let isCurrent = true;
    addressService.getStates(countryObj._id).then((res) => {
      if (!isCurrent) return;
      const stateList = res?.data || [];
      setStates(stateList);

      const currentState = getValues("state");
      const matched = stateList.find(
        (s: StateModel) =>
          s.state.toLowerCase() === (currentState || "").toLowerCase() ||
          s.code.toUpperCase() === (currentState || "").toUpperCase()
      );

      if (matched) {
        setValue("state", matched.state);
      } else if (stateList.length > 0) {
        setValue("state", stateList[0].state);
      } else {
        setValue("state", "");
      }
    });

    return () => {
      isCurrent = false;
    };
  }, [selectedCountry, countries, setValue, getValues]);

  const handleClose = () => {
    setEditAddress(null);
    setAmbiguousAddress([]);
    reset(getEmptyValues());
    setShowModal(false);
  };

  const onSubmit = async (data: AddressFormData) => {
    try {
      setIsSubmitting(true);
      const curCountry = countries.find(
        (c) =>
          c.name.toLowerCase() === data.country.toLowerCase() ||
          c.iso2.toUpperCase() === data.country.toUpperCase()
      );
      const curState = states.find(
        (s) =>
          s.state.toLowerCase() === data.state.toLowerCase() ||
          s.code.toUpperCase() === data.state.toUpperCase()
      );

      const validationPayload = {
        addressLine1: data.addressLine1,
        addressLine2: data.addressLine2 || "",
        city: data.city,
        state: curState?.code || data.state,
        country: curCountry?.iso2 || data.country,
        zipcode: data.zipcode,
      };

      const resp = await addressService.checkValidAddress(validationPayload);
      if (!resp.success || !resp.data?.isValidAddress) {
        if (resp.data?.ambiguos_address) {
          setAmbiguousAddress(resp.data.Candidates || []);
        }
        return;
      }

      const payload = {
        ...data,
        country: curCountry?.name || data.country,
        countryCode: curCountry?.iso2 || data.country,
        state: curState?.state || data.state,
        stateProvinceCode: curState?.code || data.state,
        isShipping: false,
        isBilling: false,
        email: user?.email || "",
      };

      if (!editAddress) {
        const addRes = await addressService.addAddress(payload);
        if (addRes.success) {
          setAddress([...addressList, addRes.data]);
          handleClose();
        }
      } else {
        const updateRes = await addressService.updateAddress(editAddress._id, payload);
        if (updateRes.success) {
          setAddress(addressList.map((a) => (a._id === editAddress._id ? updateRes.data : a)));
          handleClose();
        }
      }
    } catch (err) {
      console.error("Failed to save address:", err);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <div className="mb-4">
          <InputForm
            label="Name"
            placeholder="Enter Name"
            type="text"
            {...register("name")}
            errors={errors.name?.message}
            isRequired
          />
        </div>
        <div className="mb-4">
          <InputForm
            label="Company Name"
            placeholder="Enter Company Name"
            type="text"
            {...register("companyName")}
            errors={errors.companyName?.message}
            isRequired={false}
          />
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
        <div>
          <label className="font-medium mb-2 block">
            Address Line 1 <span className="text-red-500">*</span>
          </label>
          <input
            {...register("addressLine1")}
            placeholder="Address Line 1"
            className={`w-full border rounded-md px-3 py-2 focus:outline-none ${
              errors.addressLine1 ? "border-red-500" : "border-gray-300"
            }`}
          />
          {errors.addressLine1 && (
            <p className="text-red-500 text-sm mt-1">{errors.addressLine1.message}</p>
          )}
        </div>
        <div>
          <label className="font-medium mb-2 block">Address Line 2</label>
          <input
            {...register("addressLine2")}
            placeholder="Apartment, suite, unit (optional)"
            className="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none"
          />
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        <div>
          <label className="font-medium block mb-2">
            Country <span className="text-red-500">*</span>
          </label>
          <Controller
            name="country"
            control={control}
            render={({ field }) => (
              <SelectDropdown
                disabled={countries.length === 0}
                isSearchable
                options={countries}
                label="name"
                value="name"
                selected={field.value}
                onChange={(selected) => field.onChange(selected?.name || "")}
              />
            )}
          />
          {errors.country && (
            <p className="text-red-500 text-sm mt-1">{errors.country.message}</p>
          )}
        </div>

        <div>
          <label className="font-medium block mb-2">
            State <span className="text-red-500">*</span>
          </label>
          <Controller
            name="state"
            control={control}
            render={({ field }) => (
              <SelectDropdown
                disabled={!selectedCountry || states.length === 0}
                isSearchable
                options={states}
                label="state"
                value="state"
                selected={field.value}
                onChange={(selected) => field.onChange(selected?.state || "")}
              />
            )}
          />
          {errors.state && (
            <p className="text-red-500 text-sm mt-1">{errors.state.message}</p>
          )}
        </div>

        <div className="mb-4">
          <InputForm
            label="City"
            placeholder="Enter City"
            type="text"
            {...register("city")}
            errors={errors.city?.message}
            isRequired
          />
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <div className="mb-4">
          <InputForm
            label="Zipcode"
            placeholder="Enter Zipcode"
            type="text"
            {...register("zipcode")}
            errors={errors.zipcode?.message}
            isRequired
          />
        </div>
        <div className="mb-4">
          <InputForm
            label="Contact Number"
            placeholder="Enter Contact Number"
            type="text"
            {...register("contactNo")}
            errors={errors.contactNo?.message}
            isRequired
          />
        </div>
      </div>

      <AmbiguousAddressList ambiguousAddresses={ambiguousAddress} />
      <AddressValidationNote />

      <div className="flex justify-center gap-3 pt-3">
        <button
          type="submit"
          disabled={isSubmitting}
          className="bg-primary text-white px-5 py-2 rounded-md font-medium hover:bg-primary disabled:opacity-50"
        >
          {isSubmitting ? "Saving..." : "Save"}
        </button>
        {addressList.length > 0 && (
          <button
            type="button"
            onClick={handleClose}
            className="border px-5 py-2 rounded-md font-medium text-black hover:bg-gray-100"
          >
            Cancel
          </button>
        )}
      </div>
    </form>
  );
}
