<template>
  <view class="aigc-use-template-page">
    <AigcTopBar :points="pointBalance" recharge-label="充值" @back="handleBack" @history="handleHistory"
      @recharge="handleRecharge" />

    <view class="aigc-use-template-body">
      <view class="aigc-use-template-content">
        <TemplateVersionHero :template="currentTemplate" />

        <GenerateConfirmPanel v-if="currentStep === 'generateConfirm'" :cost="currentCost" :balance="pointBalance"
          @generate="handleGenerate" @recharge="handleRecharge" />

        <template v-else>
          <VersionOptionList :options="templateItems" :selected-value="selectedTemplateItemId"
            @select="handleSelectTemplateItem" />

          <text class="aigc-use-template-note">
            动效视频版会先生图，再升级为 5 秒内动效视频。
          </text>
        </template>
      </view>
    </view>

    <view v-if="currentStep === 'uploadGuide'" class="aigc-use-template-popup-host">
      <PhotoGuidePanel :positive-examples="positiveExamples" :negative-examples="negativeExamples"
        @close="handleCloseGuide" @confirm="handleConfirmGuide" />
    </view>
    <view v-if="currentStep === 'photoPick'" class="aigc-use-template-popup-host">
      <PhotoPickDrawer :loading="isUploading" @close="handleCloseGuide" @camera="handlePickCamera"
        @album="handlePickAlbum" />
    </view>
    <view v-if="currentStep === 'photoConfirm'" class="aigc-use-template-popup-host">
      <PhotoConfirmDrawer :avatar-src="selectedImageLocalPath" @close="handleClosePhotoConfirm"
        @confirm="handleConfirmPhoto" />
    </view>
    <PointInsufficientDialog v-if="pointDialogVisible" :cost="currentCost" :balance="pointBalance"
      @cancel="handleClosePointDialog" @recharge="handlePointRecharge" />
    <Privacy :visible="privacyVisible" :contract-name="privacyContractName" @agree="handlePrivacyAgree"
      @disagree="handlePrivacyDisagree" />
  </view>
</template>

<script setup>
import { computed, ref } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import Privacy from "@/components/Privacy/index.vue";
import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue";
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
import { getWechatLoginCode } from "@/pages-aigc/services/wechatLogin.js";
import {
  createAigcGeneratorTask,
  getAigcTemplateItemList,
  getAigcTemplateList,
} from "@/request/api/AigcApi.js";
import { updateImageFile } from "@/request/api/UpdateFile.js";
import GenerateConfirmPanel from "./components/GenerateConfirmPanel/index.vue";
import PhotoConfirmDrawer from "./components/PhotoConfirmDrawer/index.vue";
import PhotoGuidePanel from "./components/PhotoGuidePanel/index.vue";
import PhotoPickDrawer from "./components/PhotoPickDrawer/index.vue";
import PointInsufficientDialog from "./components/PointInsufficientDialog/index.vue";
import TemplateVersionHero from "./components/TemplateVersionHero/index.vue";
import VersionOptionList from "./components/VersionOptionList/index.vue";
import { negativeExamples, positiveExamples } from "./data/photoGuideExamples.js";

const { pointBalance, fetchCurrentCredit } = useCurrentCredit();
const templateId = ref("");
const templates = ref([]);
const templateItems = ref([]);
const selectedTemplateItemId = ref("");
const selectedImageLocalPath = ref("");
const uploadedImageUrl = ref("");
const currentStep = ref("version");
const pointDialogVisible = ref(false);
const isUploading = ref(false);
const isCreatingTask = ref(false);
const privacyVisible = ref(false);
const privacyContractName = ref("隐私保护指引");
const pendingImageSourceType = ref("");

const currentTemplate = computed(() => {
  return templates.value.find((item) => item.templateId === templateId.value) || templates.value[0] || {};
});

const currentTemplateItem = computed(() => {
  return (
    templateItems.value.find((item) => item.templateItemId === selectedTemplateItemId.value) ||
    templateItems.value[0] ||
    {}
  );
});

