/**
 * Manager GenUI Edge Function 测试
 * 使用 Deno 测试框架验证店长GenUI接口功能
 */
import "https://deno.land/std@0.224.0/dotenv/load.ts";
import { assertEquals, assertExists, assert } from "https://deno.land/std@0.224.0/assert/mod.ts";

const SUPABASE_URL = Deno.env.get("VITE_SUPABASE_URL")!;
const SUPABASE_ANON_KEY = Deno.env.get("VITE_SUPABASE_PUBLISHABLE_KEY")!;

const FUNCTION_URL = `${SUPABASE_URL}/functions/v1/manager-genui`;

// ========== UI Schema 类型定义（供契约验证） ==========
interface UIComponent {
  type: string;
  id?: string;
  props: Record<string, unknown>;
}

interface UISchema {
  layout: 'vertical' | 'horizontal' | 'grid';
  gap: 'sm' | 'md' | 'lg';
  components: UIComponent[];
}

interface GenUIResponse {
  success: boolean;
  answer?: string;
  ui_schema?: UISchema;
  insights?: unknown[];
  intent?: string;
  conversation_id?: string;
}

// ========== 辅助函数 ==========
async function callGenUI(body: Record<string, unknown>): Promise<Response> {
  return await fetch(FUNCTION_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'apikey': SUPABASE_ANON_KEY,
    },
    body: JSON.stringify(body),
  });
}

// ========== 基础功能测试 ==========
Deno.test("manager-genui: CORS预检请求应返回200", async () => {
  const response = await fetch(FUNCTION_URL, { method: 'OPTIONS' });
  const body = await response.text();
  assertEquals(response.status, 200);
  assert(response.headers.get('Access-Control-Allow-Origin') !== null);
});

