<template>
    <el-dialog title="AI生成PPT" :visible.sync="dialogVisibleAiCreate" :append-to-body="true" width="700px"
        :before-close="handleClose" class="dialog_diy">
        <div style="height: 500px; padding: 15px" v-loading="loading">
            <!-- <div class="t_box">
                <span>选择：</span>
                <el-radio-group v-model="radio" @change="changeRadio">
                    <el-radio :label="0">PPT</el-radio>
                    <el-radio :label="1">教案</el-radio>
                    <el-radio :label="2">视频</el-radio>
                </el-radio-group>
            </div> -->
            <div class="t_box" v-if="steps == 1" style="height: 100%">
                <textarea style="height: 100%" rows="10" class="binfo_input binfo_textarea" cols placeholder="请生成大纲"
                    v-model="outline"></textarea>
            </div>
            <div style="height: 100%" v-else>
                <wOffice v-if="url" :url="url"></wOffice>
            </div>
        </div>
        <span slot="footer" class="dialog-footer">
            <el-button @click="aiGet(2)" type="primary" :disabled="loading">重新生成大纲</el-button>
            <el-button @click="aiGet(1)" type="primary" :disabled="loading">{{
                url ? "重新生成PPT" : "生成PPT"
                }}</el-button>
            <el-button @click="steps = 1" type="primary" v-if="steps == 2">上一步</el-button>
            <el-button @click="steps = 2" type="primary" v-else-if="steps == 1 && url">下一步</el-button>
            <el-button @click="confirm" type="primary">确 定</el-button>
            <el-button @click="close">关 闭</el-button>
        </span>
    </el-dialog>
</template>

<script>
import Pptxgen from "pptxgenjs";
import wOffice from "../components/wOffice.vue";
import { v4 as uuidv4 } from "uuid";