const currentCost = computed(() => {
  return Number(currentTemplateItem.value.generatorCost) || 0;
});

const showPlaceholderToast = (title) => {
  uni.showToast({
    title,
    icon: "none",
  });
};

const resetSelectedPhoto = () => {
  selectedImageLocalPath.value = "";
  uploadedImageUrl.value = "";
};

const fetchTemplateList = async () => {
  try {
    const res = await getAigcTemplateList();
    if (res?.code === 0 && Array.isArray(res.data)) {
      templates.value = res.data;
      if (!templateId.value && res.data[0]?.templateId) {
        templateId.value = res.data[0].templateId;
      }
    }
  } catch (error) {
    console.warn("获取AIGC模板列表失败", error);
  }
};

const fetchTemplateItemList = async () => {
  if (!templateId.value) {
    templateItems.value = [];
    selectedTemplateItemId.value = "";
    return;
  }

  try {
    const res = await getAigcTemplateItemList({ templateId: templateId.value });
    if (res?.code === 0 && Array.isArray(res.data)) {
      templateItems.value = res.data;
      selectedTemplateItemId.value = res.data[0]?.templateItemId || "";
    }
  } catch (error) {
    console.warn("获取AIGC模板生成项失败", error);
  }
};

const fetchPageData = async () => {
  await fetchTemplateList();
  await fetchTemplateItemList();
};

onLoad((query = {}) => {
  templateId.value = query.templateId || "";
  fetchPageData();
});

onShow(() => {
  fetchCurrentCredit();
});

const handleBack = () => {
  const pages = getCurrentPages();
  if (pages.length > 1) {
    uni.navigateBack();
  }
};

const handleHistory = () => {
  uni.navigateTo({
    url: "/pages-aigc/record/record",
    fail: () => showPlaceholderToast("最近任务"),
  });
};

const handleRecharge = () => {
  uni.navigateTo({
    url: "/pages-aigc/recharge/recharge",
    fail: () => showPlaceholderToast("积分充值"),
  });
};

const handleSelectTemplateItem = (option) => {
  if (!option?.templateItemId) return;

  selectedTemplateItemId.value = option.templateItemId;
  resetSelectedPhoto();
  currentStep.value = "uploadGuide";
};

const handleCloseGuide = () => {
  currentStep.value = "version";
};

const handleConfirmGuide = () => {
  currentStep.value = "photoPick";
};

const getChosenFilePath = (res) => {
  return res?.tempFiles?.[0]?.tempFilePath || res?.tempFilePaths?.[0] || res?.tempFiles?.[0]?.path || "";
};

const isChooseCanceled = (error) => {
  const message = String(error?.errMsg || error?.message || "");
  return message.includes("cancel") || message.includes("取消");
};

const handleChooseImageSuccess = async (res) => {
  const filePath = getChosenFilePath(res);
  if (!filePath) {
    showPlaceholderToast("请选择图片");
    return;
  }

  selectedImageLocalPath.value = filePath;
  uploadedImageUrl.value = "";
  isUploading.value = true;
  uni.showLoading({
    title: "上传中",
    mask: true,
  });

  try {
    const uploadRes = await updateImageFile(filePath);
    if (uploadRes?.code === 0 && uploadRes.data) {
      uploadedImageUrl.value = uploadRes.data;
      currentStep.value = "photoConfirm";
    } else {
      resetSelectedPhoto();
      showPlaceholderToast(uploadRes?.msg || "图片上传失败");
    }
  } catch (error) {
    resetSelectedPhoto();
    console.warn("上传AIGC生成图片失败", error);
    showPlaceholderToast("图片上传失败");
  } finally {
    isUploading.value = false;
    uni.hideLoading();
  }
};

const handleChooseImageFail = (error) => {
  if (!isChooseCanceled(error)) {
    console.warn("选择AIGC生成图片失败", error);
    showPlaceholderToast("选择图片失败");
  }
};

