<template>
  <!-- <div v-if="taskInfo && taskTypes.length"> -->
  <div class="task-production-detail">
    <div
      class="task-production-detail-header flex items-center justify-between"
      :class="[isMobile ? 'p-2' : 'p-4']"
    >
      <p
        class="text-white font-bold one-ell"
        :class="[isMobile ? 'mr-1 text-sm' : 'text-2xl ml-4']"
      >
        作品集
      </p>
      <div class="flex items-center gap-2 bg-[#b3d5ff] rounded-lg flex-1">
        <el-input
          v-model="searchForm.title"
          placeholder="请输入作品标题搜索对应作品"
          clearable
          @input="debouncedSearch"
        />
        <el-icon
          @click="search"
          class="text-[#0074FE] font-bold"
          :class="[isMobile ? 'mr-2 text-lg' : 'mr-4 ml-2 text-2xl']"
          ><Search
        /></el-icon>
      </div>
    </div>
    <!-- 滚动容器 ref 绑定 -->
    <div
      ref="scrollContainer"
      class="card-scroll-container"
      :class="[isMobile ? '' : 'px-4']"
      v-show="list && list.length"
    >
      <Waterfall
        :key="waterfallKey"
        :list="list"
        :type="currentTaskType"
        imgSelector="fileUrl"
        show-loading
        lazyload
        :breakpoints="waterfallBreakpoints"
        animation-effect="fadeInUp"
      >
        <template #default="{ item, url }">
          <div
            class="border rounded-md box-shadow-md rounded-xl overflow-hidden transition-all duration-300 card-item"
            style="box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08)"
            @click="handleCardClick(item)"
          >
            <img
              :src="url"
              class="w-full object-cover"
              loading="lazy"
              :style="
                item.width && item.height
                  ? {
                      height: calculateHeight(item.width, item.height) + 'px',
                    }
                  : {}
              "
            />
            <div
              class="flex gap-2 items-center justify-start"
              :class="[isMobile ? 'p-2' : 'p-4']"
            >
              <el-tag
                v-for="tag in item.tags.split(',')"
                :key="tag"
                size="small"
                plain
                round
                type="info"
                >{{ tag }}</el-tag
              >
            </div>
          </div>
        </template>
      </Waterfall>
      <!-- 加载状态提示 -->
      <div class="loading-tip">
        <span v-if="isLoading">加载中...</span>
        <span v-else-if="!hasMore">没有更多了</span>
      </div>
    </div>
    <el-empty
      v-show="!list || !list.length"
      style="height: calc(100vh - 80px)"
      description="没有更多了"
    />
  </div>

  <el-drawer
    v-if="!isMobile"
    v-model="visible"
    :size="500"
    @close="handleClose"
    fullscreen
    title="右键保存图片"
  >
    <div v-if="currentItem" class="detail-content">
      <img
        v-if="[MediaType.IMAGE, MediaType.IMAGE_TEXT].includes(currentTaskType)"
        :src="currentItem.fileUrl"
        @error="handleImageError"
      />
      <video
        v-if="[MediaType.VIDEO].includes(currentTaskType)"
        :src="currentItem.fileUrl"
        controls
      />
      <p
        v-if="[MediaType.IMAGE_TEXT, MediaType.TEXT].includes(currentTaskType)"
        class="text-md mt-4 align-left"
      >
        <el-button
          type="text"
          @click.stop="handleCopy(currentItem.content)"
          class="!p-0"
          size="small"
        >
          复制文案
        </el-button>
        {{ currentItem.content }}
      </p>
    </div>
    <template #footer>
      <span class="">右键保存图片</span>
      <el-button type="info" plain @click="handleClose">关闭</el-button>
      <!-- <el-button type="primary" @click="handleCopy(currentItem.content)">复制文案</el-button> -->
      <!-- 保存 -->
      <!-- <el-button type="primary" @click="handleSave">保存</el-button> -->
    </template>
  </el-drawer>
  <el-dialog
    v-if="isMobile"
    v-model="visible"
    :size="500"
    @close="handleClose"
    fullscreen
    title="长按保存图片"

  >
    <img
      :src="currentItem.fileUrl"
      class="h-[80vh] object-contain rounded-md mx-auto"
    />
    <template #footer>
      <el-button type="info" plain @click="handleClose">关闭</el-button>
      <!-- <el-button type="primary" @click="handleCopy(currentItem.content)">复制文案</el-button> -->
      <!-- 保存 -->
      <!-- <el-button type="primary" @click="handleSave">保存</el-button> -->
    </template>
  </el-dialog>
  <el-button
    v-show="showScrollToTop"
    type="primary"
    @click="scrollToTop"
    class="fixed bottom-4 right-4 z-10 transition-all duration-300"
    :icon="ArrowUp"
    circle
  ></el-button>
