<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'

const loading = ref(false)
const step = ref(1);
const is_adapt_result_json = ref(1)
const form = reactive({
  chatgpt_prompt: "帮我生成一个关于医生穿越到古代行侠仗义的故事，约200字左右",
  chatgpt_answer: "曾经的医生王强穿越回了古代，发现这个时代正值战乱时期。他觉得自己是时候行侠仗义，保护那些无辜受苦的人们了。王强在一个村庄里遇到了一个年轻的农民，叫李明。李明父母在战乱中被杀，他成了孤儿，并且被恶势力欺压。王强决定帮助李明。他教授李明一些基本的医术，并且帮助他恢复村庄的秩序。为了支援农民，王强到处奔走，为那些受伤的人们进行治疗。他在古代用现代医学知识，快速治愈了一些以前无法治愈的疾病。他趁机收集了一群志同道合的人，组建了一个抗击恶势力的义勇军。由于他的医术悉心教导，王强手下的队伍战斗力大增，并且开始挑战恶势力的统治。在战斗中，王强发现一支正义的侠盗团队正在保护受苦的人们。他决定与他们合作，将农民们和侠盗团队联合起来，共同对抗恶势力。最终，王强和他的队伍，还有侠盗团队成功地将恶势力赶出了村庄，恢复了和平。他们在古代留下了无穷的传奇，为人们带来了新的希望和幸福。医生王强也与李明成了好朋友，他们一起守护着村庄的和平与安宁。",
  adapt_restrict: '将上述文案改编为10个短视频分镜，给出每个分镜的场景描述、场景关键词（年代,空间,时间段,地理环境,天气,物品,人物,镜头角度）、角色、角色关键词（性别,年龄,肤色,衣服,发型,发色,脸色,五官特点,体态,情绪,肢体动作）。以如下json字符串的格式返回：{"分镜":[{"编号":"","场景描述":"","场景关键词":"","角色":"","角色关键词":""},...]}',
  adapt_result: "",
  // adapt_result_json: <Wm.ScriptsItem[]>[],
  // adapt_result_json: [{"编号":"1","场景描述":"王强穿越回古代，来到一片战乱的村庄。","场景关键词":"古代,村庄,战乱,医生,王强","角色":"王强","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注"},{"编号":"2","场景描述":"王强在村庄遇见年轻的农民李明。","场景关键词":"村庄,农民,相遇","角色":"王强,李明","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注;男性,青年,普通,农民服装,干净,精明,忧伤"},{"编号":"3","场景描述":"王强教授李明基本的医术。","场景关键词":"教学,医术,基本","角色":"王强,李明","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注;男性,青年,普通,农民服装,干净,精明,忧伤"},{"编号":"4","场景描述":"王强帮助李明恢复村庄秩序。","场景关键词":"村庄,恢复秩序","角色":"王强,李明","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注;男性,青年,普通,农民服装,干净,精明,忧伤"},{"编号":"5","场景描述":"王强在古代使用现代医学知识治愈疾病。","场景关键词":"古代,医学知识,治愈疾病","角色":"王强","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注"},{"编号":"6","场景描述":"王强组建抗击恶势力的义勇军。","场景关键词":"抗击恶势力,义勇军","角色":"王强","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注"},{"编号":"7","场景描述":"王强与正义的侠盗团队合作。","场景关键词":"侠盗团队,合作","角色":"王强","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注"},{"编号":"8","场景描述":"王强、李明和侠盗团队共同对抗恶势力。","场景关键词":"共同对抗,恶势力","角色":"王强,李明","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注;男性,青年,普通,农民服装,干净,精明,忧伤"},{"编号":"9","场景描述":"王强和他的队伍驱逐恶势力，村庄恢复和平。","场景关键词":"驱逐恶势力,村庄和平","角色":"王强,李明","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注;男性,青年,普通,农民服装,干净,精明,忧伤"},{"编号":"10","场景描述":"王强和李明成为好朋友，守护村庄的和平与安宁。","场景关键词":"好朋友,守护和平,安宁","角色":"王强,李明","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注;男性,青年,普通,农民服装,干净,精明,忧伤"}],
  adapt_result_json: [
    {"编号":"1","场景描述":"王强穿越回古代，来到一片战乱的村庄。","场景关键词":"古代,村庄,战乱,医生,王强","角色":"王强","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注"},
    {"编号":"2","场景描述":"王强在村庄遇见年轻的农民李明。","场景关键词":"村庄,农民,相遇","角色":"王强,李明","角色关键词":"男性,中年,普通,白大褂,干练,自信,坚定,专注;男性,青年,普通,农民服装,干净,精明,忧伤"}
  ],
  // ai_draw_json: <Wm.AiDrawItem[]>[],
  ai_draw_json: [
    {"编号":"1","场景描述":"王强穿越回古代，来到一片战乱的村庄。","画面描述词":"Ancient, village, warfare, doctor, Wang Qiang, male, middle-aged, ordinary, white coat, capable, confident, determined, focused","本镜配图":"http://192.168.31.128:5001/assets/outputs/20240129175223829/1.png","task_id":"20240129175223829"},
    {"编号":"2","场景描述":"王强在村庄遇见年轻的农民李明。","画面描述词":"Village, farmer, encounter, middle-aged, ordinary, white coat, capable, confident, determined, focused; male, young, ordinary, farmer's clothing, clean, astute, sad","本镜配图":"http://192.168.31.128:5001/assets/outputs/20240129175223829/2.png","task_id":"20240129175223829"},
  ],


});

