import {
    parseTsvBody,
    valuesToMarkdownTable,
} from '../src/features/sheets/sheetsApi';
import { _parseSheetAttrs } from '../src/agent';

describe('parseTsvBody', () => {
    test('returns [] for empty / whitespace input', () => {
        expect(parseTsvBody('')).toEqual([]);
        expect(parseTsvBody('   ')).toEqual([]);
        expect(parseTsvBody('\n\n')).toEqual([]);
    });

    test('parses tab-separated rows', () => {
        const body = '이름\t나이\t직책\n민지\t29\t디자이너\n준호\t31\t개발자';
        expect(parseTsvBody(body)).toEqual([
            ['이름', '나이', '직책'],
            ['민지', '29', '디자이너'],
            ['준호', '31', '개발자'],
        ]);
    });

    test('falls back to pipe-separated when no tab present', () => {
        const body = '이름 | 나이\n민지 | 29\n준호 | 31';
        expect(parseTsvBody(body)).toEqual([
            ['이름', '나이'],
            ['민지', '29'],
            ['준호', '31'],
        ]);
    });

    test('strips leading and trailing blank lines (LLM artifact)', () => {
        const body = '\n\n이름\t나이\n민지\t29\n\n';
        expect(parseTsvBody(body)).toEqual([
            ['이름', '나이'],
            ['민지', '29'],
        ]);
    });

    test('preserves empty cells when tabs are present', () => {
        const body = 'A\t\tC';
        expect(parseTsvBody(body)).toEqual([['A', '', 'C']]);
    });
});

describe('valuesToMarkdownTable', () => {
    test('empty → placeholder', () => {
        expect(valuesToMarkdownTable([])).toBe('_(empty)_');
    });

    test('renders header + separator + rows', () => {
        const out = valuesToMarkdownTable([
            ['이름', '나이'],
            ['민지', 29],
            ['준호', 31],
        ]);
        const lines = out.split('\n');
        expect(lines[0]).toBe('| 이름 | 나이 |');
        expect(lines[1]).toBe('|---|---|');
        expect(lines[2]).toBe('| 민지 | 29 |');
        expect(lines[3]).toBe('| 준호 | 31 |');
    });

    test('truncates beyond maxRows + adds note', () => {
        const big: any[][] = [['col']];
        for (let i = 0; i < 60; i++) big.push([`row${i}`]);
        const out = valuesToMarkdownTable(big, 10);
        expect(out).toContain('| col |');
        expect(out).toContain('| row0 |');
        expect(out).toContain('| row8 |'); // 10 rows total = header + 9 data
        expect(out).not.toContain('| row9 |');
        expect(out).toContain('51 more rows truncated');
    });

    test('escapes pipe characters inside cell values', () => {
        const out = valuesToMarkdownTable([
            ['a|b', 'c'],
            ['d', 'e|f'],
        ]);
        expect(out).toContain('| a\\|b | c |');
        expect(out).toContain('| d | e\\|f |');
    });
});

describe('_parseSheetAttrs', () => {
    test('parses spreadsheet_id + range with double quotes', () => {
        const a = _parseSheetAttrs(' spreadsheet_id="1abc" range="Sheet1!A1:D20" ');
        expect(a.spreadsheetId).toBe('1abc');
        expect(a.range).toBe('Sheet1!A1:D20');
    });

    test('accepts camelCase alias spreadsheetId', () => {
        const a = _parseSheetAttrs('spreadsheetId="1xyz" range="A:B"');
        expect(a.spreadsheetId).toBe('1xyz');
    });

    test('accepts sheet_id alias', () => {
        const a = _parseSheetAttrs(`sheet_id='1qrs' range='Tab1'`);
        expect(a.spreadsheetId).toBe('1qrs');
        expect(a.range).toBe('Tab1');
    });

    test('parses bare (unquoted) values', () => {
        const a = _parseSheetAttrs('spreadsheet_id=1simple range=Sheet1!A1');
        expect(a.spreadsheetId).toBe('1simple');
        expect(a.range).toBe('Sheet1!A1');
    });

    test('returns empty for missing attrs', () => {
        expect(_parseSheetAttrs('')).toEqual({});
        expect(_parseSheetAttrs('foo="bar"')).toEqual({});
    });
});