export default {
    components: {
        wOffice,
    },
    props: {
        dialogVisibleAiCreate: {
            type: Boolean,
            default: false,
        },
        courseName: {
            type: String,
            default: "",
        },
        infoData: {
            type: Array,
            default: "",
        },
        courseTypeId: {
            type: Array,
            default: "",
        },
        CourseTypeJson: {
            type: Object,
            default: ()=>({}),
        }
    },
    // 根据用户给你的参考资料
    data() {
        return {
            userid: this.$route.query.userid,
            radio: 0,
            aiJson: {
                ppt: `## 任务
请生成关于${this.courseName}，为教师生成这节课的教学ppt，页数在20页左右。PPT的内容主要是讲解该课程中所有可能涉及到的知识点。

## 工作流
1. 从用户提供的参考资料中提取10个最重要的知识点（知识点水平限制在小学和初中），并输出。
2. 针对10个知识点中的每个，你使用1~3页ppt详细的对知识点进行讲解。你的讲解词应该在100token左右
3. 讲解完所有知识点后，再根据知识点出5道单选题（放在5页ppt中）

## 限制
- 你不能输出错误的知识，如果你实在不清楚，输出“对不起，我不确定”
- 你不能输出违反伦理的内容`,
                word: "",
                video: "",
            },
            aiUrl: {
                ppt: "",
                word: "",
                video: "",
            },
            detail: "",
            loading: false,
            url: "",
            uJson: {},
            outline: "",
            steps: 1,
        };
    },
    watch: {
        dialogVisibleAiCreate(newValue, oldValue) {
            if (newValue) {
                this.aiGet(2);
            }
        },
    },
    methods: {
        handleClose(done) {
            this.close();
            done();
        },
        close() {
            this.$emit("update:dialogVisibleAiCreate", false);
        },
        confirm() {
            if (this.url) {
                this.$emit("createAiPpt", this.uJson);
            } else {
                this.$message.error("请先生成ppt");
            }
        },
        changeRadio() {
            if (this.radio == 0) {
                this.detail = this.aiJson.ppt;
            }
            if (this.radio == 1) {
                this.detail = this.aiJson.word;
            }
            if (this.radio == 2) {
                this.detail = this.aiJson.video;
            }
        },
        createFileid(url) {
            let _this = this;
            return new Promise((resolve, reject) => {
                try {
                    _this.ajax
                        .put("https://gpt4.cocorobo.cn/upload_file_knowledge", {
                            url: url,
                        })
                        .then((res) => {
                            let _data = res.data.FunctionResponse;
                            if (_data.result && _data.result.id) {
                                resolve(_data.result.id);
                            }
                        })
                        .catch(function (error) {
                            resolve("");
                        });
                } catch (e) {
                    resolve();
                }
            });
        },
        async aiGet(type) {
            if (this.loading) {
                this.$message.error("正在生成中，请稍后");
                return;
            }
            this.url = "";
            this.uJson = {};
            let _this = this;

            let fileid = [];
            if (_this.infoData.length) {
                for (var i = 0; i < _this.infoData.length; i++) {
                    if (_this.infoData[i].fileid) {
                        fileid.push(_this.infoData[i].fileid);
                    } else {
                        let _fileid = await _this.createFileid(_this.infoData[i].url);
                        if (_fileid) {
                            _this.infoData[i].fileid = _fileid;
                            _this.$forceUpdate();
                            fileid.push(_fileid);
                        }
                    }
                }
            }
            console.log("fileid=========", fileid);

            let mclass = [];
            if (_this.courseTypeId.length) {
                for (var i = 0; i < _this.courseTypeId.length; i++) {
                    let _sid = _this.courseTypeId[i];
                    for (
                        var j = 0;
                        j <
                        _this.CourseTypeJson["34628934-d02f-11ec-8c78-005056b86db5"].length;
                        j++
                    ) {
                        if (
                            _sid ==
                            _this.CourseTypeJson["34628934-d02f-11ec-8c78-005056b86db5"][j].id
                        ) {
                            mclass.push(
                                _this.CourseTypeJson["34628934-d02f-11ec-8c78-005056b86db5"][j]
                                    .name
                            );
                        }
                    }
                }
            }
            let message = "";
            if (type == 1) {
                message = `NOTICE
Role: 从用户提供的参考资料中提取5个最重要的学科概念${mclass.length ? "（水平限制在{面向年级}中）" : ""}，作为ppt内容。
Output: Provide your output in json format.
Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
Instruction: Based on the context, follow "Format example", write content.

# Context 
## 任务
将参考#参考资料，为教师生成这节课的教学ppt。PPT的内容主要是讲解该课程中所有可能涉及到的知识点，每个知识点用1页讲解。

## 工作流
1. 针对大纲中的每个知识点，生成200字左右的详细讲解。你的语气应该让小学或初中的学生清晰易懂的讲解。请尽可能的详细，这对我很重要。
2. 针对大纲中的每个测试，详细设计不同测试题目，例如单选，多选，对错题等。

# 每一页输出格式
- 页数：序列数字
- 标题：学科概念（请从给你的大纲中摘取）
- 子标题：知识点（请从给你的大纲中摘取）
- 知识点讲解：针对大纲中的每个知识点，生成200字左右的详细讲解。你的语气应该让小学或初中的学生清晰易懂的讲解。你的讲解词在200 token左右。请尽可能的详细，这对我很重要。

## 限制
- 你不能输出错误的知识，如果你实在不清楚，修改大纲中的知识点。
- 你不能输出违反伦理的内容

## 工作流
1. 从用户提供的参考资料中提取5个最重要的学科概念，并输出。
2. 分解每个学科概念为几个子知识点
3. 简要描述每个知识点
4.生成5个测试题以考察学生的掌握情况

## 参考资料
${_this.outline}

# Format example
[{"page": "页码（数字）","title": "学科概念（请从给你的大纲中摘取）（标题）","task": "知识点（请从给你的大纲中摘取）（子标题）","points": "知识点讲解：针对大纲中的每个知识点，生成200字左右的详细讲解。你的语气应该让小学或初中的学生清晰易懂的讲解。你的讲解词在100 token左右。请尽可能的详细，这对我很重要。"}]`;
            } else {
                message = `# 任务
请根据参考资料，生成关于${this.courseName}，为教师生成这节课的教学ppt的大纲，大纲的主要内容课程知识点的讲解与相关练习和测试。你的输出应该符合#输出格式

# 工作流
1. 从用户提供的参考资料中提取5个最重要的学科概念${mclass.length ? "（水平限制在{面向年级}中）" : ""}，并输出。
2. 分解每个学科概念为几个子知识点
3. 简要描述每个知识点
4.生成5个测试题以考察学生的掌握情况

${mclass.length ? "#参考资料\n面向年级：" + mclass.join(",") : ""}

# 输出格式
- 标题：学科概念1
  1.知识点：知识点1
  2.知识点：知识点2
  3.知识点：知识点3
  4.知识点：知识点4
  5.知识点：知识点5

# 限制
- 你不能输出错误的知识，如果你实在不清楚，输出“对不起，我不确定”
- 你不能输出违反伦理的内容
`;
            }

            // let params = JSON.stringify({
            //     // "model": "Chat",
            //     model: 'gpt-3.5-turbo',
            //     temperature: 0,
            //     max_tokens: 4096,
            //     top_p: 1,
            //     frequency_penalty: 0,
            //     presence_penalty: 0,
            //     messages: [{
            //         content: message,
            //         role: 'user'
            //     }],
            //     stream: false,
            //     uid: this.userid,
            //     mind_map_question: "",
            // })

            // _this.loading = true
            // _this.ajax.post('https://gpt4.cocorobo.cn/chat', params).then(function (response) {
            //     console.log(response);
            //     let data = response.data.FunctionResponse
            //     if (data.choices && data.choices.length && data.choices[0].message) {
            //         console.log(data.choices[0].message.content);
            //         try {
            //             let _data = JSON.parse(data.choices[0].message.content)
            //             _this.createPpt(_data)
            //         } catch (e) {
            //             console.log('error_________________'+e);
            //             _this.$message.error(data.choices[0].message.content)
            //             _this.loading = false
            //         }

            //     }
            // }).catch(function (error) {
            //     _this.loading = false
            //     console.log(error);
            // });

            let parm = {
                assistant_id:
                    type == 1
                        ? "6063369f-289a-11ef-8bf4-12e77c4cb76b"
                        : "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
                message: [{ type: "text", text: message }],
                session_name: uuidv4(),
                userId: this.userid,
                file_ids: fileid.length ? [...fileid] : "",
            };
            _this.loading = true;
            this.ajax
                .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", parm)
                .then((response) => {
                    console.log(response);
                    let data = response.data.FunctionResponse;
                    if (data.message) {
                        console.log(data.message);
                        if (type == 1) {
                            try {
                                let _data = JSON.parse(
                                    data.message.replaceAll("```json", "").replaceAll("```", "")
                                );
                                _this.createPpt(_data);
                                _this.steps = 2;
                            } catch (e) {
                                console.log("error_________________" + e);
                                // _this.$message.error(data.message)
                                try {
                                    // let _data = JSON.parse(data.message.match(/(?<=```json).*?(?=```)/)[0])
                                    var message = data.message;
                                    var jsonStart = message.indexOf("```json") + 7; // `+ 7` 是为了跳过 ```json
                                    var jsonEnd = message.indexOf("```", jsonStart);
                                    if (jsonStart !== -1 && jsonEnd !== -1) {
                                        var jsonString = message
                                            .substring(jsonStart, jsonEnd)
                                            .trim();
                                        var _data2 = JSON.parse(jsonString);
                                        _this.createPpt(_data2);
                                        _this.steps = 2;
                                    } else {
                                        _this.$message.error("生成失败，正在重新生成");
                                        _this.aiGet(type);
                                    }
                                } catch (error) {
                                    _this.$message.error("生成失败，正在重新生成");
                                    _this.aiGet(type);
                                    _this.loading = false;
                                }
                            }
                        } else {
                            _this.outline = data.message;
                            _this.steps = 1;
                            _this.loading = false;
                        }
                    }
                })
                .catch((error) => {
                    _this.loading = false;
                    console.log(error);
                });
        },
        createPpt(array) {
            // 1. 创建PPT
            const pres = new Pptxgen();
            for (var i = 0; i < array.length; i++) {
                // 2. 创建一个PPT页面，每调用一次 pres.addSlide() 都可以生成一张新的页面
                // 建议把每个页面的构造抽成一个个函数，然后通过函数调用生成新页面，代码不会很乱
                const _slide = pres.addSlide();

                // 3. 调用addTetx()，在PPT页面中插入文字“Hello World from PptxGenJS...”
                // 括号里面是对文字的配置，文字横坐标x为1.5，纵坐标y为1.5，字体颜色 363636……
                // 关于坐标长度与px的转换 x 1 = 127~128px 左右
                const page = i+1 > 10 ? i+1 : "0"+(i+1);
                _slide.addText(page, {
                    x: 0.2, // 横坐标
                    y: 0.5,
                    color: "363636",
                    fontSize: 20, // 字号
                    align: "left",
                });
                const tempResult1 = array[i].title;
                _slide.addText(tempResult1, {
                    x: 0.6, // 横坐标
                    y: 0.5,
                    color: "363636",
                    fontSize: 28, // 字号
                    bold: true,
                    align: "left",
                });
                const tempResult2 = array[i].task;
                _slide.addText(tempResult2, {
                    x: 0.6, // 横坐标
                    y: 1.5,
                    color: "363636",
                    fontSize: 18, // 字号
                    align: "left",
                });
                const tempResult3 = array[i].points;
                _slide.addText(tempResult3, {
                    x: 0.6, // 横坐标
                    y: 3,
                    w: "60%",
                    color: "363636",
                    fontSize: 18, // 字号
                    align: "left",
                });
            }

            // 获取PPTX文件的ArrayBuffer

            // 保存为 Blob 并处理
            pres.write("blob").then((blob) => {
                // 现在你有了一个 Blob 对象
                console.log(blob);

                const file = new File([blob], this.courseName+".pptx", {
                    type: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
                });
                console.log(pres);
                this.beforeUpload(file);
            });
        },
        beforeUpload(event) {
            var file = event;
            var credentials = {
                accessKeyId: "AKIATLPEDU37QV5CHLMH",
                secretAccessKey: "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",
            }; //秘钥形式的登录上传
            window.AWS.config.update(credentials);
            window.AWS.config.region = "cn-northwest-1"; //设置区域

            var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
            var _this = this;

            if (file) {
                var params = {
                    Key:
                        file.name.split(".")[0] +
                        new Date().getTime() +
                        "." +
                        file.name.split(".")[file.name.split(".").length - 1],
                    ContentType: file.type,
                    Body: file,
                    "Access-Control-Allow-Credentials": "*",
                    ACL: "public-read",
                }; //key可以设置为桶的相抵路径，Body为文件， ACL最好要设置
                var options = {
                    partSize: 2048 * 1024 * 1024,
                    queueSize: 2,
                    leavePartsOnError: true,
                };
                bucket
                    .upload(params, options)
                    .on("httpUploadProgress", function (evt) {
                        //这里可以写进度条
                        // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
                    })
                    .send(function (err, data) {
                        _this.loading = false;
                        if (err) {
                            _this.$message.error("上传失败");
                        } else {
                            _this.url = data.Location;
                            _this.uJson = {
                                name: file.name,
                                url: data.Location,
                                type: 3,
                            };
                            console.log(data.Location);
                        }
                    });
            }
        },
    },
};
</script>

