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 Integrations from './Integrations';
import type { PackageWithStatus } from '../types/package';

const BASE_URL = 'http://localhost:9000/wp-json/sequensy/v1';

const mockPackages: PackageWithStatus[] = [
  {
    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: 'mailchimp',
    name: 'Mailchimp',
    description: 'Email marketing automation',
    category: 'Email Marketing',
    version: '1.2.0',
    author: 'Sequensy',
    minimum_license_tier: 'starter',
    status: 'installed',
    is_active: false,
    is_pro: false,
  },
  {
    slug: 'slack',
    name: 'Slack',
    description: 'Team messaging and notifications',
    category: 'Communication',
    version: '1.0.0',
    author: 'Sequensy',
    minimum_license_tier: 'starter',
    status: 'installed',
    is_active: true,
    is_pro: false,
  },
];

beforeEach(() => {
  // Configure Free mode
  window.sequensyAPI = {
    ...window.sequensyAPI,
    root: BASE_URL,
    nonce: 'test-nonce-12345',
    is_pro: false,
    proRoot: undefined,
    capabilities: {
      marketplace_can_install: false,
      version_history: false,
      nested_filters: false,
      activity_log_limit: 50,
    },
  };

  // Register packages handler
  server.use(
    http.get(`${BASE_URL}/packages`, () => {
      return HttpResponse.json(mockPackages);
    }),
  );
});

describe('Integrations (Free)', () => {
  it('renders package cards from API', async () => {
    render(<Integrations />);

    // Wait for package cards to appear (use testid set by PackageCard)
    await waitFor(() => {
      expect(screen.getAllByTestId('package-card')).toHaveLength(3);
    });

    // Verify package names appear as headings
    expect(screen.getByRole('heading', { name: 'WordPress' })).toBeInTheDocument();
    expect(screen.getByRole('heading', { name: 'Mailchimp' })).toBeInTheDocument();
    expect(screen.getByRole('heading', { name: 'Slack' })).toBeInTheDocument();
  });

  it('does not show Pro upsell banner', async () => {
    render(<Integrations />);

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

    // No marketplace slot div
    expect(document.getElementById('sequensy-pro-marketplace-slot')).toBeNull();
  });

  it('does not show Install button', async () => {
    // Return a package that is not_installed to verify Install is still hidden
    server.use(
      http.get(`${BASE_URL}/packages`, () => {
        return HttpResponse.json([
          {
            ...mockPackages[0],
            status: 'not_installed',
            is_active: false,
          },
        ]);
      }),
    );

    render(<Integrations />);

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

    expect(screen.queryByRole('button', { name: /Install/i })).not.toBeInTheDocument();
  });

  it('shows search and category filters', async () => {
    render(<Integrations />);

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

    // Search input
    expect(screen.getByPlaceholderText('Search packages...')).toBeInTheDocument();

    // Category chips (rendered as radio buttons inside ToggleGroup)
    expect(screen.getByRole('radio', { name: 'All' })).toBeInTheDocument();
    expect(screen.getByRole('radio', { name: 'CMS' })).toBeInTheDocument();
    expect(screen.getByRole('radio', { name: 'Email Marketing' })).toBeInTheDocument();
    expect(screen.getByRole('radio', { name: 'Communication' })).toBeInTheDocument();
  });

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

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

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

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

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

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

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

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

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

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

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

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

    render(<Integrations />);

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

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

    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();
  });

  it('does not show Uninstall option', async () => {
    render(<Integrations />);

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

    expect(screen.queryByText('Uninstall')).not.toBeInTheDocument();
  });
});
