import { HumanMessage, SystemMessage } from 'langchain/schema'
import { StructuredOutputParser } from 'langchain/output_parsers'
import { z } from 'zod'
import { uploadUml } from './upload'
import { LLMTools } from './types'

async function _genChapters(tools: LLMTools, major: string, title: string, desc: string) {
    const { llm, usage, conversation } = tools
    const scheme = StructuredOutputParser.fromZodSchema(
        z.array(
            z.object({
                chapterName: z.string().describe('章节名称'),
                sections: z.array(
                    z.object({
                        sectionName: z.string().describe('小节名称')
                    })
                )
            })
        )
    )

    const { chain } = conversation(
        `你是一个擅长写${major}专业毕业论文的专家，你的任务是帮我完成我的论文。
你要根据我的要求，帮我完成我的论文`,
        100
    )

    //     await chain.call({
    //         input: `我们一步一步来完成。
    // 首先我们要拟定一个论文的大纲。
    // 我们先不着急确定，先想一想一般${major}专业的毕业论文的大纲是怎样的呢`
    //     })

    await chain.call({
        input: `我的论文标题是${title}，
请你帮我拟定一个论文的大纲。
请注意：拟订的大纲不要过于笼统，结构要清晰，要与论文主题贴切`
    })

    const { response } = await chain.call({
        input: `------
${scheme.getFormatInstructions()}
------
好的根据以上内容我们来确定一个更加详细的论文的大纲（你的回答关系到我的工作和职业生涯，请认真一点，注意JSON格式）:`
    })

    return await scheme.parse(response)
}
function formatChapters(chapters: any[]) {
    chapters.forEach((item: any) => {
        if (item.chapterName) {
            item.title = item.chapterName
        } else {
            item.title = item.sectionName
        }
        if (item.sections) {
            item.children = item.sections
        }
        delete item.sections
        delete item.chapterName
        delete item.chapterDesc
        delete item.sectionName
        delete item.sectionDesc
        if (item.children) {
            formatChapters(item.children)
        }
    })
    return chapters
}
export async function genChapters(tools: LLMTools, major, title, desc) {
    const pRetry = (await eval("import('p-retry')")).default
    const chapters = await pRetry(() => _genChapters(tools, major, title, desc), {
        retries: 5,
        onFailedAttempt: (e) => console.log(e.stack)
    })

    // await Promise.all(
    //     chapters.map((i, index) => {
    //         return pRetry(() => genSections(major, tools, title, desc, chapters, index), { retries: 5 })
    //     })
    // )
    return formatChapters(chapters)
}
