"use client";

import { useCallback, useEffect, useState } from "react";
import { Controller, useForm, useWatch } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

import { CityFormData, citySchema } from "@/src/validation/admin/validation";

import Form from "@/src/components/admin/form/Form";
import FormGroup from "@/src/components/admin/form/FormGroup";
import Label from "@/src/components/admin/form/Label";
import Input from "@/src/components/admin/form/input/InputField";
import Select from "@/src/components/admin/form/Select";

import { useToastMessage } from "@/src/hooks/admin/useToastMessage";
import { useLabeledOptions } from "@/src/hooks/admin/useFetchOptions";
import { useFetchById } from "@/src/hooks/admin/useFetchById";
import { useUniqueCheck } from "@/src/hooks/admin/uniqueValidationHooks/useMutliUniqueCheck";
import { useStateContext } from "@/src/context/admin/StateContext";

import {
  getAllCountries,
  getAllStates,
  getAllStatesByCountry,
  getCityById,
  submitCity,
  uniqueCity,
} from "@/src/services/admin/services";


// ────────────────────────────────────────────────────────────────────────────────

export default function AddCityForm() {
  const { message, setMessage } = useToastMessage();
  const { setIsDrawerOpen, refresh, setRefresh, itemID, setItemID } =
    useStateContext();
  const [stateOptions, setStateOptions] = useState<any[]>([]);

  // ── State Options ────────────────────────────────────────────────────────────

  const { options: countryOptions } = useLabeledOptions({
    fetchService: async () => {
      const res = await getAllCountries();
      return res.data.data;
    },
    mapLabel: (item) => item.name,
    mapValue: (item) => Number(item.id),
    onError: (err) => console.error("Failed to load states:", err),
  });

  // ── Form Setup ───────────────────────────────────────────────────────────────

  const {
    control,
    register,
    handleSubmit,
    reset,
    setError,
    clearErrors,
    formState: { errors, isSubmitting },
  } = useForm<CityFormData>({
    resolver: zodResolver(citySchema),
    defaultValues: {
      name: "",
      state_id: 0,
      country_id: 0,
    },
  });

  const [cityName, stateId, countryId] = useWatch({
    control,
    name: ["name", "state_id", "country_id"],
  });

  // ── Edit Mode - Load existing city data ──────────────────────────────────────

  const setFormData = useCallback(
    (data: any) => {
      reset({
        state_id: data?.state_id ?? 0,
        name: data?.name ?? "",
        country_id: data?.country_id ?? 0,
      });
    },
    [reset]
  );

  const fetchCityById = useCallback(async (id: number) => {
    const res = await getCityById(id);
    return res.data.data;
  }, []);

  useFetchById({
    fetchService: fetchCityById,
    setFormData,
    onError: (err) => console.error("Failed to fetch city:", err),
  });

  // ── Unique City Name Check ───────────────────────────────────────────────────

  const { nonUniqueFields, checkUnique, loading: uniqueLoading } = useUniqueCheck(
    uniqueCity,
    700
  );

  useEffect(() => {
    const payload = {
      name: cityName?.trim() || "",
      state_id: stateId || 0,
      country_id: countryId || 0,
    };

    checkUnique({
      payload,
      currentId: itemID,
    });
  }, [cityName, stateId, countryId, itemID, checkUnique]);

  useEffect(() => {
    clearErrors(["name"]);

    if (nonUniqueFields?.length > 0) {
      nonUniqueFields.forEach((field) => {
        setError(field as keyof CityFormData, {
          type: "server",
          message: "This city already exists in the selected state",
        });
      });
    }
  }, [nonUniqueFields, setError, clearErrors]);

  // ── Form Submission ──────────────────────────────────────────────────────────

  const onSubmit = async (data: CityFormData) => {
    if (nonUniqueFields?.length > 0) {
      setMessage({ type: "error", text: "City name must be unique within the state" });
      return;
    }

    setMessage(null);

    try {
      const response = await submitCity(itemID, data);
      const result = response.data;

      if (!result.success) {
        throw new Error(result.message || "Failed to save record");
      }

      setMessage({ type: "success", text: itemID ? "Record updated successfully!" : "Record added successfully!", });

      reset({ name: "", state_id: 0, country_id: 0 });
      setTimeout(() => {
        setRefresh(!refresh);
        setIsDrawerOpen(false);
        setItemID(undefined);
      }, 200);
    } catch (err: any) {
      setMessage({
        type: "error",
        text: err.message || "An error occurred while saving",
      });
    }
  };

  useEffect(() => {
    const loadStateOptions = async () => {
      if (countryId) {
        try {
          const res = await getAllStatesByCountry(countryId);
          setStateOptions(
            res.data.data.map((state: any) => ({
              label: state.name,
              value: state.id,
            }))
          );
        } catch (err) {
          console.error("Failed to load states:", err);
        }
      } else {
        setStateOptions([]);
      }
    };

    loadStateOptions();
  }, [countryId]);

 

  // ── Render ───────────────────────────────────────────────────────────────────

  const hasErrors = Object.keys(errors).length > 0 || nonUniqueFields?.length > 0;

  return (
    <Form
      onSubmit={handleSubmit(onSubmit)}
      className="space-y-6"
      formLayout="vertical"
      isSubmitting={isSubmitting}
      message={message ?? undefined}
    // isDisable={hasErrors}
    >

      <FormGroup>
        <Label required>Country</Label>

        <Controller
          name="country_id"
          control={control}
          render={({ field }) => (
            <Select
              options={countryOptions}
              placeholder="Select Country | e.g., United States"
              value={field.value}
              onChange={field.onChange}
              className="dark:bg-dark-900"
              error={errors.country_id}
              errorMessage={errors.country_id?.message}
            />
          )}
        />
      </FormGroup>
      {/* State Selection */}
      <FormGroup>
        <Label required>State Name</Label>

        <Controller
          name="state_id"
          control={control}
          render={({ field }) => (
            <Select
              options={stateOptions}
              placeholder="Select State | e.g., Maharashtra"
              value={field.value}
              onChange={field.onChange}
              className="dark:bg-dark-900"
              error={errors.state_id}
              errorMessage={errors.state_id?.message}
            />
          )}
        />
      </FormGroup>

      {/* City Name */}
      <FormGroup>
        <Label required>City Name</Label>

        <Input
          placeholder="Enter City | e.g. Delhi, Mumbai, Bengaluru..."
          {...register("name")}
          error={!!errors.name || nonUniqueFields?.includes("name")}
          errorMessage={
            errors.name?.message ||
            (nonUniqueFields?.includes("name") ? "This city already exists in selected state" : undefined)
          }
          hint="Enter the full name of the city"
        />
      </FormGroup>

    </Form>
  );
}