/**
 * RecoverHub — DUX-EOU-02 tests
 *
 * Assertions:
 *  (a) Primary cells "Action queue" and "Recommendations" are visible by default.
 *  (b) A deeper-analysis cell (e.g. "Topic clusters") is NOT visible until disclosure is expanded.
 *  (c) After clicking the disclosure button the secondary cell appears.
 *  (d) "Start Recovery Run" remains the single header CTA.
 *
 * Run with: npx vitest run resources/js/Pages/Sites/RecoverHub.test.tsx
 */
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { beforeEach, describe, expect, it, vi } from 'vitest';

import React from 'react';

import RecoverHub from './RecoverHub';

// ---------------------------------------------------------------------------
// Mock heavy layout and analytics deps (same pattern as ContentHub.test.tsx)
// ---------------------------------------------------------------------------

vi.mock('@/Layouts/DashboardLayout', () => ({
  default: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
}));

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    Link: ({
      href,
      children,
      ...rest
    }: {
      href: string;
      children: React.ReactNode;
      [key: string]: unknown;
    }) => (
      <a href={href} {...rest}>
        {children}
      </a>
    ),
  };
});

vi.mock('@/lib/analytics', () => ({
  trackProductEvent: vi.fn(),
}));

// ---------------------------------------------------------------------------
// Minimal prop factories
// ---------------------------------------------------------------------------

const baseSite = {
  id: '1',
  name: 'Test Site',
  domain: 'example.com',
  has_gsc: true,
  has_analysis: true,
};

const baseCounts = {
  pending_recommendations: 5,
  keyword_opportunities: 3,
  topic_clusters: 2,
  cannibalization_cases: 1,
  link_opportunities: 4,
  draftable_recommendations_count: 7,
  freshness_recommendations: 6,
  inventory: 20,
  briefs: 3,
  drafts_in_flight: 1,
};

beforeEach(() => {
  vi.stubGlobal('route', (name: string, params?: number) =>
    params !== undefined ? `/${name}/${params}` : `/${name}`,
  );
});

// ---------------------------------------------------------------------------
// DUX-EOU-02 feature tests
// ---------------------------------------------------------------------------

describe('RecoverHub — DUX-EOU-02 primary/secondary cell split', () => {
  it('(a) primary cells "Action queue" and "Recommendations" are visible by default', () => {
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    expect(screen.getByText('Action queue')).toBeInTheDocument();
    expect(screen.getByText('Recommendations')).toBeInTheDocument();
  });

  it('(a) exactly 2 cells visible before the disclosure toggle is expanded', () => {
    // DUX-EOU-02: the primary grid must contain exactly 2 cells by default (not "at least 2").
    // This guards against primary-cell list drift — if a new key is accidentally added to
    // PRIMARY_KEYS, this test catches it before the disclosure toggle contract breaks.
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    const grid = screen.getByTestId('hub-cell-grid');
    expect(grid.children).toHaveLength(2);
  });

  it('(b) "Topic clusters" is NOT visible before the disclosure is expanded', () => {
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    expect(screen.queryByText('Topic clusters')).not.toBeInTheDocument();
  });

  it('(b) "Link opportunities" is NOT visible before the disclosure is expanded', () => {
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    expect(screen.queryByText('Link opportunities')).not.toBeInTheDocument();
  });

  it('(c) after clicking the disclosure button the secondary cell "Topic clusters" appears', async () => {
    const user = userEvent.setup();
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    // Find and click the "More tools" / "Deeper analysis" toggle
    const toggle = screen.getByRole('button', { name: /more tools|deeper analysis/i });
    await user.click(toggle);

    expect(screen.getByText('Topic clusters')).toBeInTheDocument();
  });

  it('(c) after clicking the disclosure button "Link opportunities" also appears', async () => {
    const user = userEvent.setup();
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    const toggle = screen.getByRole('button', { name: /more tools|deeper analysis/i });
    await user.click(toggle);

    expect(screen.getByText('Link opportunities')).toBeInTheDocument();
  });

  it('(d) "Start Recovery Run" CTA is present in the header', () => {
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    expect(screen.getByRole('link', { name: /start recovery run/i })).toBeInTheDocument();
  });

  it('disclosure toggle has aria-expanded=false by default', () => {
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    const toggle = screen.getByRole('button', { name: /more tools|deeper analysis/i });
    expect(toggle).toHaveAttribute('aria-expanded', 'false');
  });

  it('disclosure toggle becomes aria-expanded=true after clicking', async () => {
    const user = userEvent.setup();
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    const toggle = screen.getByRole('button', { name: /more tools|deeper analysis/i });
    await user.click(toggle);

    // After clicking, label changes to "Hide tools" — query by the expanded label
    expect(screen.getByRole('button', { name: /hide tools|hide deeper analysis/i })).toHaveAttribute(
      'aria-expanded',
      'true',
    );
  });

  it('primary cells remain visible after expanding the disclosure', async () => {
    const user = userEvent.setup();
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    const toggle = screen.getByRole('button', { name: /more tools|deeper analysis/i });
    await user.click(toggle);

    // Primary cells must still be present after expand
    expect(screen.getByText('Action queue')).toBeInTheDocument();
    expect(screen.getByText('Recommendations')).toBeInTheDocument();
  });
});

describe('RecoverHub — DUX-EOU-02 gating preserved in primary cells', () => {
  it('gated primary cells (has_analysis=false) still show without bypass', () => {
    const gatedSite = { ...baseSite, has_analysis: false };
    render(<RecoverHub site={gatedSite} counts={baseCounts} />);

    // Primary cells rendered but gated (locked, not linked)
    expect(screen.getByText('Action queue')).toBeInTheDocument();
    expect(screen.getByText('Recommendations')).toBeInTheDocument();
  });
});

describe('RecoverHub — DUX-EOU-02 hub-cell-grid testid preserved', () => {
  it('the primary grid container still has data-testid="hub-cell-grid"', () => {
    render(<RecoverHub site={baseSite} counts={baseCounts} />);

    expect(screen.getByTestId('hub-cell-grid')).toBeInTheDocument();
  });
});
