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";

type GenderValue = "male" | "female" | "other" | "";

interface FormState {
  firstName: string;
  lastName: string;
  phone: string;
  dateOfBirth: string;
  gender: GenderValue;
  password: string;
  confirmPassword: string;
  acceptTerms: boolean;
  marketingConsent: boolean;
}

interface InitialValues {
  firstName?: string;
  lastName?: string;
  phone?: string;
  dateOfBirth?: string;
  gender?: GenderValue;
  acceptTerms?: boolean;
  marketingConsent?: boolean;
}

interface UseCompleteAccountFormOptions {
  initialValues: InitialValues;
  isNewCustomer: boolean;
  needsAddress: boolean;
  updateFormData: (data: Record<string, unknown>) => void;
}

interface ValidateFieldsInput {
  isNewCustomer: boolean;
  needsAddress: boolean;
  isAddressComplete: boolean;
  firstName: string;
  lastName: string;
  passwordValidationError: string | undefined;
  password: string;
  confirmPassword: string;
  phone: string;
  dateOfBirth: string;
  gender: string;
  acceptTerms: boolean;
}

function validatePhone(phone: string): string | undefined {
  const trimmed = phone.trim();
  if (!trimmed) return "Phone number is required";
  if (!phoneSchema.safeParse(trimmed).success) return "Please enter a valid phone number";
  return undefined;
}

function validateFormFields(input: ValidateFieldsInput): AccountFormErrors {
  const errors: AccountFormErrors = {};
  if (input.isNewCustomer && !input.firstName.trim()) errors.firstName = "First name is required";
  if (input.isNewCustomer && !input.lastName.trim()) errors.lastName = "Last name is required";
  if (input.needsAddress && !input.isAddressComplete)
    errors.address = "Please complete the address";
  if (input.passwordValidationError) errors.password = input.passwordValidationError;
  if (input.password !== input.confirmPassword) errors.confirmPassword = "Passwords do not match";
  const phoneError = validatePhone(input.phone);
  if (phoneError) errors.phone = phoneError;
  if (!input.dateOfBirth) errors.dateOfBirth = "Date of birth is required";
  if (!input.gender) errors.gender = "Please select a gender";
  if (!input.acceptTerms) errors.acceptTerms = "You must accept the terms of service";
  return errors;
}

function computeCanSubmit(f: {
  password: string;
  confirmPassword: string;
  phone: string;
  dateOfBirth: string;
  gender: string;
  acceptTerms: boolean;
  firstName: string;
  lastName: string;
  isNewCustomer: boolean;
  needsAddress: boolean;
  isAddressComplete: boolean;
}) {
  const base =
    f.password && f.confirmPassword && f.phone && f.dateOfBirth && f.gender && f.acceptTerms;
  if (!base) return false;
  if (f.isNewCustomer && (!f.firstName || !f.lastName)) return false;
  if (f.needsAddress && !f.isAddressComplete) return false;
  return true;
}

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<GenderValue>(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 = validateFormFields({
      isNewCustomer,
      needsAddress,
      isAddressComplete,
      firstName,
      lastName,
      passwordValidationError,
      password,
      confirmPassword,
      phone,
      dateOfBirth,
      gender,
      acceptTerms,
    });
    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,
      password,
      confirmPassword,
      acceptTerms,
      marketingConsent,
    }),
    [
      firstName,
      lastName,
      phone,
      dateOfBirth,
      gender,
      password,
      confirmPassword,
      acceptTerms,
      marketingConsent,
    ]
  );

  const canSubmit = computeCanSubmit({
    password,
    confirmPassword,
    phone,
    dateOfBirth,
    gender,
    acceptTerms,
    firstName,
    lastName,
    isNewCustomer,
    needsAddress,
    isAddressComplete,
  });

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