<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import { Sunny, UploadFilled } from "@element-plus/icons-vue";
import { ElMessage, ElLoading } from "element-plus";
import text2videoService from "@/api/service/text2videoService";
import utils from "@/utils/utils";
import { useManyValues } from './compositions/useManyValues'

const debug = ref(true);
const loading = ref(false);
const default_data = useManyValues();
const form = reactive({
  screen: default_data.screen,
  if_need_subtitle: default_data.if_need_subtitle,
  chatgpt_prompt: "",
  chatgpt_answer: "",
  chatgpt_answer_roles: <Wm.RolesItem[]>[],
  adapt_result_json: <Wm.ScriptsItem[]>[],
  task_id: "",
  final_video: "",
});
const sd_prompt_prefix = default_data.sd_prompt_prefix;
const sd_negative_prompt_prefix = default_data.sd_negative_prompt_prefix;

onMounted(() => {
  onChangeScreen(form.screen);
});

const onSubmitGpt = () => {
  text2videoService
    .submitGpt(form.chatgpt_prompt)
    .then((result: string) => {
      console.log(form.chatgpt_prompt);
      console.log(result);
      form.chatgpt_answer = result;
    })
    .catch((error: any) => {
      // console.error(error);
      ElMessage({
        message: error,
        type: "error",
      });
    });
};

