/**
 * Auth Feature Flow Tests
 *
 * These tests verify routing, guards, navigation, cross-screen state, and user flows
 * for the auth module. They run with vitest and React Testing Library.
 *
 * Contracts are defined in apps/website/lib/types/generated
 *
 * @file apps/website/tests/flows/auth.test.tsx
 */

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import React from 'react';
import { LoginClient } from '@/client-wrapper/LoginClient';
import { SignupClient } from '@/client-wrapper/SignupClient';
import { ForgotPasswordClient } from '@/client-wrapper/ForgotPasswordClient';
import { ResetPasswordClient } from '@/client-wrapper/ResetPasswordClient';
import type { LoginViewData } from '@/lib/builders/view-data/types/LoginViewData';
import type { SignupViewData } from '@/lib/builders/view-data/types/SignupViewData';
import type { ForgotPasswordViewData } from '@/lib/builders/view-data/types/ForgotPasswordViewData';
import type { ResetPasswordViewData } from '@/lib/builders/view-data/types/ResetPasswordViewData';
import { Result } from '@/lib/contracts/Result';

// Mock next/navigation
const mockPush = vi.fn();
const mockReplace = vi.fn();
const mockRefresh = vi.fn();
const mockSearchParams = new URLSearchParams();

// Mock window.location to prevent navigation errors
const originalLocation = window.location;
delete (window as any).location;
(window as any).location = {
  href: '',
  pathname: '/auth/login',
  search: '',
  hash: '',
  origin: 'http://localhost:3000',
  protocol: 'http:',
  host: 'localhost:3000',
  hostname: 'localhost',
  port: '3000',
  assign: vi.fn(),
  replace: vi.fn(),
  reload: vi.fn(),
};

vi.mock('next/navigation', () => ({
  useRouter: () => ({
    push: mockPush,
    replace: mockReplace,
    refresh: mockRefresh,
  }),
  useSearchParams: () => mockSearchParams,
  usePathname: () => '/auth/login',
}));

// Mock AuthContext
const mockRefreshSession = vi.fn(() => Promise.resolve());
let mockSession: any = null;

vi.mock('@/components/auth/AuthContext', () => ({
  useAuth: () => ({
    refreshSession: mockRefreshSession,
    session: mockSession,
  }),
}));

// Mock mutations
const mockLoginMutation = {
  execute: vi.fn(() => Promise.resolve(Result.ok({}))),
};

const mockSignupMutation = {
  execute: vi.fn(() => Promise.resolve(Result.ok({}))),
};

const mockForgotPasswordMutation = {
  execute: vi.fn(() => Promise.resolve(Result.ok({}))),
};

const mockResetPasswordMutation = {
  execute: vi.fn(() => Promise.resolve(Result.ok({}))),
};

vi.mock('@/lib/mutations/auth/LoginMutation', () => ({
  LoginMutation: vi.fn().mockImplementation(() => ({
    execute: (...args: any[]) => mockLoginMutation.execute(...args),
  })),
}));

vi.mock('@/lib/mutations/auth/SignupMutation', () => ({
  SignupMutation: vi.fn().mockImplementation(() => ({
    execute: (...args: any[]) => mockSignupMutation.execute(...args),
  })),
}));

vi.mock('@/lib/mutations/auth/ForgotPasswordMutation', () => ({
  ForgotPasswordMutation: vi.fn().mockImplementation(() => ({
    execute: (...args: any[]) => mockForgotPasswordMutation.execute(...args),
  })),
}));

vi.mock('@/lib/mutations/auth/ResetPasswordMutation', () => ({
  ResetPasswordMutation: vi.fn().mockImplementation(() => ({
    execute: (...args: any[]) => mockResetPasswordMutation.execute(...args),
  })),
}));

// Mock process.env
const originalNodeEnv = process.env.NODE_ENV;
beforeEach(() => {
  process.env.NODE_ENV = 'development';
  vi.clearAllMocks();
  mockSession = null;
  mockSearchParams.delete('returnTo');
  mockSearchParams.delete('token');
});

afterEach(() => {
  process.env.NODE_ENV = originalNodeEnv;
});

