import _ from "lodash";

import APIException from "@/lib/exceptions/APIException.ts";
import EX from "@/api/consts/exceptions.ts";
import util from "@/lib/util.ts";
import { getCredit, receiveCredit, request } from "./core.ts";
import logger from "@/lib/logger.ts";
import { VideoTaskCache } from '@/api/VideoTaskCache.ts';

const DEFAULT_ASSISTANT_ID = "513695";
export const DEFAULT_MODEL = "jimeng-v-3.0";
const DRAFT_VERSION = "3.0.5";
const DRAFT_V_VERSION = "1.0.0";
const MODEL_MAP = {
  "jimeng-v-3.0": "dreamina_ic_generate_video_model_vgfm_3.0",
  "jimeng-v-3.0-pro": "dreamina_ic_generate_video_model_vgfm_3.0_pro",
};

export function getModel(model: string) {
  return MODEL_MAP[model] || MODEL_MAP[DEFAULT_MODEL];
}
//图片生成视频  首帧
export async function generateVideo(
  task_id: string,
  prompt: string,
  {
    images = [],
    isPro = false,
    duration = 5000,
    ratio = '9:16',
  }: {
    images: any[];  
    isPro: boolean;
    duration: number;
    ratio: string;
  },
  refreshToken: string
) {
  const videoTaskCache = VideoTaskCache.getInstance();
  videoTaskCache.startTask(task_id);

  try {
    let _model = DEFAULT_MODEL;
    if(isPro){
      _model = "jimeng-v-3.0-pro";
    }
    let video_gen_inputs:any = {
                      type: "",
                      id: util.uuid(),
                      min_version: DRAFT_V_VERSION,
                      prompt: prompt,
                      video_mode:2,
                      fps:24,
                      duration_ms:duration,
                    };
    if(!images || !images.length){
      //无图片
    }else if(images.length === 1){
      //首帧
      video_gen_inputs.first_frame_image = {
          type: "image",
          id: util.uuid(),
          source_from: "upload",
          platform_type: 1,
          name: "",
          image_uri: images[0].url,
          width: images[0].width,
          height: images[0].height,
          format: "",
          uri: images[0].url,
        }
    }else if(images.length >= 2){
      //首尾帧      
      video_gen_inputs.first_frame_image = {
          type: "image",
          id: util.uuid(),
          source_from: "upload",
          platform_type: 1,
          name: "",
          image_uri: images[0].url,
          width: images[0].width,
          height: images[0].height,
          format: "",
          uri: images[0].url,
        }
      video_gen_inputs.end_frame_image = {
          type: "image",
          id: util.uuid(),
          source_from: "upload",
          platform_type: 1,
          name: "",
          image_uri: images[1].url,
          width: images[1].width,
          height: images[1].height,
          format: "",
          uri: images[1].url,
        }
    }
  const model = getModel(_model);
  
  const { totalCredit } = await getCredit(refreshToken);
  if (totalCredit <= 0)
    await receiveCredit(refreshToken);

  const componentId = util.uuid();
  const originSubmitId = util.uuid();
  const { aigc_data } = await request(
    "post",
    "/mweb/v1/aigc_draft/generate",
    refreshToken,
    {
      params: {
        babi_param: encodeURIComponent(
          JSON.stringify({
            scenario: "image_video_generation",
            feature_key: "text_to_video",
            feature_entrance: "to_video",
            feature_entrance_detail: "to_image-text_to_video",
          })
        ),
      },
      data: {
        extend: {
          m_video_commerce_info: {
            resource_id: "generate_video",
            resource_id_type: "str",
            resource_sub_type: "aigc",
            benefit_type: "basic_video_operation_vgfm_v_three"
          },
          root_model: model,
          template_id: "",
          history_option: {},
        },
        submit_id: util.uuid(),
        metrics_extra: JSON.stringify({
          promptSource: "custom",
          originSubmitId: originSubmitId,
          isDefaultSeed: 1,
          originTemplateId: "",
          imageNameMapping: {},
        }),
        draft_content: JSON.stringify({
          type: "draft",
          id: util.uuid(),
          min_version: DRAFT_VERSION,
          min_features: [],
          is_from_tsn: true,
          version: "3.2.2",
          main_component_id: componentId,
          component_list: [
            {
              type: "video_base_component",
              id: componentId,
              min_version: DRAFT_V_VERSION,
              generate_type: "gen_video",
              aigc_mode: "workbench",
              metadata: {
                type: "",
                id: util.uuid(),
                created_platform: 3,
                created_platform_version: "",
                created_time_in_ms: Date.now(),
                created_did: "",
              },
              abilities: {
                type: "",
                id: util.uuid(),
                gen_video:{
                  type: "",
                  id: util.uuid(),
                  text_to_video_params:{
                    type: "",
                    id: util.uuid(),
                    video_gen_inputs:[video_gen_inputs],
                    video_aspect_ratio:ratio,
                    seed: Math.floor(Math.random() * 100000000) + 2500000000,
                    model_req_key: model,
                  },
                  video_task_extra:{
                    promptSource: "custom",
                    originSubmitId: originSubmitId,
                    isDefaultSeed: 1,
                    originTemplateId: "",
                    imageNameMapping: {},
                  }
                },
              },
              process_type:1,
            },
          ],
        }),
        http_common_info: {
          aid: Number(DEFAULT_ASSISTANT_ID),
        },
      },
    }
  );
  const historyId = aigc_data.history_record_id;
  if (!historyId)
    throw new APIException(EX.API_VIDEO_GENERATION_FAILED, "记录ID不存在");
  let status = 20, failCode, item_list = [];
  //https://jimeng.jianying.com/mweb/v1/get_history_by_ids?
  //
  let emptyCount = 30;
  while (status === 20) {
    await new Promise((resolve) => setTimeout(resolve, 10000));
    const result = await request("post", "/mweb/v1/get_history_by_ids", refreshToken, {
      data: {
        history_ids: [historyId],
        http_common_info: {
          aid: Number(DEFAULT_ASSISTANT_ID),
        },
      },
    });
    if (!result[historyId]){
      logger.warn(`记录ID不存在： ${historyId} 重试次数: ${emptyCount}`);
      emptyCount--;
      if(emptyCount<=0){
        throw new APIException(EX.API_HISTORY_EMPTY, "记录不存在： " + JSON.stringify(result));
      }else{
        status = 20;
        continue;
      }
    }      
    status = result[historyId].status;
    failCode = result[historyId].fail_code;
    const fail_msg = result[historyId].fail_msg;
    item_list = result[historyId].item_list;
  }
  if (status === 30) {
    if (failCode === '2038' || failCode == '2041') {
      throw new APIException(EX.API_CONTENT_FILTERED);
    } else {
      throw new APIException(EX.API_VIDEO_GENERATION_FAILED);
    }
  }
  // Assuming success if status is not 30 (failed) and not 20 (pending)
  // and item_list is populated.
  // A more robust check might be needed depending on actual API behavior for success.
  const videoUrls = item_list.map((item) => {
    let res_url = null;
    let vdata = item?.video?.transcoded_video||{};
    for(let key in vdata){
        if(vdata[key] && vdata[key].video_url){
            res_url = vdata[key].video_url;
            break;
        }
    }
    return res_url || null;
  });

  // Filter out nulls and check if any valid URL was generated
  const validVideoUrls = videoUrls.filter(url => url !== null);
  if (validVideoUrls.length > 0) {
    await videoTaskCache.finishTask(task_id, -1, validVideoUrls.join(",")); // Success
  } else {
    const errorMessage = "视频生成未返回有效链接";
    logger.error(`视频生成任务 ${task_id} 异常: ${errorMessage}`);
    // If no valid URLs but no explicit error thrown earlier, consider it a failure.
    // This could happen if item_list is empty or items don't have video_url.
    await videoTaskCache.finishTask(task_id, -2, "", errorMessage); // Failure
    throw new APIException(EX.API_VIDEO_GENERATION_FAILED, errorMessage);
  }
  return validVideoUrls;
} catch (error) {
  const errorMessage = error.message || "视频生成过程中发生未知错误";
  logger.error(`视频生成任务 ${task_id} 异常: ${errorMessage}`);
  await videoTaskCache.finishTask(task_id, -2, "", errorMessage); // Failure due to exception
  throw error; // Re-throw the error to be handled by the caller
}
}

export default {
  generateVideo,
};
