import { describe, it, expect, vi } from 'vitest';
import { z } from 'zod';

describe('Contact Page', () => {
  describe('form schema validation', () => {
    const mockT = (key: string) => key;

    const schema = z.object({
      email: z.email(mockT('pages.contact.form.validation.invalidEmail')),
      name: z
        .string()
        .min(1, mockT('pages.contact.form.validation.shortName'))
        .max(100, mockT('pages.contact.form.validation.longName')),
      message: z
        .string()
        .min(10, mockT('pages.contact.form.validation.shortMessage'))
        .max(5000, mockT('pages.contact.form.validation.longMessage')),
      website: z.string().optional(),
    });

    it('should validate valid form data', () => {
      const validData = {
        email: 'test@example.com',
        name: 'John Doe',
        message: 'This is a test message that is longer than 10 characters',
        website: '',
      };

      const result = schema.safeParse(validData);
      expect(result.success).toBe(true);
    });

    it('should reject invalid email', () => {
      const invalidData = {
        email: 'invalid-email',
        name: 'John Doe',
        message: 'This is a valid message',
      };

      const result = schema.safeParse(invalidData);
      expect(result.success).toBe(false);
    });

    it('should reject empty name', () => {
      const invalidData = {
        email: 'test@example.com',
        name: '',
        message: 'This is a valid message',
      };

      const result = schema.safeParse(invalidData);
      expect(result.success).toBe(false);
    });

    it('should reject too long name (>100 chars)', () => {
      const invalidData = {
        email: 'test@example.com',
        name: 'a'.repeat(101),
        message: 'This is a valid message',
      };

      const result = schema.safeParse(invalidData);
      expect(result.success).toBe(false);
    });

    it('should reject too short message (<10 chars)', () => {
      const invalidData = {
        email: 'test@example.com',
        name: 'John Doe',
        message: 'Short',
      };

      const result = schema.safeParse(invalidData);
      expect(result.success).toBe(false);
    });

    it('should reject too long message (>5000 chars)', () => {
      const invalidData = {
        email: 'test@example.com',
        name: 'John Doe',
        message: 'a'.repeat(5001),
      };

      const result = schema.safeParse(invalidData);
      expect(result.success).toBe(false);
    });

    it('should allow optional website field', () => {
      const validData = {
        email: 'test@example.com',
        name: 'John Doe',
        message: 'This is a valid test message',
      };

      const result = schema.safeParse(validData);
      expect(result.success).toBe(true);
    });

    it('should accept website when provided', () => {
      const validData = {
        email: 'test@example.com',
        name: 'John Doe',
        message: 'This is a valid test message',
        website: 'https://example.com',
      };

      const result = schema.safeParse(validData);
      expect(result.success).toBe(true);
    });
  });

  describe('form state', () => {
    it('should initialize with undefined values', () => {
      const state = reactive({
        name: undefined as string | undefined,
        email: undefined as string | undefined,
        message: undefined as string | undefined,
        website: undefined as string | undefined,
      });

      expect(state.name).toBeUndefined();
      expect(state.email).toBeUndefined();
      expect(state.message).toBeUndefined();
      expect(state.website).toBeUndefined();
    });

    it('should update values when set', () => {
      const state = reactive({
        name: undefined as string | undefined,
        email: undefined as string | undefined,
        message: undefined as string | undefined,
        website: undefined as string | undefined,
      });

      state.name = 'John Doe';
      state.email = 'test@example.com';
      state.message = 'Hello, this is a test message';

      expect(state.name).toBe('John Doe');
      expect(state.email).toBe('test@example.com');
      expect(state.message).toBe('Hello, this is a test message');
    });
  });

  describe('toast notification logic', () => {
    it('should show success toast on successful response', () => {
      const mockToastAdd = vi.fn();
      const mockT = (key: string) => key;
      const response = { success: true, message: 'Message sent successfully' };

      // Simulate the watcher behavior
      if (response) {
        mockToastAdd({
          title: response.success ? mockT('pages.contact.toast.success') : mockT('pages.contact.toast.error'),
          description: mockT(response.message),
          color: response.success ? 'info' : 'error',
        });
      }

      expect(mockToastAdd).toHaveBeenCalledWith({
        title: 'pages.contact.toast.success',
        description: 'Message sent successfully',
        color: 'info',
      });
    });

    it('should show error toast on failed response', () => {
      const mockToastAdd = vi.fn();
      const mockT = (key: string) => key;
      const response = { success: false, message: 'Failed to send' };

      if (response) {
        mockToastAdd({
          title: response.success ? mockT('pages.contact.toast.success') : mockT('pages.contact.toast.error'),
          description: mockT(response.message),
          color: response.success ? 'info' : 'error',
        });
      }

      expect(mockToastAdd).toHaveBeenCalledWith({
        title: 'pages.contact.toast.error',
        description: 'Failed to send',
        color: 'error',
      });
    });

    it('should show error toast on contact error', () => {
      const mockToastAdd = vi.fn();
      const mockT = (key: string) => key;
      const error = { message: 'backend.errors.unknown' };

      if (error) {
        mockToastAdd({
          title: mockT('pages.contact.toast.error'),
          description: mockT(error.message),
          color: 'error',
        });
      }

      expect(mockToastAdd).toHaveBeenCalledWith({
        title: 'pages.contact.toast.error',
        description: 'backend.errors.unknown',
        color: 'error',
      });
    });
  });
});
