import { describe, expect, it } from 'vitest';

import {
  buildSignLanguageCategories,
  buildSignLanguageYoutubeSearchUrl,
  filterSignLanguageItems,
  getSignLanguageProgressPercent,
  getSignLanguageVideoDurationSeconds,
  toSignLanguageCategoryFilter,
} from '@/business/sign-language/selectors';
import type { SignItem } from '@/shared/types/app';

const signs: readonly SignItem[] = [
  {
    id: 'help',
    word: 'Help',
    category: 'basic-needs',
    description: 'Help description',
    image: 'help.jpg',
    tip: 'Help tip',
    videoUrl: 'https://example.com/help-video',
    gifUrl: 'https://example.com/help.gif',
    videoSteps: [
      { step: 1, instruction: 'First', duration: 3 },
      { step: 2, instruction: 'Second', duration: 3 },
    ],
  },
  {
    id: 'calm',
    word: 'Calm',
    category: 'emotional',
    description: 'Calm description',
    image: 'calm.jpg',
    tip: 'Calm tip',
    videoUrl: 'https://example.com/calm-video',
    gifUrl: 'https://example.com/calm.gif',
    videoSteps: [
      { step: 1, instruction: 'First', duration: 4 },
    ],
  },
  {
    id: 'sit',
    word: 'Sit',
    category: 'classroom',
    description: 'Sit description',
    image: 'sit.jpg',
    tip: 'Sit tip',
    videoUrl: 'https://example.com/sit-video',
    gifUrl: 'https://example.com/sit.gif',
    videoSteps: [],
  },
];

describe('sign language selectors', () => {
  it('builds category counts from available signs', () => {
    expect(buildSignLanguageCategories(signs)).toEqual([
      { value: 'all', label: 'All Signs', count: 3 },
      { value: 'basic-needs', label: 'Basic Needs', count: 1 },
      { value: 'emotional', label: 'Emotional', count: 1 },
      { value: 'classroom', label: 'Classroom', count: 1 },
    ]);
  });

  it('filters signs by normalized search and category', () => {
    expect(filterSignLanguageItems(signs, {
      searchQuery: ' he ',
      categoryFilter: 'basic-needs',
    })).toEqual([signs[0]]);
  });

  it('returns zero progress when there are no signs', () => {
    expect(getSignLanguageProgressPercent([], new Set(['help']))).toBe(0);
  });

  it('calculates learned sign progress', () => {
    expect(getSignLanguageProgressPercent(signs, new Set(['help', 'calm']))).toBeCloseTo(66.67, 2);
  });

  it('calculates video duration from step count and first duration', () => {
    expect(getSignLanguageVideoDurationSeconds(signs[0])).toBe(6);
    expect(getSignLanguageVideoDurationSeconds(signs[2])).toBe(0);
  });

  it('normalizes unknown category filters to all', () => {
    expect(toSignLanguageCategoryFilter('emotional')).toBe('emotional');
    expect(toSignLanguageCategoryFilter('unknown')).toBe('all');
  });

  it('builds encoded YouTube search URLs', () => {
    expect(buildSignLanguageYoutubeSearchUrl('All Done')).toBe(
      'https://www.youtube.com/results?search_query=ASL%20sign%20language%20All%20Done%20tutorial',
    );
  });
});
