/**
 * GenUI Types 测试
 * 验证类型定义的正确性和数据结构
 */
import { describe, it, expect } from 'vitest';
import type { 
  UISchema, 
  UIComponent, 
  ComponentType,
  StatItem,
  TableColumn,
  ActionButton,
  ApprovalData,
  InsightData,
  RenderContext,
  GenUIResponse
} from '../types';

describe('GenUI Types', () => {
  describe('UISchema Structure', () => {
    it('should accept valid minimal schema', () => {
      const schema: UISchema = {
        components: []
      };
      expect(schema.components).toEqual([]);
    });

    it('should accept full schema with all options', () => {
      const schema: UISchema = {
        version: '1.0.0',
        layout: 'grid',
        gap: 'lg',
        components: [
          { type: 'text', props: { content: 'Hello' } }
        ]
      };
      expect(schema.version).toBe('1.0.0');
      expect(schema.layout).toBe('grid');
      expect(schema.gap).toBe('lg');
      expect(schema.components).toHaveLength(1);
    });
  });

  describe('ComponentType Enum', () => {
    it('should support all display component types', () => {
      const displayTypes: ComponentType[] = [
        'stats_row', 'data_table', 'chart', 'alert', 
        'progress_bar', 'text', 'divider'
      ];
      expect(displayTypes).toHaveLength(7);
    });

    it('should support all action component types', () => {
      const actionTypes: ComponentType[] = [
        'action_buttons', 'approval_card', 'insight_card'
      ];
      expect(actionTypes).toHaveLength(3);
    });

    it('should support all agent component types', () => {
      const agentTypes: ComponentType[] = [
        'agent_status', 'agent_capabilities', 'agent_thinking',
        'agent_settings_card', 'agent_settings_list'
      ];
      expect(agentTypes).toHaveLength(5);
    });

    it('should support container and special types', () => {
      const specialTypes: ComponentType[] = [
        'container', 'sandbox_result', 'insight_feed', 'approval_list'
      ];
      expect(specialTypes).toHaveLength(4);
    });
  });

  describe('StatItem Structure', () => {
    it('should accept minimal stat item', () => {
      const stat: StatItem = {
        label: 'Total Sales',
        value: 1000
      };
      expect(stat.label).toBe('Total Sales');
      expect(stat.value).toBe(1000);
    });

    it('should accept full stat item with all options', () => {
      const stat: StatItem = {
        label: 'Revenue',
        value: '¥50,000',
        trend: '+15%',
        trendDirection: 'up',
        icon: 'trending-up',
        color: 'success'
      };
      expect(stat.trendDirection).toBe('up');
      expect(stat.color).toBe('success');
    });
  });

  describe('TableColumn Structure', () => {
    it('should accept minimal table column', () => {
      const column: TableColumn = {
        key: 'name',
        label: 'Name'
      };
      expect(column.key).toBe('name');
    });

    it('should accept full table column', () => {
      const column: TableColumn = {
        key: 'status',
        label: 'Status',
        type: 'status',
        width: '100px'
      };
      expect(column.type).toBe('status');
    });
  });

  describe('ActionButton Structure', () => {
    it('should accept minimal action button', () => {
      const button: ActionButton = {
        id: 'btn-1',
        label: 'Submit',
        action: 'submit'
      };
      expect(button.action).toBe('submit');
    });

    it('should accept full action button', () => {
      const button: ActionButton = {
        id: 'btn-approve',
        label: 'Approve',
        action: 'approve_campaign',
        variant: 'default',
        icon: 'check',
        disabled: false,
        params: { campaignId: '123' }
      };
      expect(button.params?.campaignId).toBe('123');
    });
  });

  describe('ApprovalData Structure', () => {
    it('should accept valid approval data', () => {
      const approval: ApprovalData = {
        id: 'appr-1',
        title: 'Marketing Campaign',
        description: 'Summer sale campaign',
        type: 'marketing',
        priority: 'high',
        createdAt: '2024-01-15T10:00:00Z',
        metadata: { budget: 10000 }
      };
      expect(approval.priority).toBe('high');
      expect(approval.metadata?.budget).toBe(10000);
    });
  });

  describe('InsightData Structure', () => {
    it('should accept valid insight data', () => {
      const insight: InsightData = {
        id: 'insight-1',
        type: 'warning',
        title: 'Low Stock Alert',
        description: '5 products are running low on stock',
        action: {
          id: 'view-low-stock',
          label: 'View Products',
          action: 'navigate_products'
        }
      };
      expect(insight.type).toBe('warning');
      expect(insight.action?.label).toBe('View Products');
    });
  });

  describe('RenderContext Structure', () => {
    it('should accept valid render context', () => {
      const context: RenderContext = {
        onAction: (action, params) => console.log(action, params),
        theme: 'dark',
        loading: false,
        agentType: 'marketing'
      };
      expect(context.theme).toBe('dark');
      expect(context.agentType).toBe('marketing');
    });

    it('should accept minimal context', () => {
      const context: RenderContext = {};
      expect(context.onAction).toBeUndefined();
    });
  });

  describe('GenUIResponse Structure', () => {
    it('should accept minimal response', () => {
      const response: GenUIResponse = {
        answer: 'Here is your data'
      };
      expect(response.answer).toBe('Here is your data');
    });

    it('should accept full response with ui_schema', () => {
      const response: GenUIResponse = {
        answer: 'Analysis complete',
        ui_schema: {
          layout: 'vertical',
          components: [
            { type: 'text', props: { content: 'Results' } }
          ]
        },
        actions: [
          { type: 'navigate', params: { tab: 'products' } }
        ],
        conversation_id: 'conv-123',
        message_id: 'msg-456'
      };
      expect(response.ui_schema?.components).toHaveLength(1);
      expect(response.actions).toHaveLength(1);
    });
  });

  describe('Complex Schema Validation', () => {
    it('should accept nested container schema', () => {
      const schema: UISchema = {
        layout: 'vertical',
        gap: 'md',
        components: [
          { type: 'text', props: { content: 'Dashboard', variant: 'h1' } },
          {
            type: 'container',
            props: {
              layout: 'grid',
              columns: 2,
              gap: 'sm',
              children: [
                { type: 'stats_row', props: { items: [{ label: 'Sales', value: 100 }] } },
                { type: 'chart', props: { type: 'bar', data: [{ label: 'A', value: 10 }] } }
              ]
            }
          }
        ]
      };
      expect(schema.components).toHaveLength(2);
      const container = schema.components[1];
      expect(container.type).toBe('container');
    });

    it('should accept insight_feed schema', () => {
      const component: UIComponent<'insight_feed'> = {
        type: 'insight_feed',
        props: {
          title: 'AI Insights',
          insights: [
            {
              id: 'i1',
              type: 'opportunity',
              title: 'Growth Opportunity',
              description: 'Sales trending up',
              metric: { label: 'Growth', value: '+25%', trend: 'up' },
              priority: 'high',
              agent: 'marketing'
            }
          ],
          layout: 'list',
          groupBy: 'priority'
        }
      };
      expect(component.props.insights).toHaveLength(1);
      expect(component.props.groupBy).toBe('priority');
    });

    it('should accept approval_list schema', () => {
      const component: UIComponent<'approval_list'> = {
        type: 'approval_list',
        props: {
          title: 'Pending Approvals',
          approvals: [
            {
              id: 'a1',
              type: 'marketing',
              title: 'Flash Sale',
              description: 'Electronics flash sale',
              agent: 'marketing',
              priority: 'urgent',
              amount: 50000,
              timestamp: '2024-01-15T10:00:00Z'
            }
          ],
          layout: 'cards',
          groupBy: 'agent',
          showActions: true
        }
      };
      expect(component.props.approvals).toHaveLength(1);
      expect(component.props.showActions).toBe(true);
    });
  });
});
