import { describe, it, expect, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { http, HttpResponse } from 'msw';
import { server } from '../test/mocks/server';
import ProIntegrations from './ProIntegrations';
import type { PackageWithStatus } from '../types/package';

const PRO_BASE_URL = 'http://localhost:34821/wp-json/sequensy-pro/v1';

const mockPackages: PackageWithStatus[] = [
  {
    slug: 'mailchimp',
    name: 'Mailchimp',
    description: 'Email marketing automation',
    category: 'Email Marketing',
    version: '1.2.0',
    author: 'Sequensy',
    minimum_license_tier: 'starter',
    status: 'not_installed',
    is_active: false,
    is_pro: false,
  },
  {
    slug: 'wordpress',
    name: 'WordPress',
    description: 'Core WordPress actions and triggers',
    category: 'CMS',
    version: '1.0.0',
    author: 'Sequensy',
    minimum_license_tier: 'free',
    status: 'installed',
    is_active: true,
    is_pro: false,
  },
  {
    slug: 'hubspot',
    name: 'HubSpot',
    description: 'CRM and marketing platform',
    category: 'CRM',
    version: '2.0.0',
    author: 'Sequensy',
    minimum_license_tier: 'professional',
    status: 'update_available',
    installed_version: '1.5.0',
    is_active: true,
    is_pro: false,
  },
];

beforeEach(() => {
  // Configure Pro mode
  window.sequensyAPI = {
    ...window.sequensyAPI,
    root: 'http://localhost:9000/wp-json/sequensy/v1',
    nonce: 'test-nonce-12345',
    is_pro: true,
    proRoot: PRO_BASE_URL,
    license: { is_active: true, tier: 'pro' },
    capabilities: {
      marketplace_can_install: true,
      version_history: true,
      nested_filters: true,
      activity_log_limit: 0,
    },
  };

  // Register Pro API handlers
  server.use(
    http.get(`${PRO_BASE_URL}/packages`, () => {
      return HttpResponse.json(mockPackages);
    }),
    http.post(`${PRO_BASE_URL}/packages/check-updates`, () => {
      return HttpResponse.json({ success: true, updates: [] });
    }),
  );
});

describe('ProIntegrations', () => {
  it('renders all packages from marketplace API', async () => {
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    expect(screen.getByRole('heading', { name: 'Mailchimp' })).toBeInTheDocument();
    expect(screen.getByRole('heading', { name: 'WordPress' })).toBeInTheDocument();
    expect(screen.getByRole('heading', { name: 'HubSpot' })).toBeInTheDocument();
  });

  it('shows Install button for not_installed packages', async () => {
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    // Mailchimp is not_installed, so Install should be visible
    expect(screen.getByRole('button', { name: /Install/i })).toBeInTheDocument();
  });

  it('shows status filter chips (Installed, Active, Updates Available)', async () => {
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    // Status filter chips are rendered as radio buttons inside ToggleGroup.
    // The status "All" chip includes a count badge so its accessible name is "All 3".
    // The category "All" chip has no count so its name is just "All".
    expect(screen.getByRole('radio', { name: /^All 3$/ })).toBeInTheDocument();
    expect(screen.getByRole('radio', { name: /^Installed/ })).toBeInTheDocument();
    expect(screen.getByRole('radio', { name: /^Active/ })).toBeInTheDocument();
    expect(screen.getByRole('radio', { name: /^Updates Available/ })).toBeInTheDocument();
  });

  it('filters by status chip - clicking Installed hides not_installed packages', async () => {
    const user = userEvent.setup();
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    // Click "Installed" status chip
    const installedChip = screen.getByRole('radio', { name: /Installed/i });
    await user.click(installedChip);

    // Should show only installed packages (WordPress and HubSpot), not Mailchimp
    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(2);
    });

    expect(screen.getByRole('heading', { name: 'WordPress' })).toBeInTheDocument();
    expect(screen.getByRole('heading', { name: 'HubSpot' })).toBeInTheDocument();
    expect(screen.queryByRole('heading', { name: 'Mailchimp' })).not.toBeInTheDocument();
  });

  it('shows Update button for update_available packages', async () => {
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    // HubSpot has update_available status
    expect(screen.getByRole('button', { name: /Update/i })).toBeInTheDocument();
  });

  it('disables Install when license is inactive', async () => {
    // Override license to inactive
    window.sequensyAPI = {
      ...window.sequensyAPI,
      license: { is_active: false, tier: 'free' },
    };

    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    const installButton = screen.getByRole('button', { name: /Install/i });
    expect(installButton).toBeDisabled();
  });

  it('shows search input prominently', async () => {
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    const searchInput = screen.getByPlaceholderText('Search packages...');
    expect(searchInput).toBeInTheDocument();
    expect(searchInput).toBeVisible();
  });

  it('filters packages by search query', async () => {
    const user = userEvent.setup();
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    const searchInput = screen.getByPlaceholderText('Search packages...');
    await user.type(searchInput, 'hubspot');

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(1);
    });

    expect(screen.getByRole('heading', { name: 'HubSpot' })).toBeInTheDocument();
    expect(screen.queryByRole('heading', { name: 'WordPress' })).not.toBeInTheDocument();
    expect(screen.queryByRole('heading', { name: 'Mailchimp' })).not.toBeInTheDocument();
  });

  it('filters packages by category', async () => {
    const user = userEvent.setup();
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    // Click on the "CRM" category chip
    const crmChip = screen.getByRole('radio', { name: 'CRM' });
    await user.click(crmChip);

    // Only HubSpot should be visible
    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(1);
    });

    expect(screen.getByRole('heading', { name: 'HubSpot' })).toBeInTheDocument();
  });

  it('shows loading spinner initially', () => {
    render(<ProIntegrations />);
    const spinner = document.querySelector('.animate-spin');
    expect(spinner).toBeInTheDocument();
  });

  it('shows error message on API failure', async () => {
    server.use(
      http.get(`${PRO_BASE_URL}/packages`, () => {
        return HttpResponse.json(
          { code: 'internal_error', message: 'Something went wrong' },
          { status: 500 },
        );
      }),
    );

    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getByText('Error')).toBeInTheDocument();
    });
  });

  it('shows empty state when no packages match filters', async () => {
    const user = userEvent.setup();
    render(<ProIntegrations />);

    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    const searchInput = screen.getByPlaceholderText('Search packages...');
    await user.type(searchInput, 'nonexistent-package-xyz');

    await waitFor(() => {
      expect(screen.queryByTestId('package-card')).not.toBeInTheDocument();
    });

    expect(screen.getByText('No packages found')).toBeInTheDocument();
    expect(screen.getByText('Try adjusting your search or filters')).toBeInTheDocument();
  });
});
