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

import { useForm } from '@inertiajs/react';

import SiteSettings from './Settings';

const mockedUseForm = vi.mocked(useForm) as unknown as {
  mockReset: () => typeof mockedUseForm;
  mockReturnValueOnce: (val: unknown) => typeof mockedUseForm;
  mockReturnValue: (val: unknown) => typeof mockedUseForm;
};

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

// Mock SiteNav
vi.mock('@/Components/Navigation/SiteNav', () => ({
  default: ({ siteId }: { siteId: number }) => (
    <nav data-testid="site-nav">SiteNav for site {siteId}</nav>
  ),
}));

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

// Mock format helpers
vi.mock('@/lib/format', () => ({
  formatNumber: (n: number) => String(n),
  formatDate: (date: string) => date,
}));

const mockPatch = vi.fn();
const scheduleFormReturn = {
  data: { enabled: false, frequency: 'weekly' },
  setData: vi.fn(),
  patch: mockPatch,
  processing: false,
  errors: {},
  isDirty: false,
  transform: vi.fn(),
  reset: vi.fn(),
  clearErrors: vi.fn(),
  wasSuccessful: false,
  recentlySuccessful: false,
  hasErrors: false,
  setError: vi.fn(),
  setDefaults: vi.fn(),
  cancel: vi.fn(),
  submit: vi.fn(),
  progress: null,
  delete: vi.fn(),
  get: vi.fn(),
  post: vi.fn(),
  put: vi.fn(),
};

const automationFormReturn = {
  data: {
    auto_analyze_after_sync: false,
    auto_generate_drafts: false,
    draft_impact_threshold: 70,
    min_analysis_interval_hours: 6,
  },
  setData: vi.fn(),
  patch: vi.fn(),
  processing: false,
  errors: {},
  isDirty: false,
  transform: vi.fn(),
  reset: vi.fn(),
  clearErrors: vi.fn(),
  wasSuccessful: false,
  recentlySuccessful: false,
  hasErrors: false,
  setError: vi.fn(),
  setDefaults: vi.fn(),
  cancel: vi.fn(),
  submit: vi.fn(),
  progress: null,
  delete: vi.fn(),
  get: vi.fn(),
  post: vi.fn(),
  put: vi.fn(),
};

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    // useForm is called twice: once for schedule, once for automation
    useForm: vi.fn(),
  };
});

const defaultSite = { id: 1, name: 'Test Site', domain: 'example.com' };
const defaultAutomation = {
  auto_analyze_after_sync: false,
  auto_generate_drafts: false,
  draft_impact_threshold: 70,
  min_analysis_interval_hours: 6,
};

describe('Sites/Settings page', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    // Return schedule form first, then automation form
    (useForm as Mock).mockReturnValueOnce(scheduleFormReturn).mockReturnValue(automationFormReturn);
  });

  it('renders the page title', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('Analysis Schedule')).toBeInTheDocument();
  });

  it('renders SiteNav with correct site id', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByTestId('site-nav')).toHaveTextContent('SiteNav for site 1');
  });

  it('renders site description', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText(/Configure automatic analysis runs for Test Site/)).toBeInTheDocument();
  });

  it('renders enable schedule switch', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('Enable scheduled analysis')).toBeInTheDocument();
  });

  it('renders save button', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('Save Schedule')).toBeInTheDocument();
  });

  it('shows frequency selector when enabled', () => {
    mockedUseForm
      .mockReset()
      .mockReturnValueOnce({
        ...scheduleFormReturn,
        data: { enabled: true, frequency: 'weekly' },
      } as unknown as ReturnType<typeof useForm>)
      .mockReturnValue(automationFormReturn as unknown as ReturnType<typeof useForm>);

    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('Analysis frequency')).toBeInTheDocument();
  });

  it('hides frequency selector when disabled', () => {
    mockedUseForm
      .mockReset()
      .mockReturnValueOnce({
        ...scheduleFormReturn,
        data: { enabled: false, frequency: 'weekly' },
      } as unknown as ReturnType<typeof useForm>)
      .mockReturnValue(automationFormReturn as unknown as ReturnType<typeof useForm>);

    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.queryByText('Analysis frequency')).not.toBeInTheDocument();
  });

  it('shows schedule info when schedule exists', () => {
    const schedule = {
      id: 1,
      site_id: 1,
      frequency: 'weekly',
      next_run_at: '2026-03-01T00:00:00Z',
      last_run_at: '2026-02-22T00:00:00Z',
      last_run_status: 'completed',
      enabled: true,
    };

    render(<SiteSettings site={defaultSite} schedule={schedule} automation={defaultAutomation} />);

    expect(screen.getByText('Schedule Information')).toBeInTheDocument();
    expect(screen.getByText('Next scheduled run:')).toBeInTheDocument();
    expect(screen.getByText('Last run:')).toBeInTheDocument();
    expect(screen.getByText('Last run status:')).toBeInTheDocument();
  });

  it('does not show schedule info when schedule is null', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.queryByText('Schedule Information')).not.toBeInTheDocument();
  });

  it('shows validation errors', () => {
    mockedUseForm
      .mockReset()
      .mockReturnValueOnce({
        ...scheduleFormReturn,
        data: { enabled: true, frequency: 'weekly' },
        errors: { frequency: 'The selected frequency is invalid.' },
      } as unknown as ReturnType<typeof useForm>)
      .mockReturnValue(automationFormReturn as unknown as ReturnType<typeof useForm>);

    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('The selected frequency is invalid.')).toBeInTheDocument();
  });

  it('initializes form with existing schedule data', () => {
    const schedule = {
      id: 1,
      site_id: 1,
      frequency: 'daily',
      next_run_at: null,
      last_run_at: null,
      last_run_status: null,
      enabled: true,
    };

    render(<SiteSettings site={defaultSite} schedule={schedule} automation={defaultAutomation} />);

    expect(useForm).toHaveBeenCalledWith({
      enabled: true,
      frequency: 'daily',
    });
  });

  it('renders automation section heading', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('Automation')).toBeInTheDocument();
  });

  it('renders auto-analyze after sync switch', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('Auto-analyze after GSC sync')).toBeInTheDocument();
  });

  it('renders auto-generate drafts switch', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('Auto-generate content drafts')).toBeInTheDocument();
  });

  it('renders save automation settings button', () => {
    render(<SiteSettings site={defaultSite} schedule={null} automation={defaultAutomation} />);

    expect(screen.getByText('Save Automation Settings')).toBeInTheDocument();
  });
});