const chooseImageWithSource = (sourceType) => {
  // #ifdef MP-WEIXIN
  uni.chooseMedia({
    count: 1,
    mediaType: ["image"],
    sourceType: [sourceType],
    sizeType: ["compressed"],
    success: handleChooseImageSuccess,
    fail: handleChooseImageFail,
  });
  // #endif

  // #ifndef MP-WEIXIN
  uni.chooseImage({
    count: 1,
    sizeType: ["compressed"],
    sourceType: [sourceType],
    success: handleChooseImageSuccess,
    fail: handleChooseImageFail,
  });
  // #endif
};

const chooseAndUploadImage = (sourceType) => {
  if (isUploading.value || pendingImageSourceType.value) return;

  // #ifdef MP-WEIXIN
  pendingImageSourceType.value = sourceType;
  wx.getPrivacySetting({
    success: (res) => {
      if (res?.needAuthorization) {
        privacyContractName.value = res.privacyContractName || "隐私保护指引";
        privacyVisible.value = true;
        return;
      }

      pendingImageSourceType.value = "";
      chooseImageWithSource(sourceType);
    },
    fail: (error) => {
      pendingImageSourceType.value = "";
      console.warn("检查微信隐私授权失败", error);
      showPlaceholderToast("隐私授权检查失败");
    },
  });
  // #endif

  // #ifndef MP-WEIXIN
  chooseImageWithSource(sourceType);
  // #endif
};

const handlePrivacyAgree = () => {
  const sourceType = pendingImageSourceType.value;
  privacyVisible.value = false;
  pendingImageSourceType.value = "";

  if (sourceType) {
    chooseImageWithSource(sourceType);
  }
};

const handlePrivacyDisagree = () => {
  privacyVisible.value = false;
  pendingImageSourceType.value = "";
};

const handlePickCamera = () => {
  chooseAndUploadImage("camera");
};

const handlePickAlbum = () => {
  chooseAndUploadImage("album");
};

const handleClosePhotoConfirm = () => {
  currentStep.value = "photoPick";
};

const handleConfirmPhoto = () => {
  if (!uploadedImageUrl.value) {
    showPlaceholderToast("请先上传图片");
    currentStep.value = "photoPick";
    return;
  }

  currentStep.value = "generateConfirm";
};

const handleGenerate = async () => {
  if (isCreatingTask.value) return;

  const templateItemId = currentTemplateItem.value.templateItemId;
  if (!templateItemId) {
    showPlaceholderToast("请选择生成类型");
    return;
  }

  if (!uploadedImageUrl.value) {
    showPlaceholderToast("请先上传图片");
    currentStep.value = "photoPick";
    return;
  }

  const cost = currentCost.value;
  const balance = Number(pointBalance.value) || 0;

  if (balance < cost) {
    pointDialogVisible.value = true;
    return;
  }

  isCreatingTask.value = true;
  uni.showLoading({
    title: "创建中",
    mask: true,
  });

  try {
    const wxLoginCode = await getWechatLoginCode();
    const res = await createAigcGeneratorTask({
      templateItemId,
      imageUrlList: [uploadedImageUrl.value],
      wxLoginCode,
    });

    const taskId = String(res?.data || "").trim();
    if (res?.code === 0 && taskId) {
      fetchCurrentCredit();
      uni.redirectTo({
        url: `/pages-aigc/progress/progress?taskId=${encodeURIComponent(taskId)}`,
        fail: () => showPlaceholderToast("打开任务进度失败"),
      });
    } else {
      showPlaceholderToast(res?.msg || "创建任务失败");
    }
  } catch (error) {
    console.warn("创建AIGC生成任务失败", error);
    showPlaceholderToast("创建任务失败");
  } finally {
    uni.hideLoading();
    isCreatingTask.value = false;
  }
};

const handleClosePointDialog = () => {
  pointDialogVisible.value = false;
};

const handlePointRecharge = () => {
  pointDialogVisible.value = false;
  handleRecharge();
};
</script>

<style scoped lang="scss">
@import "./styles/index.scss";
</style>