</template>

<script setup lang="ts">
import {
  ref,
  reactive,
  onMounted,
  onBeforeUnmount,
  nextTick,
  computed,
} from "vue";
import { useRoute } from "vue-router";
import { debounce, throttle } from "lodash-es"; // 记得安装lodash-es
import { showLoading, hiddenLoading } from "@/utils/loading";
import { showMsg } from "@/utils/showMsg";
// Element Plus 图标 + 组件
import { Refresh, ArrowLeft, Search, ArrowUp } from "@element-plus/icons-vue";
// 接口请求
import apis from "@/api/index";
// 子组件
import WaterfallFlow from "./waterfallFlow.vue";
// import DictTag from "@/components/DictTag/index.vue";
// 静态资源 & 工具函数
import {
  DictOption,
  TaskInfo,
  WaterfallItem,
  // MediaType,
  WaterfallProps,
} from "@/typings/work";
import defaultImg from "@/assets/images/img-load-err.png";
import fallbackCopyToClipboard from "@/utils/copyText";
import { LazyImg, Waterfall } from "vue-waterfall-plugin-next";
import "vue-waterfall-plugin-next/dist/style.css";
enum MediaType {
  IMAGE = 1, // 纯图片
  IMAGE_TEXT = 2, // 图文
  VIDEO = 3, // 视频
  TEXT = 4, // 纯文字
}
const waterfallKey = ref(0);
// ✅ 自定义响应式断点配置
const waterfallBreakpoints = {
  // 1200: { rowPerView: 4 }, // 宽度 < 1200px：4列
  // 900: { rowPerView: 3 },  // 宽度 < 900px：3列
  600: { rowPerView: 2 }, // 宽度 < 600px：2列（平板横屏）
  320: { rowPerView: 2 }, // 宽度 < 320px：2列（所有手机竖屏）
};
const searchForm = ref({
  title: "",
  // type: 1, //默认图片
});
const search = async () => {
  currentPage.value = 1;
  hasMore.value = true;
  scrollContainer.value.scrollTop = 0;
  await getTaskProductionListLimit();
};
const debouncedSearch = debounce(search, 300);
const { WOEKS_LIST_TWO } = apis;
// ===================== 1. 路由实例（Vue3 替代 this.$route） =====================
const route = useRoute();
const taskId = route.params.taskId as string;
// 复用枚举：1图片 2图文 3视频 4文字

// ===================== 2. TS 类型定义 =====================
/** 任务基础信息 */

// ===================== 3. 全局响应式数据 =====================
// 字典类型列表
const taskTypes = ref<DictOption[]>(
  JSON.parse(sessionStorage.getItem("task_type") || "[]")
);
// 任务详情
const taskInfo = ref<TaskInfo>(
  JSON.parse(sessionStorage.getItem("currentTask") || "{}")
);
const currentTaskType = computed(() => Number(taskInfo.value.type || 1));

// 瀑布流列表
const list = ref<WaterfallItem[]>([]);
// 抽屉显隐
const visible = ref(false);
// 当前选中的卡片项
const currentItem = ref<WaterfallItem | null>(null);

// 分页 & 加载状态
const currentPage = ref(1);
const pageSize = computed(() => (isMobile.value ? 20 : 50));
const isLoading = ref(false);
const hasMore = ref(true);
const cardDom = computed(
  () => document.getElementsByClassName("waterfall-item")[0]
);
const cardDomWidth = computed(() => cardDom.value?.offsetWidth ?? 200);
// 计算高度方法
const calculateHeight = (width: number, height: number) => {
  // console.log(11111111111111, cardDom, cardDomWidth.value, width, height);
  // 16*200/9=
  return (cardDomWidth.value * height) / width || 356;
};
// 滚动容器 DOM 引用（标注 TS 类型）
const scrollContainer = ref<HTMLDivElement | null>(null);

// ===================== 4. 工具/业务方法 =====================
/** 返回上一页 */
const goBack = () => {
  sessionStorage.clear();
  window.history.go(-1);
};

