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

import DraftShow from './DraftShow';

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    Link: ({ children, href }: { children: React.ReactNode; href: string }) => (
      <a href={href}>{children}</a>
    ),
    usePage: vi.fn(() => ({
      props: {
        auth: { user: { name: 'Test User', email: 'test@example.com' } },
        features: { billing: false, notifications: false },
        sites: [],
        limits: null,
        ai_defaults: { model: 'gpt-4o-mini', temperature: 0.7 },
      },
    })),
    router: { reload: vi.fn() },
  };
});

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

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

vi.mock('@/Components/Recommendations/DraftPreview', () => ({
  default: ({
    originalContent,
    draftContent,
    modelUsed,
    tokens,
  }: {
    originalContent: string;
    draftContent: string;
    modelUsed: string;
    tokens: { prompt: number; completion: number };
  }) => (
    <div data-testid="draft-preview">
      <span data-testid="original-content">{originalContent}</span>
      <span data-testid="draft-content">{draftContent}</span>
      <span data-testid="model-used">{modelUsed}</span>
      <span data-testid="tokens">{tokens.prompt + tokens.completion}</span>
    </div>
  ),
}));

vi.mock('@/Components/theme/use-theme', () => ({
  useTheme: vi.fn(() => ({ theme: 'system', setTheme: vi.fn(), resolvedTheme: 'light' })),
}));

const baseSite = { id: 1, name: 'Test Site', domain: 'test.com' };

const baseDraft = {
  id: 42,
  content: '<p>This is the <strong>draft</strong> content.</p>',
  token_usage: { prompt_tokens: 500, completion_tokens: 300 },
  created_at: '2026-01-15T12:00:00Z',
  aiJob: { id: 5, model: 'gpt-4o' },
  recommendation: {
    id: 10,
    page_url: 'https://test.com/blog/seo-guide',
    title: 'Update SEO Guide',
    action_type: 'content_rewrite',
    wp_post_content: '<p>Original blog post content here.</p>',
  },
};

describe('Ai/DraftShow', () => {
  describe('page title', () => {
    it('renders page title with site name and draft id', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      expect(document.querySelector('title')).toHaveTextContent('Test Site - Draft #42');
    });
  });

  describe('navigation', () => {
    it('renders SiteNav component', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      expect(screen.getByTestId('site-nav')).toBeInTheDocument();
    });

    it('renders back to job link', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      const backLink = screen.getByRole('link', { name: /back to job/i });
      expect(backLink).toBeInTheDocument();
    });

    it('renders edit in editor button', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      const editButton = screen.getByRole('link', { name: /edit in editor/i });
      expect(editButton).toBeInTheDocument();
      expect(editButton).toHaveAttribute('href', '/sites/1/drafts/42/edit');
    });
  });

  describe('recommendation info', () => {
    it('renders recommendation title as heading', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      expect(screen.getByRole('heading', { name: 'Update SEO Guide' })).toBeInTheDocument();
    });

    it('renders recommendation page url', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      expect(screen.getByText('https://test.com/blog/seo-guide')).toBeInTheDocument();
    });

    it('renders fallback heading when no recommendation', () => {
      const draftWithoutRec = {
        ...baseDraft,
        recommendation: null,
      };

      render(<DraftShow site={baseSite} draft={draftWithoutRec} />);

      expect(screen.getByRole('heading', { name: 'Draft #42' })).toBeInTheDocument();
    });

    it('does not render page url when no recommendation', () => {
      const draftWithoutRec = {
        ...baseDraft,
        recommendation: null,
      };

      render(<DraftShow site={baseSite} draft={draftWithoutRec} />);

      expect(screen.queryByText('https://test.com/blog/seo-guide')).not.toBeInTheDocument();
    });
  });

  describe('DraftPreview with original content', () => {
    it('renders DraftPreview when original content exists', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      const preview = screen.getByTestId('draft-preview');
      expect(preview).toBeInTheDocument();
    });

    it('passes original content to DraftPreview', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      expect(screen.getByTestId('original-content')).toHaveTextContent(
        '<p>Original blog post content here.</p>',
      );
    });

    it('passes draft content to DraftPreview', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      expect(screen.getByTestId('draft-content')).toHaveTextContent(
        '<p>This is the <strong>draft</strong> content.</p>',
      );
    });

    it('passes model name to DraftPreview', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      expect(screen.getByTestId('model-used')).toHaveTextContent('gpt-4o');
    });

    it('passes token usage to DraftPreview', () => {
      render(<DraftShow site={baseSite} draft={baseDraft} />);

      expect(screen.getByTestId('tokens')).toHaveTextContent('800');
    });
  });

  describe('fallback draft display without original content', () => {
    const draftWithoutOriginal = {
      ...baseDraft,
      recommendation: {
        ...baseDraft.recommendation,
        wp_post_content: null,
      },
    };

    it('renders inline draft content when no original content', () => {
      render(<DraftShow site={baseSite} draft={draftWithoutOriginal} />);

      expect(screen.queryByTestId('draft-preview')).not.toBeInTheDocument();
      expect(screen.getByText('AI Draft')).toBeInTheDocument();
    });

    it('sanitizes HTML content with DOMPurify', () => {
      const draftWithScript = {
        ...draftWithoutOriginal,
        content: '<p>Safe content</p><script>alert("xss")</script>',
      };

      render(<DraftShow site={baseSite} draft={draftWithScript} />);

      expect(screen.getByText('Safe content')).toBeInTheDocument();
      expect(screen.queryByText('alert("xss")')).not.toBeInTheDocument();
    });

    it('renders token count and model when token usage exists', () => {
      render(<DraftShow site={baseSite} draft={draftWithoutOriginal} />);

      const tokenParagraph = screen.getByText((_content, element) => {
        return (
          element?.tagName === 'P' &&
          !!element.textContent?.includes('800') &&
          !!element.textContent?.includes('gpt-4o')
        );
      });
      expect(tokenParagraph).toBeInTheDocument();
    });

    it('does not render token info when token usage is null', () => {
      const draftNoTokens = {
        ...draftWithoutOriginal,
        token_usage: null,
      };

      render(<DraftShow site={baseSite} draft={draftNoTokens} />);

      expect(screen.queryByText(/tokens/)).not.toBeInTheDocument();
    });
  });

  describe('fallback draft display without recommendation', () => {
    const draftWithoutRec = {
      ...baseDraft,
      recommendation: null,
    };

    it('renders inline draft content when no recommendation', () => {
      render(<DraftShow site={baseSite} draft={draftWithoutRec} />);

      expect(screen.queryByTestId('draft-preview')).not.toBeInTheDocument();
      expect(screen.getByText('AI Draft')).toBeInTheDocument();
    });
  });

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