import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

import SitesCreate from './Create';

const mockPost = vi.fn();
let mockErrors: Record<string, string> = {};
let mockProcessing = false;

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    useForm: () => ({
      data: { name: '', domain: '' },
      setData: vi.fn(),
      post: mockPost,
      processing: mockProcessing,
      errors: mockErrors,
      isDirty: false,
    }),
    usePage: vi.fn(() => ({
      props: {
        auth: { user: { id: 1, name: 'Test' } },
        errors: {},
        flash: {},
        features: {},
        sites: [],
        limits: null,
        ai_defaults: {},
        notifications_unread_count: 0,
      },
    })),
  };
});

vi.mock('@/hooks/useUnsavedChanges', () => ({
  useUnsavedChanges: vi.fn(),
}));

vi.mock('@/Layouts/DashboardLayout', () => ({
  default: ({ children }: { children: React.ReactNode }) => (
    <div data-testid="dashboard-layout">{children}</div>
  ),
}));

describe('Sites/Create', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockErrors = {};
    mockProcessing = false;
    vi.stubGlobal(
      'route',
      vi.fn(() => '/sites'),
    );
  });

  // ============================================
  // Rendering tests
  // ============================================

  describe('rendering', () => {
    it('renders the page title', () => {
      render(<SitesCreate />);

      expect(document.querySelector('title')).toHaveTextContent('Create Site');
    });

    it('renders the heading', () => {
      render(<SitesCreate />);

      expect(screen.getByText('Connect your WordPress site')).toBeInTheDocument();
    });

    it('renders the description text', () => {
      render(<SitesCreate />);

      expect(
        screen.getByText(/diagnosing seo issues and generating ai-powered content fixes/i),
      ).toBeInTheDocument();
    });
  });

  // ============================================
  // Form field tests
  // ============================================

  describe('form fields', () => {
    it('renders the site name label and input', () => {
      render(<SitesCreate />);

      expect(screen.getByText('Site name')).toBeInTheDocument();
      expect(screen.getByPlaceholderText('My Website')).toBeInTheDocument();
    });

    it('renders the domain label and input', () => {
      render(<SitesCreate />);

      expect(screen.getByText('Domain')).toBeInTheDocument();
      expect(screen.getByPlaceholderText('https://example.com')).toBeInTheDocument();
    });

    it('renders the submit button', () => {
      render(<SitesCreate />);

      expect(screen.getByRole('button', { name: /connect site/i })).toBeInTheDocument();
    });
  });

  // ============================================
  // Error display tests
  // ============================================

  describe('error display', () => {
    it('shows name error when present', () => {
      mockErrors = { name: 'The name field is required.' };

      render(<SitesCreate />);

      expect(screen.getByText('The name field is required.')).toBeInTheDocument();
    });

    it('shows domain error when present', () => {
      mockErrors = { domain: 'The domain field is required.' };

      render(<SitesCreate />);

      expect(screen.getByText('The domain field is required.')).toBeInTheDocument();
    });

    it('shows both errors simultaneously', () => {
      mockErrors = {
        name: 'The name field is required.',
        domain: 'The domain must be a valid URL.',
      };

      render(<SitesCreate />);

      expect(screen.getByText('The name field is required.')).toBeInTheDocument();
      expect(screen.getByText('The domain must be a valid URL.')).toBeInTheDocument();
    });

    it('does not show errors when none are present', () => {
      mockErrors = {};

      render(<SitesCreate />);

      expect(screen.queryByText(/is required/i)).not.toBeInTheDocument();
    });
  });

  // ============================================
  // Form submission tests
  // ============================================

  describe('form submission', () => {
    it('calls post on form submission', () => {
      render(<SitesCreate />);

      const form = screen.getByRole('button', { name: /connect site/i }).closest('form')!;
      fireEvent.submit(form);

      expect(mockPost).toHaveBeenCalledWith(
        '/sites',
        expect.objectContaining({
          onSuccess: expect.any(Function),
        }),
      );
    });
  });

  // ============================================
  // Processing state tests
  // ============================================

  describe('processing state', () => {
    it('shows loading state when processing', () => {
      mockProcessing = true;

      render(<SitesCreate />);

      const button = screen.getByRole('button');
      expect(button).toBeDisabled();
    });
  });

  // ============================================
  // Layout tests
  // ============================================

  describe('layout', () => {
    it('assigns DashboardLayout as layout', () => {
      expect(SitesCreate.layout).toBeDefined();
    });
  });
});
