/**
 * d401cfe1 — secondary-surfaces-wire: ReportTemplates run/edit/delete tests
 *
 * Covers:
 *  - Each user-owned template row exposes Run, Edit, Delete buttons
 *  - System templates expose only the Run button (no edit/delete)
 *  - Failed delete surfaces hook.error inside an open dialog
 *  - Edit dialog opens pre-filled with template data
 */
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, it, expect, vi, beforeEach } from 'vitest';

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: () => ({
      props: {
        auth: { user: null },
        errors: {},
        flash: {},
        polling_interval_ms: 5000,
        // No sites — RunReportButton should show a disabled button
        sites: [],
      },
    }),
    router: {
      visit: vi.fn(),
      delete: vi.fn(),
      patch: vi.fn(),
      post: vi.fn(),
    },
  };
});

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

vi.mock('@/Components/ui/empty-state', () => ({
  EmptyState: ({
    title,
    primaryAction,
  }: {
    title: string;
    primaryAction?: { label: string; onClick?: () => void };
  }) => (
    <div data-testid="empty-state">
      <h3>{title}</h3>
      {primaryAction && (
        <button onClick={primaryAction.onClick}>{primaryAction.label}</button>
      )}
    </div>
  ),
}));

import ReportTemplatesIndex from './Index';

const userTemplate = {
  id: '01jxabc1234567890123456789',
  name: 'My Custom Template',
  description: 'Test description',
  sections: ['traffic_overview', 'top_pages'],
  filters: {},
  is_system: false,
  created_at: '2026-01-01T00:00:00Z',
};

const systemTemplate = {
  id: '01jxsystem0000000000000001',
  name: 'System Default',
  description: null,
  sections: ['traffic_overview'],
  filters: {},
  is_system: true,
  created_at: '2026-01-01T00:00:00Z',
};

const baseProps = {
  filters: {},
  counts: { total: 1, system: 0, user: 1 },
  pagination: { current_page: 1, last_page: 1, per_page: 20, total: 1, links: [] },
};

/** Minimal Inertia visit-options type for mock assertions. */
type InertiaOpts = {
  onError?: (errors: Record<string, string>) => void;
  onSuccess?: () => void;
  onFinish?: () => void;
  [key: string]: unknown;
};

