/**
 * Signup Client Component
 *
 * Handles client-side signup flow.
 */

'use client';

import { useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useAuth } from '@/components/auth/AuthContext';
import { SignupViewData } from '@/lib/builders/view-data/types/SignupViewData';
import { SignupTemplate } from '@/templates/auth/SignupTemplate';
import { SignupMutation } from '@/lib/mutations/auth/SignupMutation';
import { SignupViewModelBuilder } from '@/lib/builders/view-models/SignupViewModelBuilder';
import { SignupViewModel } from '@/lib/view-models/auth/SignupViewModel';
import { SignupFormValidation } from '@/lib/utilities/authValidation';
import { ClientWrapperProps } from '@/lib/contracts/components/ComponentContracts';

export function SignupClient({ viewData }: ClientWrapperProps<SignupViewData>) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { refreshSession } = useAuth();

  // Build ViewModel from ViewData
  const [viewModel, setViewModel] = useState<SignupViewModel>(() =>
    SignupViewModelBuilder.build(viewData)
  );

  // Handle form field changes
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;

    setViewModel(prev => {
      const newFormState = {
        ...prev.formState,
        fields: {
          ...prev.formState.fields,
          [name as keyof typeof prev.formState.fields]: {
            ...prev.formState.fields[name as keyof typeof prev.formState.fields],
            value,
            touched: true,
            error: undefined,
          },
        },
      };
      return prev.withFormState(newFormState);
    });
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    const formData = {
      firstName: viewModel.formState.fields.firstName.value as string,
      lastName: viewModel.formState.fields.lastName.value as string,
      email: viewModel.formState.fields.email.value as string,
      password: viewModel.formState.fields.password.value as string,
      confirmPassword: viewModel.formState.fields.confirmPassword.value as string,
    };

    // Validate form
    const validationErrors = SignupFormValidation.validateForm(formData);
    if (validationErrors.length > 0) {
      setViewModel(prev => {
        const newFormState = {
          ...prev.formState,
          isValid: false,
          submitCount: prev.formState.submitCount + 1,
          fields: {
            ...prev.formState.fields,
            ...validationErrors.reduce((acc, error) => ({
              ...acc,
              [error.field]: {
                ...prev.formState.fields[error.field as keyof typeof prev.formState.fields],
                error: error.message,
                touched: true,
              },
            }), {}),
          },
        };
        return prev.withFormState(newFormState);
      });
      return;
    }

    // Update submitting state
    setViewModel(prev => prev.withMutationState(true, null));

    try {
      // Generate display name
      const displayName = SignupFormValidation.generateDisplayName(formData.firstName, formData.lastName);

      // Execute signup mutation
      const mutation = new SignupMutation();
      const result = await mutation.execute({
        email: formData.email,
        password: formData.password,
        displayName,
      });

      if (result.isErr()) {
        const error = result.getError();
        setViewModel(prev => prev.withMutationState(false, error));
        return;
      }

      // Success - refresh session and redirect
      await refreshSession();

      const returnTo = searchParams.get('returnTo') ?? '/onboarding';
      router.push(returnTo);
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Signup failed';
      setViewModel(prev => prev.withMutationState(false, errorMessage));
    }
  };

  // Toggle password visibility
  const togglePassword = () => {
    setViewModel(prev => prev.withUIState({
      ...prev.uiState,
      showPassword: !prev.uiState.showPassword,
    }));
  };

  const toggleConfirmPassword = () => {
    setViewModel(prev => prev.withUIState({
      ...prev.uiState,
      showConfirmPassword: !prev.uiState.showConfirmPassword,
    }));
  };

  // Build viewData for template
  const templateViewData: SignupViewData = {
    ...viewData,
    formState: viewModel.formState,
    isSubmitting: viewModel.isSubmitting,
    submitError: viewModel.submitError,
  };

  return (
    <SignupTemplate
      viewData={templateViewData}
      formActions={{
        handleChange,
        handleSubmit,
        setShowPassword: togglePassword,
        setShowConfirmPassword: toggleConfirmPassword,
      }}
      uiState={{
        showPassword: viewModel.uiState.showPassword,
        showConfirmPassword: viewModel.uiState.showConfirmPassword,
      }}
      mutationState={{
        isPending: viewModel.mutationPending,
        error: viewModel.mutationError,
      }}
    />
  );
}
