const express = require("express");
const router = express.Router();
const steedosAuth = require('@steedos/auth');
const axios = require('axios');
const bodyParser = require('body-parser');

router.use(bodyParser.json({ limit: '2mb' }));

/**
 * AI Workflow Designer endpoint
 * 
 * Accepts natural language instructions and current workflow steps,
 * calls an OpenAI-compatible LLM API to generate modified steps.
 * 
 * Environment variables:
 *   WORKFLOW_AI_API_KEY    - API key for the LLM provider
 *   WORKFLOW_AI_BASE_URL   - Base URL (default: https://api.openai.com/v1)
 *   WORKFLOW_AI_MODEL      - Model name (default: gpt-4o)
 */
router.post('/am/ai/design', async function auth(req, res, next) {
  try {
    const result = await steedosAuth.auth(req, res);
    if (result && result.userId) {
      req.user = result;
      next();
    } else {
      res.status(401).json({ error: '请先登录' });
    }
  } catch (e) {
    res.status(401).json({ error: '认证失败' });
  }
}, async function (req, res) {
  try {
    const apiKey = process.env.WORKFLOW_AI_API_KEY;
    if (!apiKey) {
      return res.status(500).json({ error: '请先配置环境变量 WORKFLOW_AI_API_KEY' });
    }

    const baseURL = process.env.WORKFLOW_AI_BASE_URL || 'https://api.openai.com/v1';
    const model = process.env.WORKFLOW_AI_MODEL || 'gpt-4o';

    const { steps, formFields, userRequest } = req.body;

    if (!userRequest) {
      return res.status(400).json({ error: '请输入需求描述' });
    }

    // Build form fields description
    const fieldsDesc = (formFields || [])
      .filter(f => f.code)
      .map(f => `  - ${f.name || f.code} (编码: ${f.code}, 类型: ${f.type || 'text'})`)
      .join('\n');

    const systemPrompt = `你是一个专业的审批流程设计师。你的任务是根据用户的自然语言描述，修改审批流程的步骤定义（JSON 格式）。

## 步骤数据结构

每个步骤(step)是一个 JSON 对象，必须包含以下字段：
- _id: 字符串，唯一标识。已有步骤保留原 _id，新步骤使用 "step-" + 小写字母数字随机串（如 "step-a1b2c3d4"）
- name: 字符串，步骤名称
- step_type: 字符串，类型，只能是以下之一：
  - "start" — 开始节点（流程必须有且仅有一个）
  - "end" — 结束节点（流程必须有且仅有一个）
  - "submit" — 填写步骤
  - "sign" — 审批步骤
  - "counterSign" — 会签步骤（多人同时审批）
  - "condition" — 条件分支节点
- deal_type: 字符串, 处理人身份（submit/sign/counterSign 必填），可选值：
  - "pickupAtRuntime" — 审批时指定
  - "specifyUser" — 指定人员
  - "applicantSuperior" — 申请人的上级
  - "applicant" — 申请人
  - "hrRole" — 指定角色
  - "applicantRole" — 指定审批岗位
- posx, posy: 数字，节点位置。纵向从上到下排列，开始节点 posx=200,posy=40，之后每步 y 增加约120
- timeout_hours: 数字，超时小时数，默认 168
- lines: 数组，从当前步骤出发的连线，每条连线包含：
  - _id: 字符串，连线唯一标识，用 "line-" + 随机串
  - name: 字符串，连线名称（可空）
  - to_step: 字符串，目标步骤的 _id
  - state: 字符串，"submitted"（提交）/ "approved"（核准）/ "rejected"（驳回）
  - condition: 字符串，条件表达式（仅条件节点的出线需要），格式如 {字段编码} > 10000

## 规则
1. 流程必须有且仅有一个 start 和一个 end 节点
2. 所有步骤必须通过 lines 互相连通，不能有孤立节点
3. 从 start 开始必须能最终到达 end
4. 审批步骤(sign)通常有两条出线：approved（核准）到下一步，rejected（驳回）回到填写或上一步
5. 条件节点(condition)有多条出线，每条带不同的 condition 表达式
6. 不要添加 notify、concurrentStart、concurrentEnd 类型的步骤
7. 修改时尽可能保留用户已有步骤的 _id 和设置，只改需要改的部分
8. 返回完整的 steps 数组

## 输出格式
直接返回 JSON 数组，不要有任何其他文字、解释、markdown 标记。`;

    const userContent = `## 当前表单字段
${fieldsDesc || '（无字段信息）'}

## 当前流程步骤
${JSON.stringify(steps || [], null, 2)}

## 用户需求
${userRequest}

请返回修改后的完整 steps JSON 数组。`;

    const response = await axios.post(`${baseURL}/chat/completions`, {
      model,
      messages: [
        { role: 'system', content: systemPrompt },
        { role: 'user', content: userContent },
      ],
      temperature: 0.3,
      max_tokens: 8000,
    }, {
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
      timeout: 120000,
    });

    const content = response.data?.choices?.[0]?.message?.content;
    if (!content) {
      return res.status(500).json({ error: 'AI 未返回有效内容' });
    }

    // Try to parse the JSON from the response
    let stepsResult;
    try {
      let text = content.trim();
      // Strip markdown code block if present
      if (text.startsWith('```json')) text = text.slice(7);
      else if (text.startsWith('```')) text = text.slice(3);
      if (text.endsWith('```')) text = text.slice(0, -3);
      text = text.trim();

      // Find JSON array
      const arrStart = text.indexOf('[');
      const arrEnd = text.lastIndexOf(']');
      if (arrStart !== -1 && arrEnd > arrStart) {
        stepsResult = JSON.parse(text.substring(arrStart, arrEnd + 1));
      } else {
        stepsResult = JSON.parse(text);
      }
    } catch (parseErr) {
      return res.status(500).json({
        error: 'AI 返回内容无法解析为 JSON',
        raw: content,
      });
    }

    if (!Array.isArray(stepsResult)) {
      return res.status(500).json({ error: 'AI 返回的不是步骤数组' });
    }

    // Basic validation
    const hasStart = stepsResult.some(s => s.step_type === 'start');
    const hasEnd = stepsResult.some(s => s.step_type === 'end');
    if (!hasStart || !hasEnd) {
      return res.status(500).json({ error: 'AI 返回的流程缺少开始或结束节点' });
    }

    return res.json({ steps: stepsResult });

  } catch (error) {
    console.error('AI workflow design error:', error?.response?.data || error?.message || error);
    if (error.response) {
      const status = error.response.status;
      const data = error.response.data;
      if (status === 401 || status === 403) {
        return res.status(500).json({ error: 'AI API 密钥无效或权限不足，请检查 WORKFLOW_AI_API_KEY' });
      }
      if (status === 429) {
        return res.status(500).json({ error: 'AI API 请求频率超限，请稍后重试' });
      }
      return res.status(500).json({ error: data?.error?.message || 'AI API 调用失败' });
    }
    return res.status(500).json({ error: error.message || 'AI 服务调用失败' });
  }
});

exports.default = router;
