import type {SearchMessageMatchItem} from '@modules/chats/interfaces';

import {mapSearchMessageMatchesFromServer} from '../mappers/messageMapper';

const makeMatchItem = (ts: string, text: string): SearchMessageMatchItem => ({
  type: 'message',
  item: {
    hu_data: {
      message_ts: ts,
    },
    text,
  },
});

describe('mapSearchMessageMatchesFromServer', () => {
  it('returns empty array for empty input', () => {
    expect(mapSearchMessageMatchesFromServer([], 'test')).toEqual([]);
  });

  it('returns viewPosition 0.5 when query is not found in text', () => {
    const result = mapSearchMessageMatchesFromServer(
      [makeMatchItem('ts1', 'Hello world')],
      'notfound',
    );
    expect(result[0].viewPosition).toBe(0.5);
  });

  it('returns viewPosition 0 when query is at the very start of text', () => {
    // lastIndexOf('test') = 0 → 0 / 12 = 0.0
    const result = mapSearchMessageMatchesFromServer(
      [makeMatchItem('ts1', 'test message')],
      'test',
    );
    expect(result[0].viewPosition).toBe(0);
  });

  it('calculates viewPosition as lastIndex / textLength', () => {
    // 'XXXXXXXXXX' length=10, lastIndexOf('X') = 9 → 9/10 = 0.9
    const result = mapSearchMessageMatchesFromServer(
      [makeMatchItem('ts1', 'XXXXXXXXXX')],
      'X',
    );
    expect(result[0].viewPosition).toBe(0.9);
  });

  it('uses the last occurrence when query appears multiple times', () => {
    // 'abcabc' length=6, lastIndexOf('abc') = 3 → 3/6 = 0.5
    const result = mapSearchMessageMatchesFromServer(
      [makeMatchItem('ts1', 'abcabc')],
      'abc',
    );
    expect(result[0].viewPosition).toBe(0.5);
  });

  it('rounds viewPosition to one decimal place', () => {
    // 'abc' length=3, lastIndexOf('c') = 2 → 2/3 ≈ 0.667 → toFixed(1) → 0.7
    const result = mapSearchMessageMatchesFromServer(
      [makeMatchItem('ts1', 'abc')],
      'c',
    );
    expect(result[0].viewPosition).toBe(0.7);
  });

  it('keeps viewPosition within [0, 1] range', () => {
    const result = mapSearchMessageMatchesFromServer(
      [makeMatchItem('ts1', 'aX')],
      'X',
    );
    expect(result[0].viewPosition).toBeGreaterThanOrEqual(0);
    expect(result[0].viewPosition).toBeLessThanOrEqual(1);
  });

  it('maps ts from each item', () => {
    const result = mapSearchMessageMatchesFromServer(
      [makeMatchItem('1234567890.123456', 'some text')],
      'notfound',
    );
    expect(result[0].ts).toBe('1234567890.123456');
  });

  it('maps multiple items independently', () => {
    const items = [
      makeMatchItem('ts1', 'test message'), // lastIndexOf('test') = 0 → 0.0
      makeMatchItem('ts2', 'no result'), // query not found → 0.5
      makeMatchItem('ts3', 'XXXXXXXXXX'), // query not found → 0.5
    ];
    const result = mapSearchMessageMatchesFromServer(items, 'test');
    expect(result).toEqual([
      {ts: 'ts1', viewPosition: 0},
      {ts: 'ts2', viewPosition: 0.5},
      {ts: 'ts3', viewPosition: 0.5},
    ]);
  });
});