describe('ReportTemplates/Index — d401cfe1 run/edit/delete', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.stubGlobal('route', vi.fn((name: string, params?: string | number) => {
      if (params !== undefined) return `/mock/${name}/${params}`;
      return `/mock/${name}`;
    }));
  });

  // ── Row action buttons ──────────────────────────────────────────────────────

  it('user-owned row exposes Run, Edit, and Delete buttons', () => {
    render(<ReportTemplatesIndex {...baseProps} templates={[userTemplate]} />);

    // Run is always visible (disabled when no sites)
    expect(screen.getByRole('button', { name: /Run report for My Custom Template/i })).toBeInTheDocument();
    // Edit and Delete only for non-system templates
    expect(screen.getByRole('button', { name: /Edit My Custom Template/i })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: /Delete My Custom Template/i })).toBeInTheDocument();
  });

  it('system template row exposes Run but NOT Edit or Delete buttons', () => {
    render(<ReportTemplatesIndex {...baseProps} templates={[systemTemplate]} />);

    expect(screen.getByRole('button', { name: /Run report for System Default/i })).toBeInTheDocument();
    expect(screen.queryByRole('button', { name: /Edit System Default/i })).not.toBeInTheDocument();
    expect(screen.queryByRole('button', { name: /Delete System Default/i })).not.toBeInTheDocument();
  });

  it('Run button is disabled when sites list is empty', () => {
    render(<ReportTemplatesIndex {...baseProps} templates={[userTemplate]} />);
    const runBtn = screen.getByRole('button', { name: /Run report for My Custom Template/i });
    expect(runBtn).toBeDisabled();
  });

  // ── Edit dialog ─────────────────────────────────────────────────────────────

  it('Edit button opens a dialog pre-filled with template name', async () => {
    const user = userEvent.setup();
    render(<ReportTemplatesIndex {...baseProps} templates={[userTemplate]} />);

    await user.click(screen.getByRole('button', { name: /Edit My Custom Template/i }));

    // Dialog should be open
    expect(screen.getByRole('dialog')).toBeInTheDocument();
    // Name input pre-filled
    const nameInput = screen.getByLabelText(/^Name/i);
    expect(nameInput).toHaveValue('My Custom Template');
  });

  it('Edit dialog Cancel closes the dialog', async () => {
    const user = userEvent.setup();
    render(<ReportTemplatesIndex {...baseProps} templates={[userTemplate]} />);

    await user.click(screen.getByRole('button', { name: /Edit My Custom Template/i }));
    expect(screen.getByRole('dialog')).toBeInTheDocument();

    await user.click(screen.getByRole('button', { name: /^Cancel$/i }));

    await waitFor(() => {
      expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
    });
  });

  // ── Delete dialog + useMutationButton error path ────────────────────────────

  it('Delete button opens a delete confirm dialog', async () => {
    const user = userEvent.setup();
    render(<ReportTemplatesIndex {...baseProps} templates={[userTemplate]} />);

    await user.click(screen.getByRole('button', { name: /Delete My Custom Template/i }));

    const dialog = screen.getByRole('dialog');
    expect(dialog).toBeInTheDocument();
    // The dialog's description paragraph includes the template name
    expect(dialog).toHaveTextContent(/Are you sure you want to delete/i);
    expect(dialog).toHaveTextContent('My Custom Template');
  });

  it('failed delete surfaces hook.error inside an open dialog', async () => {
    const user = userEvent.setup();
    const { router } = await import('@inertiajs/react');

    // Simulate router.delete calling onError with a server error
    vi.mocked(router.delete).mockImplementation((_url, options) => {
      (options as InertiaOpts).onError?.({ message: 'Cannot delete template in use' });
      (options as InertiaOpts).onFinish?.();
    });

    render(<ReportTemplatesIndex {...baseProps} templates={[userTemplate]} />);

    // Open delete dialog
    await user.click(screen.getByRole('button', { name: /Delete My Custom Template/i }));

    // Click the Delete confirm button
    const deleteConfirmBtn = screen.getByRole('button', { name: /^Delete$/i });
    await user.click(deleteConfirmBtn);

    // Dialog should stay open AND show the error
    await waitFor(() => {
      expect(screen.getByRole('alert')).toBeInTheDocument();
      expect(screen.getByRole('alert')).toHaveTextContent('Cannot delete template in use');
    });

    // Dialog is still open
    expect(screen.getByRole('dialog')).toBeInTheDocument();
  });

  it('successful delete closes the dialog', async () => {
    const user = userEvent.setup();
    const { router } = await import('@inertiajs/react');

    vi.mocked(router.delete).mockImplementation((_url, options) => {
      (options as InertiaOpts).onSuccess?.();
      (options as InertiaOpts).onFinish?.();
    });

    render(<ReportTemplatesIndex {...baseProps} templates={[userTemplate]} />);

    await user.click(screen.getByRole('button', { name: /Delete My Custom Template/i }));
    await user.click(screen.getByRole('button', { name: /^Delete$/i }));

    await waitFor(() => {
      expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
    });
  });

  it('delete Cancel button closes dialog without calling router.delete', async () => {
    const user = userEvent.setup();
    const { router } = await import('@inertiajs/react');

    render(<ReportTemplatesIndex {...baseProps} templates={[userTemplate]} />);

    await user.click(screen.getByRole('button', { name: /Delete My Custom Template/i }));
    await user.click(screen.getByRole('button', { name: /^Cancel$/i }));

    await waitFor(() => {
      expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
    });
    expect(router.delete).not.toHaveBeenCalled();
  });
});
