import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { PackageCard } from './PackageCard';
import type { PackageWithStatus } from '../types/package';

const basePackage: PackageWithStatus = {
  slug: 'mailchimp',
  name: 'Mailchimp',
  description: 'Email marketing automation',
  category: 'Email Marketing',
  version: '1.0.0',
  author: 'Sequensy',
  minimum_license_tier: 'starter',
  status: 'installed',
  is_active: false,
  is_pro: false,
};

describe('PackageCard', () => {
  it('renders package name and description', () => {
    render(<PackageCard package={basePackage} />);
    expect(screen.getByText('Mailchimp')).toBeInTheDocument();
    expect(screen.getByText('Email marketing automation')).toBeInTheDocument();
  });

  it('shows Activate button for installed inactive package', () => {
    render(<PackageCard package={{ ...basePackage, status: 'installed', is_active: false }} />);
    expect(screen.getByRole('button', { name: /Activate/i })).toBeInTheDocument();
  });

  it('shows Deactivate button for active package', () => {
    render(<PackageCard package={{ ...basePackage, status: 'installed', is_active: true }} />);
    expect(screen.getByRole('button', { name: /Deactivate/i })).toBeInTheDocument();
  });

  it('shows Install button for not_installed when showInstall=true', () => {
    render(
      <PackageCard
        package={{ ...basePackage, status: 'not_installed', is_active: false }}
        showInstall={true}
      />,
    );
    expect(screen.getByRole('button', { name: /Install/i })).toBeInTheDocument();
  });

  it('does NOT show Install button when showInstall=false', () => {
    render(
      <PackageCard
        package={{ ...basePackage, status: 'not_installed', is_active: false }}
        showInstall={false}
      />,
    );
    expect(screen.queryByRole('button', { name: /Install/i })).not.toBeInTheDocument();
  });

  it('shows Update button for update_available status', () => {
    render(
      <PackageCard package={{ ...basePackage, status: 'update_available', is_active: true }} />,
    );
    expect(screen.getByRole('button', { name: /Update/i })).toBeInTheDocument();
  });

  it('calls onActivate with slug when clicked', () => {
    const onActivate = vi.fn();
    render(
      <PackageCard
        package={{ ...basePackage, status: 'installed', is_active: false }}
        onActivate={onActivate}
      />,
    );
    fireEvent.click(screen.getByRole('button', { name: /Activate/i }));
    expect(onActivate).toHaveBeenCalledWith('mailchimp');
  });

  it('calls onDeactivate with slug when clicked', () => {
    const onDeactivate = vi.fn();
    render(
      <PackageCard
        package={{ ...basePackage, status: 'installed', is_active: true }}
        onDeactivate={onDeactivate}
      />,
    );
    fireEvent.click(screen.getByRole('button', { name: /Deactivate/i }));
    expect(onDeactivate).toHaveBeenCalledWith('mailchimp');
  });

  it('shows category badge', () => {
    render(<PackageCard package={basePackage} />);
    expect(screen.getByText('Email Marketing')).toBeInTheDocument();
  });

  it('disables buttons when actionInProgress matches slug', () => {
    render(
      <PackageCard
        package={{ ...basePackage, status: 'installed', is_active: false }}
        actionInProgress="mailchimp"
      />,
    );
    expect(screen.getByRole('button', { name: /Activate/i })).toBeDisabled();
  });

  it('disables Install when installDisabled=true', () => {
    render(
      <PackageCard
        package={{ ...basePackage, status: 'not_installed', is_active: false }}
        showInstall={true}
        installDisabled={true}
        installDisabledReason="Activate your license to install packages"
      />,
    );
    expect(screen.getByRole('button', { name: /Install/i })).toBeDisabled();
  });

  it('calls onInstall with slug when Install is clicked', () => {
    const onInstall = vi.fn();
    render(
      <PackageCard
        package={{ ...basePackage, status: 'not_installed', is_active: false }}
        showInstall={true}
        onInstall={onInstall}
      />,
    );
    fireEvent.click(screen.getByRole('button', { name: /Install/i }));
    expect(onInstall).toHaveBeenCalledWith('mailchimp');
  });

  it('calls onUpdate with slug when Update is clicked', () => {
    const onUpdate = vi.fn();
    render(
      <PackageCard
        package={{ ...basePackage, status: 'update_available', is_active: true }}
        onUpdate={onUpdate}
      />,
    );
    fireEvent.click(screen.getByRole('button', { name: /Update/i }));
    expect(onUpdate).toHaveBeenCalledWith('mailchimp');
  });

  it('shows Active badge for active installed package', () => {
    render(<PackageCard package={{ ...basePackage, status: 'installed', is_active: true }} />);
    expect(screen.getByText('Active')).toBeInTheDocument();
  });

  it('shows Inactive badge for inactive installed package', () => {
    render(<PackageCard package={{ ...basePackage, status: 'installed', is_active: false }} />);
    expect(screen.getByText('Inactive')).toBeInTheDocument();
  });

  it('does not show status badge for not_installed package', () => {
    render(
      <PackageCard package={{ ...basePackage, status: 'not_installed', is_active: false }} />,
    );
    expect(screen.queryByText('Active')).not.toBeInTheDocument();
    expect(screen.queryByText('Inactive')).not.toBeInTheDocument();
  });

  it('shows Update Available badge for update_available status', () => {
    render(
      <PackageCard package={{ ...basePackage, status: 'update_available', is_active: true }} />,
    );
    expect(screen.getByText('Update Available')).toBeInTheDocument();
  });

  it('does not show Uninstall menu when showUninstall=false', () => {
    render(
      <PackageCard
        package={{ ...basePackage, status: 'installed', is_active: false }}
        showUninstall={false}
      />,
    );
    // The three-dot menu trigger should not be rendered
    expect(screen.queryByText('Uninstall')).not.toBeInTheDocument();
  });

  it('does not disable buttons when actionInProgress is for a different slug', () => {
    render(
      <PackageCard
        package={{ ...basePackage, status: 'installed', is_active: false }}
        actionInProgress="some-other-package"
      />,
    );
    expect(screen.getByRole('button', { name: /Activate/i })).not.toBeDisabled();
  });
});
