"use client";

import { useAction } from "convex/react";
import { useCallback, useState } from "react";
import { api } from "../../../../../convex/_generated/api";
import type { AddressFormData, CheckoutAddressValidationResult } from "./types";

/**
 * Manages the Shippo address validation lifecycle.
 *
 * - `validate(input)` — calls `api.checkoutActions.validateAddress`, stores result.
 * - `reset()` — clears result and error (use when switching addresses or editing the form).
 * - `error` — user-friendly string when the action fails (network, Shippo outage, etc.).
 */
export function useAddressValidation(): {
  validate: (input: AddressFormData) => Promise<CheckoutAddressValidationResult | null>;
  result: CheckoutAddressValidationResult | null;
  isValidating: boolean;
  error: string | null;
  reset: () => void;
} {
  const validateAction = useAction(api.checkoutActions.validateAddress);

  const [result, setResult] = useState<CheckoutAddressValidationResult | null>(null);
  const [isValidating, setIsValidating] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const validate = useCallback(
    async (input: AddressFormData): Promise<CheckoutAddressValidationResult | null> => {
      setIsValidating(true);
      setError(null);
      setResult(null);

      try {
        const validationResult = await validateAction({
          addressLine1: input.addressLine1,
          additionalInformation: input.additionalInformation,
          city: input.city,
          postalCode: input.postalCode,
          country: input.country,
          name: `${input.firstName} ${input.lastName}`.trim(),
        });

        const mapped = validationResult as CheckoutAddressValidationResult;
        setResult(mapped);
        return mapped;
      } catch (err) {
        const message =
          err instanceof Error ? err.message : "Address validation failed. Please try again.";
        setError(message);
        return null;
      } finally {
        setIsValidating(false);
      }
    },
    [validateAction],
  );

  const reset = useCallback(() => {
    setResult(null);
    setError(null);
  }, []);

  return { validate, result, isValidating, error, reset };
}