const sd_prompt_prefix = `best quality,masterpiece,realistic,HDR,UHD,8K,best quality,highres,absurdres,realistic,masterpiece,
Highly detailed,extreme detail description,Professional,lens_flare,cinematic_lighting,ultra-fine painting,
full body,Vivid Colors,physically-based rendering,sharp focus,wide shot,cinematic,lens_flare,reality_ray_tracing,`

const sd_negative_prompt_prefix = `multiple breasts, (mutated hands and fingers:1.5 ), (long body :1.3), 
(mutation, poorly drawn :1.2) , black-white, bad anatomy, liquid body, liquid tongue, disfigured, 
malformed, mutated, anatomical nonsense, malformed hands, long neck, blurred, 
lowers, bad proportions, bad shadow, uncoordinated body, unnatural body, fused breasts, 
bad breasts, huge breasts, poorly drawn breasts, extra breasts, liquid breasts, heavy breasts, missing breasts, 
huge haunch, huge thighs, huge calf, bad hands, fused hand, missing hand, disappearing arms, disappearing thigh, 
disappearing calf, disappearing legs, fused ears, bad ears, poorly drawn ears, extra ears, liquid ears, heavy ears, 
missing ears, fused animal ears, bad animal ears, poorly drawn animal ears, extra animal ears, liquid animal ears, 
heavy animal ears, missing animal ears, text, ui, error, missing fingers, missing limb, fused fingers, 
one hand with more than 5 fingers, one hand with less than 5 fingers, one hand with more than 5 digit, 
one hand with less than 5 digit, extra digit, fewer digits, fused digit, missing digit, bad digit, liquid digit, 
colorful tongue, black tongue, cropped, watermark, username, blurry, JPEG artifacts, signature, 3D, 3D game, 
3D game scene, 3D character, malformed feet, extra feet, bad feet, poorly drawn feet, fused feet, missing feet, 
extra shoes, bad shoes, fused shoes, more than two shoes, poorly drawn shoes, bad gloves, poorly drawn gloves, 
fused gloves, bad cum, poorly drawn cum, fused cum, bad hairs, poorly drawn hairs, fused hairs, big muscles, ugly, 
bad face, fused face, poorly drawn face, cloned face, big face, long face, bad eyes, fused eyes poorly drawn eyes, 
extra eyes, malformed limbs, more than 2 nipples, missing nipples, different nipples, fused nipples, bad nipples, 
poorly drawn nipples, black nipples, colorful nipples, gross proportions. short arm, (((missing arms))), missing thighs, 
missing calf, missing legs, mutation, duplicate, morbid, mutilated, poorly drawn hands, more than 1 left hand, 
more than 1 right hand, deformed, (blurry), disfigured, missing legs, extra arms, extra thighs, more than 2 thighs, 
extra calf, fused calf, nsfw,logo,text,extra legs, bad knee, extra knee, more than 2 legs, bad tails, bad mouth, 
fused mouth, poorly drawn mouth, bad tongue, tongue within mouth, too long tongue, black tongue, big mouth, cracked mouth, 
bad mouth, dirty face, dirty teeth, dirty pantie, fused pantie, poorly drawn pantie, fused cloth, poorly drawn cloth, bad pantie, 
yellow teeth, thick lips, bad cameltoe, colorful cameltoe, bad asshole, poorly drawn asshole, fused asshole, missing asshole, 
bad anus, bad pussy, bad crotch, bad crotch seam, fused anus, fused pussy, fused anus, fused crotch, poorly drawn crotch, 
fused seam, poorly drawn anus, poorly drawn pussy, poorly drawn crotch, poorly drawn crotch seam, bad thigh gap, missing thigh gap, 
fused thigh gap, liquid thigh gap, poorly drawn thigh gap, poorly drawn anus, bad collarbone, fused collarbone, missing collarbone, 
liquid collarbone, obesity, worst quality, low quality, normal quality, liquid tentacles, bad tentacles, poorly drawn tentacles, 
split tentacles, fused tentacles, missing clit, bad clit, fused clit, colorful clit, black clit, liquid clit, QR code, bar code, censored, 
safety panties, safety knickers, beard, furry ,pony, pubic hair, mosaic, excrement, faeces, shit, futa, testis,mutated hands and fingers,
deformed,bad anatomy,disfigured,poorly drawn face,lowres,mutated,extra limb,ugly,poorly drawn hands,missing limb,floating limbs,
disconnected limbs,malformed hands,out of focus,long neck,long body,gape,`



onMounted(() => {});

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

