import { useState, useCallback } from "react";
import { type JapanAddressFormData } from "@/features/address/components/JapanAddressForm";
import { usePasswordValidation } from "@/features/auth/hooks/usePasswordValidation";
import { phoneSchema } from "@customer-portal/domain/common";
import type { AccountFormErrors } from "./types";

interface FormState {
  firstName: string;
  lastName: string;
  phone: string;
  dateOfBirth: string;
  gender: "male" | "female" | "other" | "";
  password: string;
  confirmPassword: string;
  acceptTerms: boolean;
  marketingConsent: boolean;
}

interface InitialValues {
  firstName?: string | undefined;
  lastName?: string | undefined;
  phone?: string | undefined;
  dateOfBirth?: string | undefined;
  gender?: "male" | "female" | "other" | "" | undefined;
  acceptTerms?: boolean | undefined;
  marketingConsent?: boolean | undefined;
}

interface UseCompleteAccountFormOptions {
  initialValues: InitialValues;
  isNewCustomer: boolean;
  /** Whether the user needs to provide address data (new customer or SF-unmapped with incomplete address) */
  needsAddress: boolean;
  updateFormData: (data: Record<string, unknown>) => void;
}

export function useCompleteAccountForm({
  initialValues,
  isNewCustomer,
  needsAddress,
  updateFormData,
}: UseCompleteAccountFormOptions) {
  const [firstName, setFirstName] = useState(initialValues.firstName || "");
  const [lastName, setLastName] = useState(initialValues.lastName || "");
  const [isAddressComplete, setIsAddressComplete] = useState(!needsAddress);
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [phone, setPhone] = useState(initialValues.phone || "");
  const [dateOfBirth, setDateOfBirth] = useState(initialValues.dateOfBirth || "");
  const [gender, setGender] = useState<"male" | "female" | "other" | "">(
    initialValues.gender || ""
  );
  const [acceptTerms, setAcceptTerms] = useState(initialValues.acceptTerms || false);
  const [marketingConsent, setMarketingConsent] = useState(initialValues.marketingConsent || false);
  const [errors, setErrors] = useState<AccountFormErrors>({});
  const { error: passwordValidationError } = usePasswordValidation(password);

  const clearError = useCallback((field: keyof AccountFormErrors) => {
    setErrors(prev => ({ ...prev, [field]: undefined }));
  }, []);

  const handleAddressChange = useCallback(
    (data: JapanAddressFormData, isComplete: boolean) => {
      setIsAddressComplete(isComplete);
      updateFormData({ address: data });
    },
    [updateFormData]
  );

  const validate = useCallback((): boolean => {
    const newErrors: AccountFormErrors = {};

    if (isNewCustomer) {
      if (!firstName.trim()) newErrors.firstName = "First name is required";
      if (!lastName.trim()) newErrors.lastName = "Last name is required";
    }
    if (needsAddress && !isAddressComplete) {
      newErrors.address = "Please complete the address";
    }

    if (passwordValidationError) newErrors.password = passwordValidationError;
    if (password !== confirmPassword) newErrors.confirmPassword = "Passwords do not match";
    if (phone.trim()) {
      const phoneResult = phoneSchema.safeParse(phone.trim());
      if (!phoneResult.success) {
        newErrors.phone = "Please enter a valid phone number";
      }
    } else {
      newErrors.phone = "Phone number is required";
    }
    if (!dateOfBirth) newErrors.dateOfBirth = "Date of birth is required";
    if (!gender) newErrors.gender = "Please select a gender";
    if (!acceptTerms) newErrors.acceptTerms = "You must accept the terms of service";

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  }, [
    isNewCustomer,
    needsAddress,
    firstName,
    lastName,
    isAddressComplete,
    passwordValidationError,
    password,
    confirmPassword,
    phone,
    dateOfBirth,
    gender,
    acceptTerms,
  ]);

  const getFormData = useCallback(
    (): FormState => ({
      firstName: firstName.trim(),
      lastName: lastName.trim(),
      phone: phone.trim(),
      dateOfBirth,
      gender: gender as "male" | "female" | "other" | "",
      password,
      confirmPassword,
      acceptTerms,
      marketingConsent,
    }),
    [
      firstName,
      lastName,
      phone,
      dateOfBirth,
      gender,
      password,
      confirmPassword,
      acceptTerms,
      marketingConsent,
    ]
  );

  const canSubmit =
    password &&
    confirmPassword &&
    phone &&
    dateOfBirth &&
    gender &&
    acceptTerms &&
    (isNewCustomer ? firstName && lastName : true) &&
    (needsAddress ? isAddressComplete : true);

  return {
    // Form values
    firstName,
    lastName,
    phone,
    dateOfBirth,
    gender,
    password,
    confirmPassword,
    acceptTerms,
    marketingConsent,
    errors,
    // Setters
    setFirstName,
    setLastName,
    setPhone,
    setDateOfBirth,
    setGender,
    setPassword,
    setConfirmPassword,
    setAcceptTerms,
    setMarketingConsent,
    // Handlers
    clearError,
    handleAddressChange,
    validate,
    getFormData,
    canSubmit,
  };
}