/** 返回顶部 */
const scrollToTop = () => {
  scrollContainer.value?.scrollTo({
    top: 0,
    behavior: "smooth",
  });
};
/** 刷新列表 */
const refresh = () => {
  currentPage.value = 1;
  list.value = [];
  hasMore.value = true;
  getTaskProductionListLimit();
};
/** 图片加载错误兜底 */
const handleImageError = (e: Event) => {
  const target = e.target as HTMLImageElement;
  target.src = defaultImg;
};

/** 分页加载作品列表（无限滚动核心） */
const getTaskProductionListLimit = async () => {
  // 防重复请求
  if (isLoading.value || !hasMore.value) return;

  isLoading.value = true;
  try {
    currentPage.value == 1 && showLoading();
    const res = await WOEKS_LIST_TWO({
      // taskId,
      current: currentPage.value,
      size: pageSize.value,
      ...searchForm.value,
    });

    const { records = [] } = res || {};
    records.forEach((item) => {
      let sizes = [
        [9, 16],
        [1, 1],
        [16, 9],
        [3, 4],
        [4, 3],
        [2, 3],
        [3, 2],
      ];
      if (!item.width || !item.height) {
        let size = sizes[Math.floor(Math.random() * sizes.length)];
        item.width = size[0];
        item.height = size[1];
      }
    });
    if (currentPage.value == 1) {
      list.value = records;
    } else {
      list.value = list.value.concat(records);
    }
    // 判断是否还有更多数据
    hasMore.value = !(records.length < pageSize.value);
  } catch (error) {
    console.error("列表加载失败：", error);
    // 加载失败，页码回退
    currentPage.value = Math.max(1, currentPage.value - 1);
  } finally {
    isLoading.value = false;
    if (currentPage.value == 1 && !isFirstLoad.value) {
      hiddenLoading();
    }
  }
};
const showScrollToTop = ref(false);
/** 滚动触底加载 */
const handleScroll = throttle(() => {
  const container = scrollContainer.value;
  if (!container || isLoading.value || !hasMore.value) return;

  const { scrollHeight, scrollTop, clientHeight } = container;
  // 距离底部 50px 预加载
  if (scrollTop + clientHeight >= scrollHeight - 50) {
    currentPage.value++;
    getTaskProductionListLimit();
  }
  if (scrollTop > 1000) {
    showScrollToTop.value = true;
  } else {
    showScrollToTop.value = false;
  }
}, 100);
// 检测师手机端还是pc端,不要宽度判断,用userAgent判断
const isMobile = computed(() => {
  return navigator.userAgent.includes("Mobile");
});
/** 瀑布流卡片点击 */
const handleCardClick = (item: WaterfallItem) => {
  // if (isMobile.value) {
  // } else {
  visible.value = true;
  currentItem.value = item;
  console.log("点击作品：", item);
  // }
};
const saving = ref(false);
/** 抽屉关闭 */
const handleClose = () => {
  visible.value = false;
  // currentItem.value = null;
};
/**
 * ✅ 纯前端保存功能（无后端接口）
 * 支持：图片/视频/纯文字三种类型
 */
const handleSave = async () => {
  if (!currentItem.value) {
    showMsg("请先选择要保存的作品");
    return;
  }

  if (saving.value) return; // 防止重复点击
  saving.value = true;

  try {
    const item = currentItem.value;
    // 生成文件名：标题_时间戳.后缀（避免重复）
    const timestamp = Date.now();
    const safeTitle =
      item.title?.replace(/[<>:"/\\|?*]/g, "_") || `work_${item.id}`;

    switch (currentTaskType.value) {
      // 图片类型：Canvas转Blob下载（解决跨域问题）
      case MediaType.IMAGE:
      case MediaType.IMAGE_TEXT:
        await saveImage(item.fileUrl, `${safeTitle}_${timestamp}.png`);
        break;

      // 视频类型：Fetch获取Blob下载
      case MediaType.VIDEO:
        await saveVideo(item.fileUrl, `${safeTitle}_${timestamp}.mp4`);
        break;

      // 纯文字类型：生成TXT文件下载
      case MediaType.TEXT:
        saveText(item.content, `${safeTitle}_${timestamp}.txt`);
        break;

      default:
        showMsg("不支持的文件类型");
        break;
    }

    showMsg("保存成功！", "success");
    handleClose();
  } catch (error) {
    console.error("保存失败：", error);
    showMsg(error.message || "保存失败，请检查网络连接或稍后重试", "error");
  } finally {
    saving.value = false;
  }
};

/**
 * 保存图片（解决跨域问题）
 * @param url 图片URL
 * @param fileName 保存的文件名
 */
const saveImage = (url: string, fileName: string): Promise<void> => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.crossOrigin = "anonymous"; // 关键：允许跨域
    img.onload = () => {
      try {
        // 创建Canvas
        const canvas = document.createElement("canvas");
        canvas.width = img.naturalWidth;
        canvas.height = img.naturalHeight;
        const ctx = canvas.getContext("2d");

        if (!ctx) {
          reject(new Error("Canvas不支持"));
          return;
        }

        // 绘制图片
        ctx.drawImage(img, 0, 0);

        // 转Blob并下载
        canvas.toBlob((blob) => {
          if (!blob) {
            reject(new Error("图片转换失败"));
            return;
          }
          downloadBlob(blob, fileName);
          resolve();
        }, "image/png");
      } catch (e) {
        reject(new Error("图片处理失败，可能是跨域限制"));
      }
    };

    img.onerror = () => {
      reject(new Error("图片加载失败"));
    };

    img.src = url;
  });
};