const onAdaptRoles = async () => {
  if (!form.chatgpt_answer || form.chatgpt_answer.length == 0) {
    ElMessage({
      message: "文案不能为空",
      type: "error",
    });
    return;
  }
  loading.value = true;
  // 推理角色
  try {
    const adapt_restrict = `
    指令：
    请理解这个故事，给出这个故事的所有角色、角色关键词（性别(可以发挥想象进行补充，但一定要明确),年龄(可以发挥想象进行补充，但一定要明确),
    肤色(可以发挥想象进行补充，但一定要明确),衣服(可以发挥想象进行补充，但一定要明确),发型(可以发挥想象进行补充，但一定要明确),发色(可以发挥想象进行补充，但一定要明确),
    脸色(可以发挥想象进行补充，但一定要明确),五官特点(可以发挥想象进行补充，但一定要明确)）。\n
    要求：
    角色和角色关键词要对应。
    严格以如下格式返回：[{"角色":"","角色关键词":""}]`;
    const keywords = await text2videoService.submitGpt(form.chatgpt_answer + "\n" + adapt_restrict);
    console.log(keywords)
    const keywords_obj = utils.formatJsonObj(keywords.replace(/```json/g, '').replace(/```/g, ''))
    console.log(keywords_obj)
    form.chatgpt_answer_roles = []
    for (let item of keywords_obj) {
      let newObjItem = {
        "角色": JSON.stringify(item["角色"]).replace(/"/g, ''),
        "角色关键词": JSON.stringify(item["角色关键词"]).replace(/"/g, '')
      };
      form.chatgpt_answer_roles.push(newObjItem);
    }
    console.log(form.chatgpt_answer_roles)
  } catch (error) {
    ElMessage({
      message: String(error),
      type: "error",
    });
  } finally {
    // 最终关闭loading（无论成功或失败）
    loading.value = false;
  }
};

const onAdapt = async () => {
  if (!form.chatgpt_answer || form.chatgpt_answer.length == 0) {
    ElMessage({
      message: "文案不能为空",
      type: "error",
    });
    return;
  }
  loading.value = true;
  form.task_id = utils.genDateTimeStr();
  console.log(form.task_id)
  // 按标点拆分成分镜
  const sentences = utils.splitText(form.chatgpt_answer);
  console.log(sentences.length)
  // 分镜
  form.adapt_result_json = []
  for (let i = 0; i < sentences.length; i++) {
    form.adapt_result_json.push({
      "编号": (i + 1).toString(),
      "场景描述": sentences[i].trim(),
      "场景关键词": "",
      "角色": "",
      "角色关键词": "",
      "画面描述词": "",
      "本镜配图": "",
      "local_image_path": "",
    });
  }
  console.log(form.adapt_result_json)

  const delay = (ms: any) => new Promise(res => setTimeout(res, ms));

  async function processScenes() {
    for (const item of form.adapt_result_json) {
      await onAdaptOne(item);
      await delay(1000);
      await onDrawOne(item);
    }
  }

  try {
    await processScenes();
    ElMessage({
      message: "all scene ok",
      type: "success"
    });
    console.log(form.adapt_result_json);
  } catch (error) {
    ElMessage({
      message: String(error),
      type: "error"
    });
  } finally {
    loading.value = false; // 最终关闭loading（无论成功或失败）
  }

};

const onAdaptOne = async (item: any) => {
  if (!item.场景描述) {
    ElMessage({
      message: "分镜场景描述不能为空",
      type: "error",
    });
    return;
  }
  // 推理关键词
  try {
    const adapt_restrict = `
    指令：
    请理解这个故事，针对其中的这个场景：“${item.场景描述}”，给出这个场景的：
    场景关键词（年代,空间,时间段,地理环境,天气,物品,人物,镜头角度）、
    角色(从所有角色中选择本场景的角色)、
    角色关键词（从所有角色中选择本场景的角色关键字，原样拷贝）。
    要求：
    角色和角色关键词要对应。
    严格以如下格式返回：[{"场景关键词":"（多个词以逗号分隔）","角色":"（角色以逗号分隔）","角色关键词":"（分别给予对应角色的关键词，多个词以逗号分隔）"}]`;
    const keywords = await text2videoService.submitGpt("故事：\n" + form.chatgpt_answer + "\n所有角色：\n"+ JSON.stringify(form.chatgpt_answer_roles)+"\n" + adapt_restrict);
    // console.log(keywords)
    const keywords_obj = utils.formatJsonObj(keywords.replace(/```json/g, '').replace(/```/g, ''))
    // console.log(keywords_obj)
    item.场景关键词 = JSON.stringify(keywords_obj[0].场景关键词).replace(/"/g, '');
    item.角色 = JSON.stringify(keywords_obj[0].角色).replace(/"/g, '');
    item.角色关键词 = JSON.stringify(keywords_obj[0].角色关键词).replace(/"/g, '');
  } catch (error) {
    ElMessage({
      message: String(error),
      type: "error",
    });
  }
};

const onDrawOne = async (item: any) => {
  if (!item.编号 || !item.场景描述 || !item.场景关键词 || !item.角色 || !item.角色关键词) {
    ElMessage({
      message: "分镜参数不能为空",
      type: "error",
    });
    return;
  }
  // 翻译+画图
  if (!form.task_id) {
    form.task_id = utils.genDateTimeStr();
    console.log(form.task_id)
  }
  try {
    const sd_describe = await text2videoService.submitGpt(
      `场景描述为：${item.场景描述}\n场景关键词为：${item.场景关键词}\n场景中的角色有：${item.角色}\n角色关键词为：${item.角色关键词}\n
      指令：
      请理解以上内容，并返回一段英文的镜头描述。`
    );
    item.画面描述词 = sd_describe;
    const sd_prompt = item.画面描述词 + "," + sd_prompt_prefix;
    let width = "960";
    let height = "540";
    if (form.screen == "竖屏") {
      width = "540";
      height = "960";
    }
    console.log(sd_prompt);
    console.log(sd_negative_prompt_prefix);
    const sd_img = await text2videoService.submitSD(form.task_id, item.编号, sd_prompt, sd_negative_prompt_prefix, width, height);
    item.本镜配图 = sd_img.domain_image_path+"?v="+utils.genDateTimeStr();
    item.local_image_path = sd_img.local_image_path;
  } catch (error) {
    ElMessage({
      message: String(error),
      type: "error",
    });
  }
};

const onGenVideo = () => {
  if (!form.adapt_result_json || form.adapt_result_json.length == 0 ) {
    ElMessage({
      message: "必要信息不能为空，请重新执行",
      type: "error",
    });
    return;
  }
  let is_all_ok = true;
  form.adapt_result_json.map(item => {
    if (item.编号 == "" || item.场景描述 == "" || item.local_image_path == "") {
      ElMessage({
        message: `分镜 ${item.编号} 的必要信息为空，请重新执行`,
        type: "error",
      });
      is_all_ok = false;
    }
  });
  if (!is_all_ok) return;
  console.log(form.adapt_result_json);
  const video_param_detail = form.adapt_result_json.map(item => {
    return {
      idx: item.编号,
      text: item.场景描述,
      img_path: item.local_image_path
    };
  });
  const video_param = {
    task_id: form.task_id,
    if_need_subtitle: form.if_need_subtitle,
    task_info: video_param_detail,
  }
  text2videoService
    .submitGenVideo(video_param)
    .then((result: string) => {
      console.log(result);
      form.final_video = "";
      form.final_video = result+"?v="+utils.genDateTimeStr();
    })
    .catch((error: any) => {
      // console.error(error);
      ElMessage({
        message: error,
        type: "error",
      });
    });
};

const clean_demo = () => {
  form.chatgpt_prompt = "";
  form.chatgpt_answer = "";
  form.chatgpt_answer_roles = <Wm.RolesItem[]>[];
  form.adapt_result_json = <Wm.ScriptsItem[]>[];
  form.task_id = "";
  form.final_video = "";
}

const onChangeScreen = (val: string) => {
  if (debug.value == true) {
    if (val == "横屏") {
      form.task_id = default_data.horizontal_data.task_id;
      form.chatgpt_prompt = default_data.horizontal_data.chatgpt_prompt;
      form.chatgpt_answer = default_data.horizontal_data.chatgpt_answer;
      form.chatgpt_answer_roles = default_data.horizontal_data.chatgpt_answer_roles;
      form.adapt_result_json = default_data.horizontal_data.adapt_result_json;
      form.final_video = default_data.horizontal_data.final_video;
    } else {
      form.task_id = default_data.vertical_data.task_id;
      form.chatgpt_prompt = default_data.vertical_data.chatgpt_prompt;
      form.chatgpt_answer = default_data.vertical_data.chatgpt_answer;
      form.chatgpt_answer_roles = default_data.vertical_data.chatgpt_answer_roles;
      form.adapt_result_json = default_data.vertical_data.adapt_result_json;
      form.final_video = default_data.vertical_data.final_video;
    }
  }
}

const showsdpromt = (item: any) => {
  alert(item.画面描述词)
}
</script>

<template>
  <main class="home-container">
    <!-- 标题 -->
    <el-divider content-position="left">text2video</el-divider>
    <el-form :model="form" label-width="114px" v-loading="loading">
      <el-form-item>
        <div>
          <el-radio-group v-model="form.screen" @change="onChangeScreen">
            <el-radio label="横屏" size="large" border/>
            <el-radio label="竖屏" size="large" border/>
          </el-radio-group>
        </div>
      </el-form-item>
      <el-form-item>
        <el-button type="success" @click="clean_demo">清除示例数据</el-button>
      </el-form-item>
      <!-- Prompt到文案 -->
      <el-form-item label="Prompt">
        <el-input v-model="form.chatgpt_prompt" :autosize="true" type="textarea" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmitGpt">生成文案</el-button>
      </el-form-item>
      <el-form-item label="文案">
        <el-input v-model="form.chatgpt_answer" :autosize="true" type="textarea" />
      </el-form-item>
      <!-- 角色 -->
      <el-form-item>
        <el-button type="primary" @click="onAdaptRoles">推理所有角色</el-button>
      </el-form-item>
      <el-form-item label="角色">
        <el-table :data="form.chatgpt_answer_roles" border style="width: 100%; z-index: calc(var(--el-table-index) -1)">
          <el-table-column prop="角色" label="角色">
            <template v-slot="scope">
              <el-input v-model="scope.row.角色" :autosize="true" type="textarea"></el-input>
            </template>
          </el-table-column>
          <el-table-column prop="角色关键词" label="角色关键词">
            <template v-slot="scope">
              <el-input v-model="scope.row.角色关键词" :autosize="true" type="textarea"></el-input>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <!-- 分镜 -->
      <el-form-item>
        <el-button type="primary" @click="onAdapt">分镜、推理关键词、绘图</el-button>
      </el-form-item>
      <el-form-item label="分镜">
        <el-table :data="form.adapt_result_json" border style="width: 100%; z-index: calc(var(--el-table-index) -1)">
          <el-table-column prop="编号" label="编号" width="60" />
          <el-table-column prop="场景描述" label="场景描述">
            <template v-slot="scope">
              <el-input v-model="scope.row.场景描述" :autosize="true" type="textarea"></el-input>
            </template>
          </el-table-column>
          <el-table-column prop="场景关键词" label="场景关键词">
            <template v-slot="scope">
              <el-input v-model="scope.row.场景关键词" :autosize="true" type="textarea"></el-input>
            </template>
          </el-table-column>
          <el-table-column prop="角色" label="角色">
            <template v-slot="scope">
              <el-input v-model="scope.row.角色" :autosize="true" type="textarea"></el-input>
            </template>
          </el-table-column>
          <el-table-column prop="角色关键词" label="角色关键词">
            <template v-slot="scope">
              <el-input v-model="scope.row.角色关键词" :autosize="true" type="textarea"></el-input>
            </template>
          </el-table-column>
          <el-table-column prop="本镜配图" label="本镜配图" width="300">
            <template v-slot="scope">
              <div>
                <el-image :src="scope.row.本镜配图" :zoom-rate="1.2" :max-scale="1.5" :min-scale="0.5"
                  :preview-src-list="[scope.row.本镜配图]" fit="cover" :hide-on-click-modal="true"
                />
              </div>
            </template>
          </el-table-column>
          <el-table-column width="120" label="操作" align="center">
            <!-- 
            <template v-slot:header>
              <el-button type="danger" size="default" @click="">批量绘制所有图片</el-button>
            </template> 
            -->
            <template v-slot="scope">
              <div style="margin: 10px 0"><el-button type="primary" size="default" @click="onAdaptOne(scope.row)">重新推理<br />关键字</el-button></div>
              <div style="margin: 10px 0"><el-button type="primary" size="default" @click="onDrawOne(scope.row)">重绘本镜</el-button></div>
              <div style="margin: 10px 0"><el-button type="primary" size="small" @click="showsdpromt(scope.row)">show sd promt</el-button></div>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <!-- 生成视频 -->
      <el-form-item>
        <el-button type="primary" @click="onGenVideo">生成视频</el-button>
      </el-form-item>
      <el-form-item>
        <video :src="form.final_video" controls></video>
      </el-form-item>
    </el-form>
  </main>
</template>

<style lang="scss" scoped>
.home-container {
  width: 100%;
}
</style>

<style lang="scss">
.home-container {
  .el-table .el-table__cell {
    z-index: calc(var(--el-table-index) -1);
  }
}
</style>
