"use client";

import { useCallback, useEffect, useState } from "react";
import { accountService } from "@/features/account/api/account.api";
import { useAuthStore } from "@/features/auth/stores/auth.store";
import type { AuthenticatedUser } from "@customer-portal/domain/customer";
import { useProfileEdit } from "./useProfileEdit";
import { useAddressEdit } from "./useAddressEdit";

function applyAddressValues(
  setValue: ReturnType<typeof useAddressEdit>["setValue"],
  addr: Record<string, string | null | undefined>
) {
  const fields = [
    "address1",
    "address2",
    "city",
    "state",
    "postcode",
    "country",
    "countryCode",
    "phoneNumber",
    "phoneCountryCode",
  ] as const;
  for (const field of fields) {
    setValue(field, (addr[field] as string) ?? "");
  }
}

function applyProfileValues(
  setValue: ReturnType<typeof useProfileEdit>["setValue"],
  prof: AuthenticatedUser
) {
  setValue("email", prof.email || "");
  setValue("phonenumber", prof.phonenumber || "");
  useAuthStore.getState().hydrateUserProfile(prof);
}

interface UseProfileDataLoadingOptions {
  /** Initial email from user store */
  email: string;
  /** Initial phone number from user store */
  phonenumber: string;
}

/**
 * Hook that consolidates profile and address data loading.
 * Composes useProfileEdit and useAddressEdit internally.
 */
export function useProfileDataLoading({ email, phonenumber }: UseProfileDataLoadingOptions) {
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [reloadKey, setReloadKey] = useState(0);

  const profile = useProfileEdit({
    email,
    phonenumber,
  });

  const address = useAddressEdit({
    address1: "",
    address2: "",
    city: "",
    state: "",
    postcode: "",
    country: "",
    countryCode: "",
    phoneNumber: "",
    phoneCountryCode: "",
  });

  // Extract stable setValue functions to avoid infinite re-render loop.
  // The hook objects (address, profile) are recreated every render, but
  // the setValue callbacks inside them are stable (memoized with useCallback).
  const setAddressValue = address.setValue;
  const setProfileValue = profile.setValue;

  const loadProfile = useCallback(() => {
    void (async () => {
      try {
        setError(null);
        setIsLoading(true);
        const [addr, prof] = await Promise.all([
          accountService.getAddress().catch(() => null),
          accountService.getProfile().catch(() => null),
        ]);
        if (addr) {
          applyAddressValues(setAddressValue, addr);
        }
        if (prof) {
          applyProfileValues(setProfileValue, prof);
        }
      } catch (e) {
        setError(e instanceof Error ? e.message : "Failed to load profile data");
      } finally {
        setIsLoading(false);
      }
    })();
  }, [setAddressValue, setProfileValue]);

  useEffect(() => {
    loadProfile();
  }, [loadProfile, reloadKey]);

  const reload = useCallback(() => {
    setReloadKey(k => k + 1);
  }, []);

  return {
    isLoading,
    error,
    reload,
    profile,
    address,
  };
}