/**
 * 保存视频
 * @param url 视频URL
 * @param fileName 保存的文件名
 */
const saveVideo = async (url: string, fileName: string): Promise<void> => {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`视频加载失败：${response.status}`);
    }
    const blob = await response.blob();
    downloadBlob(blob, fileName);
  } catch (error) {
    throw new Error("视频下载失败，可能是文件过大或网络问题");
  }
};

/**
 * 保存纯文字为TXT文件
 * @param text 文字内容
 * @param fileName 保存的文件名
 */
const saveText = (text: string, fileName: string) => {
  const blob = new Blob([text], { type: "text/plain;charset=utf-8" });
  downloadBlob(blob, fileName);
};

/**
 * 通用Blob下载方法
 * @param blob 要下载的Blob对象
 * @param fileName 保存的文件名
 */
const downloadBlob = (blob: Blob, fileName: string) => {
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = fileName;
  a.style.display = "none";
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url); // 释放内存
};
/** 复制文案 */
const handleCopy = (text: string) => {
  fallbackCopyToClipboard(text);
};
// 是否首次加载
const isFirstLoad = ref(true);
// ===================== 5. 生命周期 =====================
/** 组件挂载：初始化所有数据 + 绑定滚动事件 */
onMounted(async () => {
  // 纯文字类型，修改每页条数
  // 重置分页 + 加载第一页
  currentPage.value = 1;
  hasMore.value = true;
  await getTaskProductionListLimit();
  // 绑定滚动事件
  await nextTick();
  const container = scrollContainer.value;
  if (container) {
    container.addEventListener("scroll", handleScroll);
  }
  setTimeout(() => {
    isFirstLoad.value = false;
    waterfallKey.value++;
    hiddenLoading();
  }, 500);
});

/** 组件卸载：解绑滚动事件，防止内存泄漏 */
onBeforeUnmount(() => {
  const container = scrollContainer.value;
  if (container) {
    container.removeEventListener("scroll", handleScroll);
  }
});
</script>

<style scoped lang="scss">
.task-production-detail {
  max-height: 100vh;
  overflow: hidden;

  .task-production-detail-header {
    overflow-y: auto;
    background-color: #0072fed6;
    // border-bottom: 1px solid #e5e5e5;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    // text-align: center;
    // background-color: #0072fe;
    > div {
      max-width: 300px;
      :deep(.el-input) {
        // width: 100%;
        flex: 1;
      }
    }
  }

  .card-scroll-container {
    max-height: calc(100vh - 60px);
    overflow-y: auto;
  }
}

.loading-tip {
  text-align: center;
  padding: 0 0 20px;
  font-size: 14px;
  color: #999;
}

.detail-content {
  h3 {
    font-size: 20px;
    font-weight: bold;
    margin-bottom: 20px;
    text-align: center;
  }

  img,
  video {
    width: 100%;
    height: auto;
    display: block;
    object-fit: contain;
    transition: transform 0.3s ease;
  }
}

/* Vue3 推荐使用 :deep() 替代 ::v-deep，两种都兼容 */
:deep(.el-drawer__title) {
  margin-bottom: 0 !important;
}
span {
  text-align: left;
}
.card-item {
  &:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.829);
  }
  img {
    &:hover {
      transform: scale(1.05);
      transition: transform 0.3s ease;
    }
  }
}
</style>