import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, rmSync, readFileSync, existsSync, readdirSync } from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';
import { saveStructuredBlocks, type StructuredBlock } from './structured-blocks.js';

let ws: string;

beforeEach(() => {
  ws = mkdtempSync(join(tmpdir(), 'structured-blocks-test-'));
});

afterEach(() => {
  rmSync(ws, { recursive: true, force: true });
});

const block = (refId: string, overrides: Partial<StructuredBlock> = {}): StructuredBlock => ({
  refId,
  type: 'x_posts',
  title: 'sample',
  data: { query: 'q', posts: [] },
  ...overrides,
});

describe('saveStructuredBlocks', () => {
  it('writes one JSON file per block under logs/structured', () => {
    saveStructuredBlocks(ws, [block('ref-1'), block('ref-2', { type: 'map_places' })]);
    const dir = join(ws, 'logs', 'structured');
    expect(readdirSync(dir).sort()).toEqual(['ref-1.json', 'ref-2.json']);
    const parsed = JSON.parse(readFileSync(join(dir, 'ref-1.json'), 'utf-8')) as StructuredBlock;
    expect(parsed.refId).toBe('ref-1');
    expect(parsed.type).toBe('x_posts');
    expect(parsed.data).toEqual({ query: 'q', posts: [] });
  });

  it('does nothing for an empty block list', () => {
    saveStructuredBlocks(ws, []);
    expect(existsSync(join(ws, 'logs', 'structured'))).toBe(false);
  });

  it('round-trips unicode data intact', () => {
    saveStructuredBlocks(ws, [block('jp', { title: '日本語タイトル', data: { text: '絵文字🎉' } })]);
    const parsed = JSON.parse(
      readFileSync(join(ws, 'logs', 'structured', 'jp.json'), 'utf-8'),
    ) as StructuredBlock;
    expect(parsed.title).toBe('日本語タイトル');
    expect(parsed.data).toEqual({ text: '絵文字🎉' });
  });

  it('swallows write failures instead of throwing', () => {
    // Point the workspace at a path whose parent is a regular file.
    const bogus = join(ws, 'not-a-dir');
    saveStructuredBlocks(ws, [block('pre')]); // creates logs/structured
    expect(() =>
      saveStructuredBlocks(join(ws, 'logs', 'structured', 'pre.json'), [block('x')]),
    ).not.toThrow();
    expect(existsSync(bogus)).toBe(false);
  });
});
