import { describe, it, expect, vi, afterEach } from 'vitest';
import { render, screen, fireEvent, cleanup } from '@testing-library/react';

afterEach(() => {
  cleanup();
});
import userEvent from '@testing-library/user-event';
import {
  InteractiveRegionsMap,
  MapLegend,
  MapTooltip,
  MapResetButton,
  MapZoomControls,
} from '../src/components/interactive-regions-map/index.js';

// Minimal region fixture
const REGIONS = [
  { countries: ['us', 'ca'], name: 'North America', color: '#3b82f6' },
  { countries: ['fr', 'de'], name: 'Europe', color: '#10b981' },
];

describe('InteractiveRegionsMap', () => {
  it('renders the title', () => {
    render(<InteractiveRegionsMap title='My Map' regions={[]} />);
    expect(screen.getByText('My Map')).toBeDefined();
  });

  it('renders optional content text', () => {
    render(
      <InteractiveRegionsMap
        title='My Map'
        content='Some description'
        regions={[]}
      />
    );
    expect(screen.getByText('Some description')).toBeDefined();
  });

  it('does not render content paragraph when content prop is absent', () => {
    render(<InteractiveRegionsMap title='My Map' regions={[]} />);
    expect(screen.queryByRole('paragraph')).toBeNull();
  });

  it('renders an SVG with aria-label', () => {
    render(<InteractiveRegionsMap title='Map' regions={[]} />);
    expect(screen.getByLabelText('Interactive world map')).toBeDefined();
  });

  it('calls onRegionClick when an interactive country is clicked', () => {
    const onRegionClick = vi.fn();
    render(
      <InteractiveRegionsMap
        title='Map'
        regions={REGIONS}
        onRegionClick={onRegionClick}
      />
    );
    const usPath = document.getElementById('us');
    if (usPath) {
      fireEvent.click(usPath);
      expect(onRegionClick).toHaveBeenCalledWith(REGIONS[0]);
    }
  });

  it('calls onRegionHover on mouse enter of interactive country', () => {
    const onRegionHover = vi.fn();
    render(
      <InteractiveRegionsMap
        title='Map'
        regions={REGIONS}
        onRegionHover={onRegionHover}
      />
    );
    const frPath = document.getElementById('fr');
    if (frPath) {
      fireEvent.mouseEnter(frPath, { clientX: 100, clientY: 100 });
      expect(onRegionHover).toHaveBeenCalledWith(REGIONS[1]);
    }
  });

  it('calls onRegionHover(null) on mouse leave', () => {
    const onRegionHover = vi.fn();
    render(
      <InteractiveRegionsMap
        title='Map'
        regions={REGIONS}
        onRegionHover={onRegionHover}
      />
    );
    const frPath = document.getElementById('fr');
    if (frPath) {
      fireEvent.mouseEnter(frPath, { clientX: 100, clientY: 100 });
      fireEvent.mouseLeave(frPath);
      expect(onRegionHover).toHaveBeenLastCalledWith(null);
    }
  });

  it('keyboard Enter triggers click on interactive country', () => {
    const onRegionClick = vi.fn();
    render(
      <InteractiveRegionsMap
        title='Map'
        regions={REGIONS}
        onRegionClick={onRegionClick}
      />
    );
    const usPath = document.getElementById('us');
    if (usPath) {
      fireEvent.keyDown(usPath, { key: 'Enter' });
      expect(onRegionClick).toHaveBeenCalledWith(REGIONS[0]);
    }
  });

  it('keyboard Space triggers click on interactive country', () => {
    const onRegionClick = vi.fn();
    render(
      <InteractiveRegionsMap
        title='Map'
        regions={REGIONS}
        onRegionClick={onRegionClick}
      />
    );
    const usPath = document.getElementById('us');
    if (usPath) {
      fireEvent.keyDown(usPath, { key: ' ' });
      expect(onRegionClick).toHaveBeenCalledWith(REGIONS[0]);
    }
  });

  it('renders compound children instead of defaults when children present', () => {
    render(
      <InteractiveRegionsMap title='Map' regions={REGIONS}>
        <MapZoomControls />
      </InteractiveRegionsMap>
    );
    expect(screen.getByLabelText('Zoom in')).toBeDefined();
  });

  it('renders default zoom controls when no children', () => {
    render(<InteractiveRegionsMap title='Map' regions={[]} />);
    expect(screen.getByLabelText('Zoom in')).toBeDefined();
  });
});

describe('MapLegend (compound)', () => {
  it('renders region names in legend', () => {
    render(
      <InteractiveRegionsMap title='Map' regions={REGIONS}>
        <MapLegend />
      </InteractiveRegionsMap>
    );
    // Legend is rendered in JourneySlot area (outside canvas) when children present
    // but MapLegend placed inside children renders inside canvas
    expect(screen.getByText('North America')).toBeDefined();
    expect(screen.getByText('Europe')).toBeDefined();
  });

  it('renders nothing when regions is empty', () => {
    render(
      <InteractiveRegionsMap title='Map' regions={[]}>
        <MapLegend />
      </InteractiveRegionsMap>
    );
    // No region items should appear
    expect(screen.queryByText('North America')).toBeNull();
  });
});

describe('MapTooltip (compound)', () => {
  it('is not visible initially (no tooltip shown before hover)', () => {
    // Tooltip hidden before hover — tested indirectly via hover tests above
    // The default layout renders MapTooltip which returns null when tooltip.visible=false
    render(<InteractiveRegionsMap title='Tooltip Test' regions={[]} />);
    expect(screen.queryByRole('status')).toBeNull();
  });
});

describe('MapResetButton (compound)', () => {
  it('renders with default label', () => {
    render(
      <InteractiveRegionsMap title='Map' regions={[]}>
        <MapResetButton />
      </InteractiveRegionsMap>
    );
    expect(screen.getByText('Reset View')).toBeDefined();
  });

  it('renders with custom children', () => {
    render(
      <InteractiveRegionsMap title='Map' regions={[]}>
        <MapResetButton>Back to World</MapResetButton>
      </InteractiveRegionsMap>
    );
    expect(screen.getByText('Back to World')).toBeDefined();
  });
});

describe('MapZoomControls (compound)', () => {
  it('renders zoom in and zoom out buttons', () => {
    render(
      <InteractiveRegionsMap title='Map' regions={[]}>
        <MapZoomControls />
      </InteractiveRegionsMap>
    );
    expect(screen.getByLabelText('Zoom in')).toBeDefined();
    expect(screen.getByLabelText('Zoom out')).toBeDefined();
  });
});

describe('InteractiveRegionsMap error boundary', () => {
  it('throws when MapLegend used outside provider', () => {
    expect(() => {
      render(<MapLegend />);
    }).toThrow('InteractiveRegionsMap sub-components must be used inside');
  });

  it('throws when MapTooltip used outside provider', () => {
    expect(() => {
      render(<MapTooltip />);
    }).toThrow('InteractiveRegionsMap sub-components must be used inside');
  });

  it('throws when MapResetButton used outside provider', () => {
    expect(() => {
      render(<MapResetButton />);
    }).toThrow('InteractiveRegionsMap sub-components must be used inside');
  });
});
