import { describe, it, expect } from 'vitest';
import { formatTable } from '../../src/formatters/table.js';
import type { Column } from '../../src/formatters/table.js';

interface TestRow {
  name: string;
  age: number;
  city: string;
}

const columns: Column<TestRow>[] = [
  { header: 'NAME', key: 'name' },
  { header: 'AGE', key: 'age', align: 'right' },
  { header: 'CITY', key: 'city' },
];

describe('formatTable', () => {
  it('returns empty message for no rows', () => {
    expect(formatTable([], columns)).toBe('No results found.');
  });

  it('formats a single row', () => {
    const rows = [{ name: 'Alice', age: 30, city: 'NYC' }];
    const result = formatTable(rows, columns);
    const lines = result.split('\n');
    expect(lines).toHaveLength(3); // header, separator, data
    expect(lines[0]).toContain('NAME');
    expect(lines[0]).toContain('AGE');
    expect(lines[0]).toContain('CITY');
    expect(lines[2]).toContain('Alice');
    expect(lines[2]).toContain('NYC');
  });

  it('right-aligns numeric columns', () => {
    const rows = [{ name: 'Bob', age: 5, city: 'LA' }];
    const result = formatTable(rows, columns);
    const lines = result.split('\n');
    // AGE column should be right-aligned: " 5" or "5" padded
    const ageLine = lines[2];
    // The age value should have leading space(s) for right alignment
    expect(ageLine).toMatch(/\s+5/);
  });

  it('auto-sizes columns to content', () => {
    const rows = [
      { name: 'A', age: 1, city: 'X' },
      { name: 'LongName', age: 100, city: 'LongCityName' },
    ];
    const result = formatTable(rows, columns);
    const lines = result.split('\n');
    // Header should be at least as wide as longest data
    expect(lines[0]).toContain('NAME');
    expect(lines[2]).toContain('A');
    expect(lines[3]).toContain('LongName');
    expect(lines[3]).toContain('LongCityName');
  });

  it('truncates long values when width is fixed', () => {
    const narrowCols: Column<TestRow>[] = [
      { header: 'NAME', key: 'name', width: 5 },
    ];
    const rows = [{ name: 'VeryLongName', age: 0, city: '' }];
    const result = formatTable(rows, narrowCols);
    const lines = result.split('\n');
    // Should be truncated with ellipsis
    expect(lines[2].trim().length).toBeLessThanOrEqual(5);
    expect(lines[2]).toContain('\u2026');
  });

  it('supports function-based column keys', () => {
    const fnCols: Column<TestRow>[] = [
      { header: 'INFO', key: (row) => `${row.name} (${row.age})` },
    ];
    const rows = [{ name: 'Eve', age: 25, city: 'SF' }];
    const result = formatTable(rows, fnCols);
    expect(result).toContain('Eve (25)');
  });

  it('handles separator line matching column widths', () => {
    const rows = [{ name: 'Test', age: 1, city: 'Here' }];
    const result = formatTable(rows, columns);
    const lines = result.split('\n');
    const separator = lines[1];
    // Separator should consist of dashes and spaces
    expect(separator).toMatch(/^[-\s]+$/);
  });
});
