import { describe, it, expect } from 'vitest';
import {
  getVisibleSections,
  getAvailableActions,
  pickSmartDefault,
  MAX_VISIBLE_ITEMS,
  MAX_VISIBLE_LIST,
} from './client.js';
import type { ProgressiveSection, QuickAction, SmartDefault } from './types.js';

describe('getVisibleSections', () => {
  const sections: ProgressiveSection[] = [
    { id: 'main', title: 'Main', defaultExpanded: true, priority: 'primary' },
    { id: 'stats', title: 'Stats', defaultExpanded: false, priority: 'secondary' },
    { id: 'details', title: 'Details', defaultExpanded: false, priority: 'detail' },
    { id: 'advanced', title: 'Advanced', defaultExpanded: false, priority: 'primary' },
  ];

  it('should show primary and defaultExpanded sections', () => {
    const visible = getVisibleSections(sections, new Set());
    expect(visible.map(s => s.id)).toEqual(['main', 'advanced']);
  });

  it('should include explicitly expanded sections', () => {
    const visible = getVisibleSections(sections, new Set(['stats']));
    expect(visible.map(s => s.id)).toEqual(['main', 'stats', 'advanced']);
  });

  it('should return empty for no sections', () => {
    expect(getVisibleSections([], new Set())).toHaveLength(0);
  });
});

describe('getAvailableActions', () => {
  const actions: QuickAction[] = [
    {
      id: 'start',
      label: 'Start',
      icon: 'play',
      shortLabel: 'Start',
      action: 'start',
      requiresAuth: false,
    },
    {
      id: 'share',
      label: 'Share',
      icon: 'share',
      shortLabel: 'Share',
      action: 'share',
      requiresAuth: true,
    },
    {
      id: 'stop',
      label: 'Stop',
      icon: 'stop',
      shortLabel: 'Stop',
      action: 'stop',
      requiresAuth: false,
    },
  ];

  it('should filter out auth-required actions when not authenticated', () => {
    const available = getAvailableActions(actions, { isAuthenticated: false });
    expect(available.map(a => a.id)).toEqual(['start', 'stop']);
  });

  it('should include all when authenticated', () => {
    const available = getAvailableActions(actions, { isAuthenticated: true });
    expect(available).toHaveLength(3);
  });

  it('should include non-auth actions by default', () => {
    const available = getAvailableActions(actions, {});
    expect(available.map(a => a.id)).toEqual(['start', 'stop']);
  });
});

describe('pickSmartDefault', () => {
  it('should prefer last_used over others', () => {
    const candidates: SmartDefault[] = [
      { key: 'protocol', value: 'OMAD', source: 'most_common' },
      { key: 'protocol', value: '16:8', source: 'last_used' },
      { key: 'protocol', value: '18:6', source: 'recommendation' },
    ];
    const result = pickSmartDefault(candidates);
    expect(result?.value).toBe('16:8');
  });

  it('should fall back to most_common', () => {
    const candidates: SmartDefault[] = [
      { key: 'protocol', value: 'OMAD', source: 'most_common' },
      { key: 'protocol', value: '18:6', source: 'system' },
    ];
    const result = pickSmartDefault(candidates);
    expect(result?.value).toBe('OMAD');
  });

  it('should return null for empty array', () => {
    expect(pickSmartDefault([])).toBeNull();
  });

  it('should return first if no priority match', () => {
    const candidates: SmartDefault[] = [{ key: 'x', value: 'a', source: 'system' }];
    const result = pickSmartDefault(candidates);
    expect(result?.value).toBe('a');
  });
});

describe('constants', () => {
  it('should export MAX_VISIBLE_ITEMS', () => {
    expect(MAX_VISIBLE_ITEMS).toBe(3);
  });

  it('should export MAX_VISIBLE_LIST', () => {
    expect(MAX_VISIBLE_LIST).toBe(5);
  });
});
