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

import {
  digilanderModuleAvailable,
  digilanderModuleEmpty,
  digilanderModuleFailed,
  digilanderModuleFromError,
  digilanderModuleLocked,
  digilanderModuleOk,
  digilanderSafeArrayLength,
  digilanderSummarizeModule,
} from '../../services/digilander-contract';

describe('Digilander contract helpers', () => {
  it('builds a ready module and preserves data outside summary mode', () => {
    const module = digilanderModuleOk({ items: [{ id: 'news-1' }, { id: 'news-2' }] }, 2);

    expect(module).toEqual({
      status: 'ready',
      reason: null,
      count: 2,
      data: { items: [{ id: 'news-1' }, { id: 'news-2' }] },
    });
    expect(digilanderModuleAvailable(module)).toBe(true);
    expect(digilanderSummarizeModule(module, false)).toEqual(module);
  });

  it('summarizes modules by stripping data but keeping status and count', () => {
    const module = digilanderModuleOk({ players: [{ player: 'Luka Doncic' }] }, 1);

    expect(digilanderSummarizeModule(module, true)).toEqual({
      status: 'ready',
      reason: null,
      count: 1,
      data: null,
    });
  });

  it('maps 404s to empty modules', () => {
    const error = Object.assign(new Error('No player props for this game'), { status: 404 });

    expect(digilanderModuleFromError(error, 'Player props failed')).toEqual(
      digilanderModuleEmpty('No player props for this game'),
    );
  });

  it('maps 403s to locked modules', () => {
    const error = Object.assign(new Error('Sign in to view player data'), { status: 403 });

    expect(digilanderModuleFromError(error, 'Player data failed')).toEqual(
      digilanderModuleLocked('Sign in to view player data'),
    );
  });

  it('maps unexpected errors to failed modules', () => {
    expect(digilanderModuleFromError(new Error('Market timed out'), 'Market failed')).toEqual(
      digilanderModuleFailed('Market timed out'),
    );
    expect(digilanderModuleFromError(null, 'Market failed')).toEqual(
      digilanderModuleFailed('Market failed'),
    );
  });

  it('treats empty and locked modules as unavailable and counts arrays safely', () => {
    expect(digilanderModuleAvailable(digilanderModuleEmpty('No news'))).toBe(false);
    expect(digilanderModuleAvailable(digilanderModuleLocked('Sign in'))).toBe(false);
    expect(digilanderSafeArrayLength([{ id: 1 }, { id: 2 }])).toBe(2);
    expect(digilanderSafeArrayLength(null)).toBe(0);
    expect(digilanderSafeArrayLength({ length: 99 })).toBe(0);
  });
});