describe('Auth Feature Flow', () => {
  describe('Login Flow', () => {
    const mockLoginViewData: LoginViewData = {
      formState: {
        fields: {
          email: { value: '', touched: false, error: undefined, validating: false },
          password: { value: '', touched: false, error: undefined, validating: false },
          rememberMe: { value: false, touched: false, error: undefined, validating: false },
        },
        isValid: true,
        isSubmitting: false,
        submitCount: 0,
        submitError: undefined,
      },
      showPassword: false,
      showErrorDetails: false,
      hasInsufficientPermissions: false,
      returnTo: '/dashboard',
      isSubmitting: false,
    };

    it('should display login form with all fields', () => {
      render(<LoginClient viewData={mockLoginViewData} />);

      expect(screen.getByLabelText(/email address/i)).toBeDefined();
      expect(screen.getByLabelText(/password/i)).toBeDefined();
      expect(screen.getByLabelText(/keep me signed in/i)).toBeDefined();
      expect(screen.getByRole('button', { name: /sign in/i })).toBeDefined();
    });

    it('should display validation errors for empty fields', async () => {
      render(<LoginClient viewData={mockLoginViewData} />);

      const submitButton = screen.getByRole('button', { name: /sign in/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/email is required/i)).toBeDefined();
        expect(screen.getByText(/password is required/i)).toBeDefined();
      });
    });

    it('should display validation error for invalid email format', async () => {
      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      fireEvent.change(emailInput, { target: { value: 'invalid-email' } });

      const submitButton = screen.getByRole('button', { name: /sign in/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/invalid email/i)).toBeDefined();
      });
    });

    it('should successfully login with valid credentials', async () => {
      mockLoginMutation.execute.mockImplementation(() => {
        mockSession = { userId: 'user-123' };
        return Promise.resolve(Result.ok({
          token: 'test-token-123',
          user: {
            userId: 'user-123',
            email: 'test@example.com',
            displayName: 'Test User',
            role: 'user',
          },
        }));
      });

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(mockLoginMutation.execute).toHaveBeenCalledWith({
          email: 'test@example.com',
          password: 'ValidPass123!',
          rememberMe: false,
        });
      });

      await waitFor(() => {
        expect(mockRefreshSession).toHaveBeenCalled();
      });

      await waitFor(() => {
        expect(mockPush).toHaveBeenCalledWith('/dashboard');
      });
    });

    it('should handle login with remember me option', async () => {
      mockLoginMutation.execute.mockImplementation(() => {
        mockSession = { userId: 'user-123' };
        return Promise.resolve(Result.ok({
          token: 'test-token-123',
          user: {
            userId: 'user-123',
            email: 'test@example.com',
            displayName: 'Test User',
            role: 'user',
          },
        }));
      });

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const rememberMeCheckbox = screen.getByLabelText(/keep me signed in/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(rememberMeCheckbox);
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(mockLoginMutation.execute).toHaveBeenCalledWith({
          email: 'test@example.com',
          password: 'ValidPass123!',
          rememberMe: true,
        });
      });
    });

    it('should handle login errors (invalid credentials)', async () => {
      mockLoginMutation.execute.mockResolvedValue(
        Result.err('Invalid credentials')
      );

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'wrong@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'WrongPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/invalid credentials/i)).toBeDefined();
      });

      // Verify form remains in error state
      expect((emailInput as HTMLInputElement).value).toBe('wrong@example.com');
    });

    it('should handle login errors (server error)', async () => {
      mockLoginMutation.execute.mockResolvedValue(
        Result.err('Internal Server Error')
      );

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/error/i)).toBeDefined();
      });
    });

    it('should navigate to forgot password from login', () => {
      render(<LoginClient viewData={mockLoginViewData} />);

      const forgotPasswordLink = screen.getByText(/forgot password/i);
      fireEvent.click(forgotPasswordLink);

      expect(mockPush).toHaveBeenCalledWith('/auth/forgot-password');
    });

    it('should navigate to signup from login', () => {
      render(<LoginClient viewData={mockLoginViewData} />);

      const signupLink = screen.getByText(/create one/i);
      fireEvent.click(signupLink);

      expect(mockPush).toHaveBeenCalledWith('/auth/signup');
    });

    it('should handle password visibility toggle', () => {
      render(<LoginClient viewData={mockLoginViewData} />);

      const passwordInput = screen.getByLabelText(/password/i);
      expect((passwordInput as HTMLInputElement).type).toBe('password');

      const toggleButton = screen.getByRole('button', { name: /show password/i });
      fireEvent.click(toggleButton);

      expect((passwordInput as HTMLInputElement).type).toBe('text');
    });
  });

  describe('Signup Flow', () => {
    const mockSignupViewData: SignupViewData = {
      returnTo: '/onboarding',
      formState: {
        fields: {
          firstName: { value: '', touched: false, error: undefined, validating: false },
          lastName: { value: '', touched: false, error: undefined, validating: false },
          email: { value: '', touched: false, error: undefined, validating: false },
          password: { value: '', touched: false, error: undefined, validating: false },
          confirmPassword: { value: '', touched: false, error: undefined, validating: false },
        },
        isValid: true,
        isSubmitting: false,
        submitCount: 0,
        submitError: undefined,
      },
      isSubmitting: false,
    };

    it('should display signup form with all fields', () => {
      render(<SignupClient viewData={mockSignupViewData} />);

      expect(screen.getByLabelText(/first name/i)).toBeDefined();
      expect(screen.getByLabelText(/last name/i)).toBeDefined();
      expect(screen.getByLabelText(/email address/i)).toBeDefined();
      expect(screen.getByLabelText(/^password$/i)).toBeDefined();
      expect(screen.getByLabelText(/confirm password/i)).toBeDefined();
      expect(screen.getByRole('button', { name: /create account/i })).toBeDefined();
    });

    it('should display validation errors for empty required fields', async () => {
      render(<SignupClient viewData={mockSignupViewData} />);

      const submitButton = screen.getByRole('button', { name: /create account/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/first name is required/i)).toBeDefined();
        expect(screen.getByText(/last name is required/i)).toBeDefined();
        expect(screen.getByText(/email is required/i)).toBeDefined();
        expect(screen.getByText(/password is required/i)).toBeDefined();
        expect(screen.getByText(/confirm password is required/i)).toBeDefined();
      });
    });

    it('should display validation errors for weak password', async () => {
      render(<SignupClient viewData={mockSignupViewData} />);

      const passwordInput = screen.getByLabelText(/^password$/i);
      fireEvent.change(passwordInput, { target: { value: 'weak' } });

      const submitButton = screen.getByRole('button', { name: /create account/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/password must be/i)).toBeDefined();
      });
    });

    it('should successfully signup with valid data', async () => {
      mockSignupMutation.execute.mockImplementation(() => {
        mockSession = { userId: 'user-456' };
        return Promise.resolve(Result.ok({
          token: 'test-token-456',
          user: {
            userId: 'user-456',
            email: 'newuser@example.com',
            displayName: 'New User',
            role: 'user',
          },
        }));
      });

      render(<SignupClient viewData={mockSignupViewData} />);

      const firstNameInput = screen.getByLabelText(/first name/i);
      const lastNameInput = screen.getByLabelText(/last name/i);
      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/^password$/i);
      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      const submitButton = screen.getByRole('button', { name: /create account/i });

      fireEvent.change(firstNameInput, { target: { value: 'New' } });
      fireEvent.change(lastNameInput, { target: { value: 'User' } });
      fireEvent.change(emailInput, { target: { value: 'newuser@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.change(confirmPasswordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(mockSignupMutation.execute).toHaveBeenCalledWith({
          email: 'newuser@example.com',
          password: 'ValidPass123!',
          displayName: 'New User',
        });
      });

      await waitFor(() => {
        expect(mockRefreshSession).toHaveBeenCalled();
      });

      await waitFor(() => {
        expect(mockPush).toHaveBeenCalledWith('/onboarding');
      });
    });

    it('should handle signup errors (email already exists)', async () => {
      mockSignupMutation.execute.mockResolvedValue(
        Result.err('Email already exists')
      );

      render(<SignupClient viewData={mockSignupViewData} />);

      const firstNameInput = screen.getByLabelText(/first name/i);
      const lastNameInput = screen.getByLabelText(/last name/i);
      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/^password$/i);
      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      const submitButton = screen.getByRole('button', { name: /create account/i });

      fireEvent.change(firstNameInput, { target: { value: 'Existing' } });
      fireEvent.change(lastNameInput, { target: { value: 'User' } });
      fireEvent.change(emailInput, { target: { value: 'existing@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.change(confirmPasswordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/already exists/i)).toBeDefined();
      });
    });

    it('should handle signup errors (server error)', async () => {
      mockSignupMutation.execute.mockResolvedValue(
        Result.err('Internal Server Error')
      );

      render(<SignupClient viewData={mockSignupViewData} />);

      const firstNameInput = screen.getByLabelText(/first name/i);
      const lastNameInput = screen.getByLabelText(/last name/i);
      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/^password$/i);
      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      const submitButton = screen.getByRole('button', { name: /create account/i });

      fireEvent.change(firstNameInput, { target: { value: 'Test' } });
      fireEvent.change(lastNameInput, { target: { value: 'User' } });
      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.change(confirmPasswordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/error/i)).toBeDefined();
      });
    });

    it('should navigate to login from signup', () => {
      render(<SignupClient viewData={mockSignupViewData} />);

      const loginLink = screen.getByText(/already have an account/i);
      fireEvent.click(loginLink);

      expect(mockPush).toHaveBeenCalledWith('/auth/login');
    });

    it('should handle password visibility toggle', () => {
      render(<SignupClient viewData={mockSignupViewData} />);

      const passwordInput = screen.getByLabelText(/^password$/i);
      expect((passwordInput as HTMLInputElement).type).toBe('password');

      const toggleButton = screen.getByRole('button', { name: /show password/i });
      fireEvent.click(toggleButton);

      expect((passwordInput as HTMLInputElement).type).toBe('text');
    });

    it('should handle confirm password visibility toggle', () => {
      render(<SignupClient viewData={mockSignupViewData} />);

      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      expect((confirmPasswordInput as HTMLInputElement).type).toBe('password');

      const toggleButton = screen.getByRole('button', { name: /show confirm password/i });
      fireEvent.click(toggleButton);

      expect((confirmPasswordInput as HTMLInputElement).type).toBe('text');
    });
  });

  describe('Forgot Password Flow', () => {
    const mockForgotPasswordViewData: ForgotPasswordViewData = {
      returnTo: '/auth/login',
      formState: {
        fields: {
          email: { value: '', touched: false, error: undefined, validating: false },
        },
        isValid: true,
        isSubmitting: false,
        submitCount: 0,
        submitError: undefined,
      },
      showSuccess: false,
      successMessage: undefined,
      magicLink: undefined,
      isSubmitting: false,
    };

    it('should display forgot password form with email field', () => {
      render(<ForgotPasswordClient viewData={mockForgotPasswordViewData} />);

      expect(screen.getByLabelText(/email address/i)).toBeDefined();
      expect(screen.getByRole('button', { name: /send reset link/i })).toBeDefined();
    });

    it('should display validation error for empty email', async () => {
      render(<ForgotPasswordClient viewData={mockForgotPasswordViewData} />);

      const submitButton = screen.getByRole('button', { name: /send reset link/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/email is required/i)).toBeDefined();
      });
    });

    it('should display validation error for invalid email format', async () => {
      render(<ForgotPasswordClient viewData={mockForgotPasswordViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      fireEvent.change(emailInput, { target: { value: 'invalid-email' } });

      const submitButton = screen.getByRole('button', { name: /send reset link/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/invalid email/i)).toBeDefined();
      });
    });

    it('should successfully submit forgot password request', async () => {
      mockForgotPasswordMutation.execute.mockResolvedValue(
        Result.ok({
          success: true,
          message: 'Password reset email sent',
        })
      );

      render(<ForgotPasswordClient viewData={mockForgotPasswordViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const submitButton = screen.getByRole('button', { name: /send reset link/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(mockForgotPasswordMutation.execute).toHaveBeenCalledWith({
          email: 'test@example.com',
        });
      });

      await waitFor(() => {
        expect(screen.getByText(/password reset email sent/i)).toBeDefined();
      });
    });

    it('should handle forgot password errors (email not found)', async () => {
      mockForgotPasswordMutation.execute.mockResolvedValue(
        Result.err('Email not found')
      );

      render(<ForgotPasswordClient viewData={mockForgotPasswordViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const submitButton = screen.getByRole('button', { name: /send reset link/i });

      fireEvent.change(emailInput, { target: { value: 'nonexistent@example.com' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/email not found/i)).toBeDefined();
      });
    });

    it('should handle forgot password errors (rate limit)', async () => {
      mockForgotPasswordMutation.execute.mockResolvedValue(
        Result.err('Rate limit exceeded')
      );

      render(<ForgotPasswordClient viewData={mockForgotPasswordViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const submitButton = screen.getByRole('button', { name: /send reset link/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/rate limit/i)).toBeDefined();
      });
    });

    it('should navigate back to login from forgot password', () => {
      render(<ForgotPasswordClient viewData={mockForgotPasswordViewData} />);

      const loginLink = screen.getByText(/back to login/i);
      fireEvent.click(loginLink);

      expect(mockPush).toHaveBeenCalledWith('/auth/login');
    });
  });

  describe('Reset Password Flow', () => {
    const mockResetPasswordViewData: ResetPasswordViewData = {
      token: 'abc123',
      returnTo: '/auth/login',
      formState: {
        fields: {
          newPassword: { value: '', touched: false, error: undefined, validating: false },
          confirmPassword: { value: '', touched: false, error: undefined, validating: false },
        },
        isValid: true,
        isSubmitting: false,
        submitCount: 0,
        submitError: undefined,
      },
      showSuccess: false,
      successMessage: undefined,
      isSubmitting: false,
    };

    beforeEach(() => {
      mockSearchParams.set('token', 'abc123');
    });

    it('should display reset password form with password fields', () => {
      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      expect(screen.getByLabelText(/^new password$/i)).toBeDefined();
      expect(screen.getByLabelText(/confirm password/i)).toBeDefined();
      expect(screen.getByRole('button', { name: /reset password/i })).toBeDefined();
    });

    it('should display validation errors for empty password fields', async () => {
      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const submitButton = screen.getByRole('button', { name: /reset password/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/new password is required/i)).toBeDefined();
        expect(screen.getByText(/confirm password is required/i)).toBeDefined();
      });
    });

    it('should display validation error for non-matching passwords', async () => {
      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const newPasswordInput = screen.getByLabelText(/^new password$/i);
      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);

      fireEvent.change(newPasswordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.change(confirmPasswordInput, { target: { value: 'DifferentPass456!' } });

      const submitButton = screen.getByRole('button', { name: /reset password/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/passwords do not match/i)).toBeDefined();
      });
    });

    it('should display validation error for weak new password', async () => {
      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const newPasswordInput = screen.getByLabelText(/^new password$/i);
      fireEvent.change(newPasswordInput, { target: { value: 'weak' } });

      const submitButton = screen.getByRole('button', { name: /reset password/i });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/password must be/i)).toBeDefined();
      });
    });

    it('should successfully reset password', async () => {
      mockResetPasswordMutation.execute.mockResolvedValue(
        Result.ok({
          success: true,
          message: 'Password reset successfully',
        })
      );

      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const newPasswordInput = screen.getByLabelText(/^new password$/i);
      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      const submitButton = screen.getByRole('button', { name: /reset password/i });

      fireEvent.change(newPasswordInput, { target: { value: 'NewPass123!' } });
      fireEvent.change(confirmPasswordInput, { target: { value: 'NewPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(mockResetPasswordMutation.execute).toHaveBeenCalledWith({
          token: 'abc123',
          newPassword: 'NewPass123!',
        });
      });

      await waitFor(() => {
        expect(screen.getByText(/password reset successfully/i)).toBeDefined();
      });

      // Verify redirect to login page after delay
      await waitFor(() => {
        expect(mockPush).toHaveBeenCalledWith('/auth/login');
      }, { timeout: 5000 });
    });

    it('should handle reset password with invalid token', async () => {
      mockResetPasswordMutation.execute.mockResolvedValue(
        Result.err('Invalid token')
      );

      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const newPasswordInput = screen.getByLabelText(/^new password$/i);
      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      const submitButton = screen.getByRole('button', { name: /reset password/i });

      fireEvent.change(newPasswordInput, { target: { value: 'NewPass123!' } });
      fireEvent.change(confirmPasswordInput, { target: { value: 'NewPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/invalid token/i)).toBeDefined();
      });

      // Verify form is disabled
      expect((submitButton as HTMLButtonElement).disabled).toBe(true);
    });

    it('should handle reset password with expired token', async () => {
      mockResetPasswordMutation.execute.mockResolvedValue(
        Result.err('Token expired')
      );

      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const newPasswordInput = screen.getByLabelText(/^new password$/i);
      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      const submitButton = screen.getByRole('button', { name: /reset password/i });

      fireEvent.change(newPasswordInput, { target: { value: 'NewPass123!' } });
      fireEvent.change(confirmPasswordInput, { target: { value: 'NewPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/token expired/i)).toBeDefined();
      });

      // Verify link to request new reset email
      expect(screen.getByText(/request new link/i)).toBeDefined();
    });

    it('should handle reset password errors (server error)', async () => {
      mockResetPasswordMutation.execute.mockResolvedValue(
        Result.err('Internal Server Error')
      );

      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const newPasswordInput = screen.getByLabelText(/^new password$/i);
      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      const submitButton = screen.getByRole('button', { name: /reset password/i });

      fireEvent.change(newPasswordInput, { target: { value: 'NewPass123!' } });
      fireEvent.change(confirmPasswordInput, { target: { value: 'NewPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/error/i)).toBeDefined();
      });
    });

    it('should navigate to login from reset password', () => {
      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const loginLink = screen.getByText(/back to login/i);
      fireEvent.click(loginLink);

      expect(mockPush).toHaveBeenCalledWith('/auth/login');
    });

    it('should handle password visibility toggle', () => {
      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const newPasswordInput = screen.getByLabelText(/^new password$/i);
      expect((newPasswordInput as HTMLInputElement).type).toBe('password');

      const toggleButton = screen.getByRole('button', { name: /show password/i });
      fireEvent.click(toggleButton);

      expect((newPasswordInput as HTMLInputElement).type).toBe('text');
    });

    it('should handle confirm password visibility toggle', () => {
      render(<ResetPasswordClient viewData={mockResetPasswordViewData} />);

      const confirmPasswordInput = screen.getByLabelText(/confirm password/i);
      expect((confirmPasswordInput as HTMLInputElement).type).toBe('password');

      const toggleButton = screen.getByRole('button', { name: /show confirm password/i });
      fireEvent.click(toggleButton);

      expect((confirmPasswordInput as HTMLInputElement).type).toBe('text');
    });
  });

  describe('Auth Cross-Screen State Management', () => {
    const mockLoginViewData: LoginViewData = {
      formState: {
        fields: {
          email: { value: '', touched: false, error: undefined, validating: false },
          password: { value: '', touched: false, error: undefined, validating: false },
          rememberMe: { value: false, touched: false, error: undefined, validating: false },
        },
        isValid: true,
        isSubmitting: false,
        submitCount: 0,
        submitError: undefined,
      },
      showPassword: false,
      showErrorDetails: false,
      hasInsufficientPermissions: false,
      returnTo: '/dashboard',
      isSubmitting: false,
    };

    it('should preserve form data when navigating between auth pages', async () => {
      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });

      // Navigate to forgot password
      const forgotPasswordLink = screen.getByText(/forgot password/i);
      fireEvent.click(forgotPasswordLink);

      // Navigate back to login
      const loginLink = screen.getByText(/back to login/i);
      fireEvent.click(loginLink);

      // Verify email is preserved
      await waitFor(() => {
        expect((emailInput as HTMLInputElement).value).toBe('test@example.com');
      });
    });

    it('should clear form data after successful authentication', async () => {
      mockLoginMutation.execute.mockImplementation(() => {
        mockSession = { userId: 'user-123' };
        return Promise.resolve(Result.ok({
          token: 'test-token-123',
          user: {
            userId: 'user-123',
            email: 'test@example.com',
            displayName: 'Test User',
            role: 'user',
          },
        }));
      });

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(mockPush).toHaveBeenCalledWith('/dashboard');
      });

      // Navigate back to login
      mockPush.mockClear();
      const loginLink = screen.getByText(/sign in/i);
      fireEvent.click(loginLink);

      // Verify form is cleared
      await waitFor(() => {
        expect((emailInput as HTMLInputElement).value).toBe('');
        expect((passwordInput as HTMLInputElement).value).toBe('');
      });
    });

    it('should handle concurrent auth operations', async () => {
      mockLoginMutation.execute.mockImplementation(() => {
        mockSession = { userId: 'user-123' };
        return Promise.resolve(Result.ok({
          token: 'test-token-123',
          user: {
            userId: 'user-123',
            email: 'test@example.com',
            displayName: 'Test User',
            role: 'user',
          },
        }));
      });

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });

      // Click submit multiple times quickly
      fireEvent.click(submitButton);
      fireEvent.click(submitButton);
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(mockLoginMutation.execute).toHaveBeenCalledTimes(1);
      });

      await waitFor(() => {
        expect(mockPush).toHaveBeenCalledWith('/dashboard');
      });
    });
  });

  describe('Auth UI State Management', () => {
    const mockLoginViewData: LoginViewData = {
      formState: {
        fields: {
          email: { value: '', touched: false, error: undefined, validating: false },
          password: { value: '', touched: false, error: undefined, validating: false },
          rememberMe: { value: false, touched: false, error: undefined, validating: false },
        },
        isValid: true,
        isSubmitting: false,
        submitCount: 0,
        submitError: undefined,
      },
      showPassword: false,
      showErrorDetails: false,
      hasInsufficientPermissions: false,
      returnTo: '/dashboard',
      isSubmitting: false,
    };

    it('should show loading states during auth operations', async () => {
      mockLoginMutation.execute.mockImplementation(
        () => new Promise(resolve => setTimeout(() => {
          mockSession = { userId: 'user-123' };
          resolve(Result.ok({
            token: 'test-token-123',
            user: {
              userId: 'user-123',
              email: 'test@example.com',
              displayName: 'Test User',
              role: 'user',
            },
          }));
        }, 100))
      );

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(submitButton);

      // Verify loading state
      await waitFor(() => {
        expect(screen.getByText(/signing in/i)).toBeDefined();
      });

      // Wait for loading to complete
      await waitFor(() => {
        expect(screen.queryByText(/signing in/i)).toBeNull();
      });

      // Verify authentication is successful
      await waitFor(() => {
        expect(mockPush).toHaveBeenCalledWith('/dashboard');
      });
    });

    it('should handle error states gracefully', async () => {
      mockLoginMutation.execute.mockResolvedValue(
        Result.err('Invalid credentials')
      );

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'wrong@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'WrongPass123!' } });
      fireEvent.click(submitButton);

      // Verify error message is displayed
      await waitFor(() => {
        expect(screen.getByText(/invalid credentials/i)).toBeDefined();
      });

      // Verify UI remains usable after errors
      expect((emailInput as HTMLInputElement).disabled).toBe(false);
      expect((passwordInput as HTMLInputElement).disabled).toBe(false);
      expect((submitButton as HTMLButtonElement).disabled).toBe(false);
    });

    it('should handle network connectivity issues', async () => {
      mockLoginMutation.execute.mockResolvedValue(
        Result.err('Network Error')
      );

      render(<LoginClient viewData={mockLoginViewData} />);

      const emailInput = screen.getByLabelText(/email address/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /sign in/i });

      fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
      fireEvent.change(passwordInput, { target: { value: 'ValidPass123!' } });
      fireEvent.click(submitButton);

      // Verify network error message is shown
      await waitFor(() => {
        expect(screen.getByText(/network/i)).toBeDefined();
      });
    });
  });
});
