import { HumanMessage } from 'langchain/schema'
import { StructuredOutputParser } from 'langchain/output_parsers'
import { z } from 'zod'
import pRetry from 'p-retry'
import { LLMTools } from './types'

async function listTables(tools: LLMTools, title, desc) {
    const { llm, usage, conversation } = tools
    const scheme = StructuredOutputParser.fromZodSchema(z.array(z.string().describe('表名')))
    const res = await llm.call([
        new HumanMessage(`${scheme.getFormatInstructions()}
------
你是一个计算机专业擅长写毕业论文的专家，你的任务是帮我的毕业设计撰写一篇论文
我的毕业设计项目是${title}
这个项目包含以下功能：
${desc}
现在我们需要开始为这个系统设计数据库，首先请帮我列出我们需要哪些表：`)
    ])
    return await scheme.parse(res.content)
}

async function describeTable(tools, title, desc, list, name) {
    const { llm, usage, conversation } = tools
    const res = await llm.call([
        new HumanMessage(`
你是一个计算机专业擅长写毕业论文的专家，你的任务是帮我的毕业设计撰写一篇论文
我的毕业设计项目是${title}
这个项目包含以下功能：
${desc}
现在我们需要开始为这个系统设计数据库，我们需要以下这些数据库表：
${list.map((i) => `- ${i}`).join('\n')}
现在我们一步一步设计这些表的具体字段，首先我们需要设计${name}表的字段，请你帮我设计一下这个表的字段，以表格的形式返回，包含字段名称、类型、长度、字段说明、主键、默认值`)
    ])

    return {
        name,
        desc: '\n' + new RegExp('\\|[\\s\\S]+\\|').exec(res.content)[0] + '\n'
    }
}

export async function createTable(tools: LLMTools, title, desc) {
    const pRetry = (await eval("import('p-retry')")).default
    const list = await pRetry(() => listTables(tools, title, desc), { retries: 5 })

    const tables = []
    for (const item of list) {
        tables.push(await pRetry(() => describeTable(tools, title, desc, list, item), { retries: 5 }))
    }
    return tables
}