<style scoped>
.dialog_diy>>>.el-dialog {
    height: auto;
    margin: 15vh auto 0 !important;
}

.dialog_diy>>>.el-dialog__header {
    background: #454545 !important;
    padding: 15px 20px;
}

.dialog_diy>>>.el-dialog__body {
    height: calc(100% - 124px);
    box-sizing: border-box;
    padding: 0px;
}

.dialog_diy>>>.el-dialog__title {
    color: #fff;
}

.dialog_diy>>>.el-dialog__headerbtn {
    top: 19px;
}

.dialog_diy>>>.el-dialog__headerbtn .el-dialog__close {
    color: #fff;
}

.dialog_diy>>>.el-dialog__headerbtn .el-dialog__close:hover {
    color: #fff;
}

.dialog_diy>>>.el-dialog__body,
.dialog_diy>>>.el-dialog__footer {
    background: #fafafa;
}

.binfo_input {
    width: 100%;
    margin: 0;
    padding: 5px 7px;
    display: block;
    min-width: 0;
    outline: none;
    box-sizing: border-box;
    background: none;
    border: none;
    border-radius: 4px;
    background: #fff;
    font-size: 15px;
    resize: none;
    font-family: "Microsoft YaHei";
    min-height: 48px;
    /* border: 1px solid #3682fc00; */
    border: 1.5px solid #cad1dc;
}

.binfo_textarea {
    border: 1.5px solid #cad1dc;
    font-size: 15px;
    resize: none;
    /* background: #f6f6f6; */
    font-family: "Microsoft YaHei";
}

.binfo_input:focus-visible {
    border: 1.5px solid #3681fc !important;
}

.t_box {
    display: flex;
    margin-bottom: 15px;
}

.t_box>span:nth-child(1) {
    min-width: 80px;
    font-size: 16px;
    color: #000;
}
</style>