import { describe, test, expect } from 'vitest';
import { serializeTreeForCraft, __test } from './apply-ai-response';

describe('serializeTreeForCraft', () => {
  test('flattens nested tree', () => {
    const tree = {
      type: { resolvedName: 'Section' },
      props: { aiName: 'Hero', node_id: 'ai-hero-1' },
      nodes: [
        {
          type: { resolvedName: 'Heading' },
          props: { aiName: 'Title', node_id: 'ai-h-1', text: 'Welcome' },
          nodes: [],
        },
      ],
    };
    const out = serializeTreeForCraft(tree);
    expect(out.rootNodeId).toBe('ai-hero-1');
    expect((out.nodes['ai-hero-1'] as any).nodes).toEqual(['ai-h-1']);
    expect((out.nodes['ai-h-1'] as any).parent).toBe('ROOT');
  });

  test('auto-generates ids when node_id is missing', () => {
    const tree = { type: { resolvedName: 'Heading' }, props: {}, nodes: [] };
    const out = serializeTreeForCraft(tree);
    expect(typeof out.rootNodeId).toBe('string');
    expect(out.nodes[out.rootNodeId]).toBeDefined();
  });

  test('sets isCanvas true for layout components', () => {
    const tree = {
      type: { resolvedName: 'Container' },
      props: { node_id: 'c1' },
      nodes: [],
    };
    const out = serializeTreeForCraft(tree);
    expect((out.nodes['ROOT'] as any).isCanvas).toBe(true);
  });

  test('sets isCanvas false for leaf components', () => {
    const tree = {
      type: { resolvedName: 'Heading' },
      props: { node_id: 'h1' },
      nodes: [],
    };
    const out = serializeTreeForCraft(tree);
    expect((out.nodes['ROOT'] as any).isCanvas).toBe(false);
  });

  test('aliases root node to ROOT key', () => {
    const tree = {
      type: { resolvedName: 'Section' },
      props: { node_id: 'ai-section-1' },
      nodes: [],
    };
    const out = serializeTreeForCraft(tree);
    expect(out.nodes['ROOT']).toBeDefined();
    expect((out.nodes['ROOT'] as any).parent).toBeNull();
  });
});

describe('findNodeIdByAiNodeId', () => {
  const query = {
    getNodes: () => ({
      'craft-id-1': { data: { props: { node_id: 'ai-hero-1' } } },
      'craft-id-2': { data: { props: { node_id: 'ai-cta-1' } } },
    }),
  };

  test('returns craft id for matching node_id prop', () => {
    expect(__test.findNodeIdByAiNodeId(query, 'ai-hero-1')).toBe('craft-id-1');
  });

  test('returns craft id for second entry', () => {
    expect(__test.findNodeIdByAiNodeId(query, 'ai-cta-1')).toBe('craft-id-2');
  });

  test('falls back to raw id match', () => {
    const q = {
      getNodes: () => ({
        'exact-id': { data: { props: {} } },
      }),
    };
    expect(__test.findNodeIdByAiNodeId(q, 'exact-id')).toBe('exact-id');
  });

  test('returns null when not found', () => {
    expect(__test.findNodeIdByAiNodeId({ getNodes: () => ({}) }, 'missing')).toBe(null);
  });
});