const onAdapt = () => {
  if (!form.chatgpt_answer) {
    ElMessage({
      message: "内容不能为空",
      type: "error",
    });
    return
  }
  text2videoService
    .submitGpt(form.chatgpt_answer + '\n' + form.adapt_restrict)
    .then((result: string) => {
      console.log(result);
      try {
        form.adapt_result_json = utils.formatJsonObj(result).分镜
      } catch (error) {
        form.adapt_result = result
        is_adapt_result_json.value = 0
      }
    })
    .catch((error: any) => {
      console.error(error);
      ElMessage({
        message: error,
        type: "error",
      });
    });
};

// const drawOne = async (task_id: string, item_idx: string, sd_prompt: string, sd_negative_prompt: string) => {
//   try {
//     const sd_result = await text2videoService.submitSD(task_id, item_idx, sd_prompt, sd_negative_prompt);
//     return sd_result
//   } catch (error) {
//     return ""
//   }
// };

const onDraw = async () => {
  form.ai_draw_json = []
  loading.value = true;
  const task_id = utils.genDateTimeStr();
  const taskPromises = form.adapt_result_json.map(async (item) => {
    try {
      const result = await text2videoService.submitGpt(`请将这些内容“${item.场景关键词},${item.角色关键词}”翻译为英文`);
      const newResult = result.replaceAll('.', '').replaceAll('"', '');
      try {
        const sd_prompt = sd_prompt_prefix + newResult;
        const sd_result = await text2videoService.submitSD(task_id, item.编号, sd_prompt, sd_negative_prompt_prefix);
        return { 
          编号: item.编号,
          场景描述: item.场景描述,
          画面描述词: newResult,
          本镜配图: sd_result,
          task_id: task_id
        };
      } catch (error) {
        ElMessage({
          message: String(error),
          type: "error",
        });
        return { 
          编号: item.编号,
          场景描述: item.场景描述,
          画面描述词: newResult,
          本镜配图: "",
          task_id: task_id
        };
      }
    } catch (error) {
      // console.error(error);
      ElMessage({
        message: String(error),
        type: "error",
      });
      return { 
        编号: item.编号,
        场景描述: item.场景描述,
        画面描述词: "",
        本镜配图: "",
        task_id: task_id
      };
    }
  });
  // 所有请求都返回后，重新排序
  try {
    const results = await Promise.all(taskPromises);
    form.ai_draw_json = results.sort((a, b) => parseInt(a.编号) - parseInt(b.编号));
  } catch (error) {
    // 处理错误
    ElMessage({
      message: String(error),
      type: "error",
    });
  } finally {
    // 最终关闭loading（无论成功或失败）
    loading.value = false;
  }
};

const onDrawOne = (idxStr: string) => {
  const idx = parseInt(idxStr) - 1
  const task_id = form.ai_draw_json[idx].task_id;
  // console.log(task_id)
  const newResult = form.ai_draw_json[idx].画面描述词;
  text2videoService
    .submitSD(task_id, idxStr, newResult, sd_negative_prompt_prefix)
    .then((result: string) => {
      // console.log(result);
      form.ai_draw_json[idx].本镜配图 = result
    })
    .catch((error: any) => {
      // console.error(error);
      ElMessage({
        message: error,
        type: "error",
      });
    });
};

</script>

<template>
  <main class="home-container">
    <!-- 标题 -->
    <el-divider content-position="left">text2video</el-divider>
    <el-form :model="form" label-width="114px">
      <!-- 小说到文案 -->
      <el-form-item label="小说">
        <el-input
          v-model="form.chatgpt_prompt"
          :autosize=true
          type="textarea"
          placeholder="输入小说"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmitGpt">提交chatgpt，生成文案</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 label="分镜要求">
        <el-input
          v-model="form.adapt_restrict"
          :autosize=true
          type="textarea"
          placeholder=""
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onAdapt">填写或修改分镜要求，提交chatgpt，生成分镜</el-button>
      </el-form-item>
      <el-form-item label="分镜结果" v-if="is_adapt_result_json === 0">
        <el-input
          v-model="form.adapt_result"
          :autosize=true
          type="textarea"
        />
      </el-form-item>
      <el-form-item label="分镜结果" v-if="is_adapt_result_json === 1">
        <el-table :data="form.adapt_result_json" border style="width: 100%">
          <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 width="100">
            <template #header>
              <el-button type="primary" size="small" @click="">一键推理</el-button>
            </template>
            <template #default="scope">
              <el-button type="primary" size="small" @click="">推理</el-button>
            </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 width="100">
            <template #header>
              <el-button type="primary" size="small" @click="">一键推理</el-button>
            </template>
            <template #default="scope">
              <el-button type="primary" size="small" @click="">推理</el-button>
            </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="onDraw">组合SD提示词并绘图</el-button>
      </el-form-item>
      <el-form-item label="绘图">
        <el-table :data="form.ai_draw_json" border style="width: 100%; z-index: calc(var(--el-table-index) -1);" v-loading="loading">
          <el-table-column prop="编号" label="编号" width="60"/>
          <el-table-column prop="场景描述" label="场景描述" />
          <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">
              <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="100" label="操作">
            <template v-slot="scope">
              <el-button type="primary" size="small" @click="onDrawOne(scope.row.编号)">重绘本镜</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>


      
    </el-form>
    
  </main>
</template>

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