Deno.test("manager-genui: 空消息应返回dashboard视图", async () => {
  const response = await callGenUI({ message: '' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(response.status, 200);
  assertEquals(data.success, true);
  assertExists(data.ui_schema);
  assertEquals(data.intent, 'dashboard');
});

Deno.test("manager-genui: 仪表盘请求应返回统计组件", async () => {
  const response = await callGenUI({ message: '查看今日数据' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  assertExists(data.ui_schema);
  
  const schema = data.ui_schema!;
  assertEquals(schema.layout, 'vertical');
  assert(schema.components.length > 0);
  
  // 验证包含stats_row组件
  const hasStatsRow = schema.components.some(c => c.type === 'stats_row');
  assert(hasStatsRow, '仪表盘应包含stats_row组件');
});

// ========== 意图检测测试 ==========
Deno.test("manager-genui: 商品相关查询应检测为products意图", async () => {
  const response = await callGenUI({ message: '查看库存情况' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  assertEquals(data.intent, 'products');
});

Deno.test("manager-genui: 订单相关查询应检测为orders意图", async () => {
  const response = await callGenUI({ message: '最近订单怎么样' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  assertEquals(data.intent, 'orders');
});

Deno.test("manager-genui: 营销相关查询应检测为marketing意图", async () => {
  const response = await callGenUI({ message: '营销活动状态' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  assertEquals(data.intent, 'marketing');
});

Deno.test("manager-genui: 售后相关查询应检测为aftersales意图", async () => {
  const response = await callGenUI({ message: '待处理售后' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  assertEquals(data.intent, 'aftersales');
});

Deno.test("manager-genui: 用户相关查询应检测为users意图", async () => {
  const response = await callGenUI({ message: '用户统计' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  assertEquals(data.intent, 'users');
});

Deno.test("manager-genui: 帮助请求应检测为help意图", async () => {
  const response = await callGenUI({ message: '帮助' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  assertEquals(data.intent, 'help');
});

// ========== UI Schema 契约测试 ==========
Deno.test("manager-genui: ui_schema应符合标准结构", async () => {
  const response = await callGenUI({ message: '数据概览' });
  const data: GenUIResponse = await response.json();
  
  assertExists(data.ui_schema);
  const schema = data.ui_schema!;
  
  // 验证顶层结构
  assert(['vertical', 'horizontal', 'grid'].includes(schema.layout), 'layout应为有效值');
  assert(['sm', 'md', 'lg'].includes(schema.gap), 'gap应为有效值');
  assert(Array.isArray(schema.components), 'components应为数组');
  
  // 验证每个组件结构
  for (const component of schema.components) {
    assertExists(component.type, '组件必须有type');
    assertExists(component.props, '组件必须有props');
    assert(typeof component.props === 'object', 'props应为对象');
  }
});

Deno.test("manager-genui: stats_row组件props应包含items数组", async () => {
  const response = await callGenUI({ message: '查看概览' });
  const data: GenUIResponse = await response.json();
  
  const statsRow = data.ui_schema?.components.find(c => c.type === 'stats_row');
  if (statsRow) {
    const props = statsRow.props as { items?: unknown[] };
    assert(Array.isArray(props.items), 'stats_row应包含items数组');
    
    if (props.items.length > 0) {
      const item = props.items[0] as Record<string, unknown>;
      assertExists(item.label, 'stats item应有label');
      assertExists(item.value, 'stats item应有value');
    }
  }
});

Deno.test("manager-genui: chart组件props应包含必要字段", async () => {
  const response = await callGenUI({ message: '销售趋势' });
  const data: GenUIResponse = await response.json();
  
  const chart = data.ui_schema?.components.find(c => c.type === 'chart');
  if (!chart) {
    // 可能嵌套在container中
    const container = data.ui_schema?.components.find(c => c.type === 'container');
    if (container) {
      const children = (container.props as { children?: UIComponent[] }).children || [];
      const nestedChart = children.find(c => c.type === 'chart');
      if (nestedChart) {
        const props = nestedChart.props as Record<string, unknown>;
        assertExists(props.type, 'chart应有type (line/bar/pie/area)');
        assert(Array.isArray(props.data), 'chart应有data数组');
      }
    }
  } else {
    const props = chart.props as Record<string, unknown>;
    assertExists(props.type, 'chart应有type');
    assert(Array.isArray(props.data), 'chart应有data数组');
  }
});

// ========== 视图参数测试 ==========
Deno.test("manager-genui: 明确指定view参数应覆盖意图检测", async () => {
  const response = await callGenUI({ 
    message: '查看商品', // 通常会检测为products
    view: 'marketing'   // 但明确指定marketing视图
  });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  assertEquals(data.intent, 'marketing');
});

// ========== 洞察生成测试 ==========
Deno.test("manager-genui: 应返回insights数组", async () => {
  const response = await callGenUI({ message: '查看仪表盘' });
  const data: GenUIResponse = await response.json();
  
  assertEquals(data.success, true);
  if (data.insights) {
    assert(Array.isArray(data.insights), 'insights应为数组');
    
    // 验证洞察结构
    for (const insight of data.insights) {
      const i = insight as Record<string, unknown>;
      assertExists(i.id, '洞察应有id');
      assertExists(i.type, '洞察应有type');
      assertExists(i.title, '洞察应有title');
    }
  }
});

// ========== 错误处理测试 ==========
Deno.test("manager-genui: 无效请求体应正常处理", async () => {
  const response = await fetch(FUNCTION_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'apikey': SUPABASE_ANON_KEY,
    },
    body: 'invalid json{',
  });
  
  // 即使请求体无效，也应返回合理响应
  assert(response.status === 200 || response.status === 400);
  await response.text(); // 消费响应体
});

// ========== 支持的组件类型契约 ==========
const VALID_COMPONENT_TYPES = [
  'stats_row', 'data_table', 'chart', 'alert', 'action_buttons',
  'approval_card', 'insight_card', 'progress_bar', 'text', 'divider',
  'container', 'agent_status', 'agent_capabilities', 'agent_thinking',
  'agent_settings_card', 'agent_settings_list', 'sandbox_result',
  'insight_feed', 'approval_list'
];

Deno.test("manager-genui: 返回的组件类型应在白名单内", async () => {
  const response = await callGenUI({ message: '完整数据' });
  const data: GenUIResponse = await response.json();
  
  function validateComponents(components: UIComponent[]) {
    for (const component of components) {
      assert(
        VALID_COMPONENT_TYPES.includes(component.type),
        `组件类型 '${component.type}' 不在白名单内`
      );
      
      // 递归验证container的children
      if (component.type === 'container') {
        const children = (component.props as { children?: UIComponent[] }).children;
        if (children) {
          validateComponents(children);
        }
      }
    }
  }
  
  if (data.ui_schema?.components) {
    validateComponents(data.ui_schema.components);
  }
});
