<script setup>
import TopNav from "@/components/topNav.vue";
import { qcckPost, qcckGet } from "@/api/qcckApi";
import { onMounted, ref, reactive, onUnmounted } from "vue";
import { useRoute } from "vue-router";
import { selectByTaskInfo } from "@/api/patrolList";
import { getBase64, hintToast } from "@/utils/tools";
import { ImagePreview } from "vant";
import MapWrapper from "@/pages/clockInPage/components/mapWrapper.vue";
import emitter from "@/utils/eventBus";

const route = useRoute();
const info = ref({});
const pointsList = ref([]);
const listQuery = ref({
  dktp: "",
  jd: "",
  wd: "",
});
const leaveQuery = ref({
  id: "",
  lkjd: "",
  lkwd: "",
  lktp: "",
});
const zxdksj = ref("");
const dwIndex = ref();
const imageMap = new Map();
const getImageUrl = async (fileId) => {
  if (!fileId) return null;
  if (imageMap.has(fileId)) return imageMap.get(fileId);
  const res = await qcckGet({}, `/mosty-base/minio/file/download/${fileId}`);
  if (res?.url) {
    const base64 = await getBase64("", res.url);
    imageMap.set(fileId, base64);
    return base64;
  }
  return null;
};
const getImageUrlOld = (item) => {
  qcckGet({}, `/mosty-base/minio/file/download/${item}`).then((res) => {
    console.log(res.url, 'res.url');
    _getBase64(res.url);
  });
};
const preview = (url) => {
  if (url) ImagePreview([url]);
};

const loadData = async () => {
  const id = route.query.id || "";
  const detail = await selectByTaskInfo({ fgrwid: id });
  if (detail) {
    getUserLocation();
    // 删除方格
    emitter.emit("deletePointArea", "zdxl_fzyc");
    // 生成方格
    const { x1, y1, x2, y2, fgId, zxX, zxY, fgMc } = detail.fgdwVO;
    const centerPoint = [zxX, zxY];
    const position = [
      [Number(x1), Number(y1)],
      [Number(x2), Number(y2)],
    ];
    const text = fgMc;
    const obj = [{ position: position, text, id: fgId, userData: detail.bxds }];
    emitter.emit("echoPlane", {
      fontColor: "#12fdb8",
      coords: obj,
      type: "rectangle",
      flag: "zdxl_fzyc",
      color: "rgba(2,20,51,0.5)",
      linecolor: "#1C97FF",
    });
    emitter.emit("setMapCenter", { location: centerPoint, zoomLevel: 12 });
    // 获取所有唯一的图片ID（打卡图片和离开图片）
    const uniqueImageIds = new Set();
    detail.bxds?.forEach((item) => {
      if (item?.dktp) uniqueImageIds.add(item.dktp);
      if (item?.lktp) uniqueImageIds.add(item.lktp);
    });
    // 批量获取图片URL
    const imageEntries = await Promise.allSettled(
      Array.from(uniqueImageIds).map(async (id) => {
        try {
          const url = await getImageUrl(id);
          return { id, url };
        } catch (error) {
          return { id, url: null };
        }
      })
    );
    // 创建图片映射表
    const imageMap = new Map();
    imageEntries.forEach((entry) => {
      if (entry.status === "fulfilled") {
        imageMap.set(entry.value.id, entry.value.url);
      }
    });
    // 设置数据
    pointsList.value = detail.bxds.map((item, index) => ({
      ...item,
      imgUrlDkFj: item?.dktp ? imageMap.get(item.dktp) : null,
      lkImgUrl: item?.lktp ? imageMap.get(item.lktp) : null,
    }));
    // 为每个必到点添加图片URL
    zxdksj.value = detail.zxdksj;
    info.value = detail.fgrw;
    listQuery.value.fgrwid = info.value.id;

    // 在地图上显示打卡点
    const dkPoints = detail.bxds
      ?.filter((item) => item.jd && item.wd)
      .map((item) => ({
        jd: item.jd,
        wd: item.wd,
        bxdMc: item.bxdMc,
        dkzt: item.dkzt,
      }));
    if (dkPoints && dkPoints.length > 0) {
      emitter.emit("deletePointArea", "historyPoints");
      emitter.emit("addPointArea", {
        coords: dkPoints,
        icon: require("../../assets/images/11.png"),
        flag: "historyPoints",
        showTitle: true,
      });
    }
  }
};
//获取当前位置信息
function getUserLocation(sfdw) {
  let { lng, lat } = getLocation();
  if (lng && lat) {
    emitter.emit("deletePointArea", "dw");
    //地图撒点然后移动
    emitter.emit("addPointArea", {
      coords: [{ jd: lng, wd: lat }],
      icon: require("../../assets/lz/dw.png"),
      flag: "dw",
      sfdw: sfdw,
      sizeX: 30,
      sizeY: 35,
    });
  } else {
    hintToast("暂无坐标信息");
  }
}
function isInThirtyMinutes(targetTime, jgsj) {
  let flag = false
  // 获取当前时间
  const now = new Date();
  // 最新打卡时间
  const targetDate = new Date(targetTime);
  let nowMin = now.getTime();//当前时间
  let newMin = targetDate.getTime();//最新打卡时间
  let count = nowMin - newMin;
  if (count > jgsj * 60 * 1000) {
    flag = true
  } else {
    flag = false
  }
  return flag
}
// 检查是否存在已打卡但未离开的点
const hasUnfinishedCheckIn = () => {
  // dksj: 打卡时间，lksj: 离开时间
  // 已打卡且有打卡时间，但没有离开时间，说明未完成
  return pointsList.value.some((item) => item.dksj && !item.lksj);
};
// 点击上传
const photoFn = (val, index) => {
  // 检查是否存在已打卡但未离开的点
  const unfinishedPoint = pointsList.value.find((item) => item.dksj && !item.lksj);
  if (unfinishedPoint) {
    hintToast(`请先完成【${unfinishedPoint.bxdMc || '上一个点'}】的离开打卡`);
    return;
  }
  dwIndex.value = index;
  listQuery.value.bxdid = val.bxdid;
  // 判断此任务最新打卡时间如果在打卡间隔时间之后才能继续打卡
  if (zxdksj.value) {
    if (!isInThirtyMinutes(zxdksj.value, info.value.dkjgsj)) {
      const nowtime = new Date();
      const time1 = new Date(zxdksj.value);//最新打卡时间
      let newMin = time1.getTime() + Number(info.value.dkjgsj) * 60 * 1000;//30分钟后的时间
      let max = Math.floor((newMin - nowtime.getTime()) / 1000 / 60);//最大可打卡时间
      hintToast(`请于${max}分钟后打卡`);
      return;
    }
    try {
      bridge.pZ("photo");
    } catch (err) {
      console.log(err, "err");
    }
    // handleClick()
  } else {
    try {
      bridge.pZ("photo");
    } catch (err) {
      console.log(err, "err");
    }
    // handleClick()
  }
};
// 打卡
const handleClick = () => {
  const { lng, lat } = getLocation();
  listQuery.value.jd = lng;
  listQuery.value.wd = lat;
  qcckPost(listQuery.value, "/mosty-yjzl/tbZdyrw/zdyRwdk")
    .then((res) => {
      if (res) {
        hintToast(`打卡成功`);
        loadData()
      }
    })
    .catch((err) => {
      console.log(err, "err");
      hintToast("打卡失败");
      loadData()
    });
};
// 检查是否可以离开打卡（当前时间要大于打卡时间+打卡间隔时间）
const canLeave = (dksj, dkjgsj) => {
  if (!dksj) return false;
  const now = new Date();
  const dkTime = new Date(dksj);
  const minLeaveTime = new Date(dkTime.getTime() + Number(dkjgsj || 0) * 60 * 1000);
  return now.getTime() >= minLeaveTime.getTime();
};
// 获取剩余等待时间（分钟）
const getLeaveWaitTime = (dksj, dkjgsj) => {
  if (!dksj) return 0;
  const now = new Date();
  const dkTime = new Date(dksj);
  const minLeaveTime = new Date(dkTime.getTime() + Number(dkjgsj || 0) * 60 * 1000);
  const diff = minLeaveTime.getTime() - now.getTime();
  return Math.ceil(diff / 1000 / 60);
};
// 离开打卡拍照
const leavePhotoFn = (item, index) => {
  // 判断时间间隔
  if (!canLeave(item.dksj, info.value.dkjgsj)) {
    const waitMin = getLeaveWaitTime(item.dksj, info.value.dkjgsj);
    hintToast(`请于${waitMin}分钟后离开打卡`);
    return;
  }
  dwIndex.value = index;
  leaveQuery.value.id = item.id;
  const { lng, lat } = getLocation();
  leaveQuery.value.lkjd = lng;
  leaveQuery.value.lkwd = lat;
  try {
    bridge.pZ("leavePhoto");
  } catch (err) {
    console.log(err, "err");
  }
};
// 离开打卡提交
const handleLeaveSubmit = () => {
  qcckPost(leaveQuery.value, "/mosty-yjzl/tbZdyrw/zdyLkdk")
    .then((res) => {
      if (res) {
        hintToast(`离开打卡成功`);
        loadData();
      }
    })
    .catch((err) => {
      console.log(err, "err");
      hintToast("离开打卡失败");
    });
};
function setimage_base64(pzid, base64) {
  if (pzid === "leavePhoto") {
    // 离开打卡
    pointsList.value[dwIndex.value].lkImgUrl = `data:image/jpeg;base64,${base64}`;
    qcckPost({ base64: base64 }, "/mosty-base/minio/image/upload/base64").then(
      (res) => {
        leaveQuery.value.lktp = res;
        handleLeaveSubmit();
      },
    );
  } else {
    // 打卡
    pointsList.value[dwIndex.value].imgUrlDkFj = `data:image/jpeg;base64,${base64}`;
    qcckPost({ base64: base64 }, "/mosty-base/minio/image/upload/base64").then(
      (res) => {
        listQuery.value.dktp = res;
        handleClick();
      },
    );
  }
}
onMounted(async () => {
  await loadData();
  window.setimagebase64 = setimage_base64;
  setInterval(() => {
    getUserLocation()
  }, 2000);
});

onUnmounted(() => {
  emitter.emit("deletePointArea", "historyPoints");
});
</script>

<template>
  <div class="page-container">
    <TopNav nav-title="任务详情" show-left />
    <div class="content">
      <!-- Header Card -->
      <div class="card header-card">
        <div class="title">{{ info.fgRwmc }}</div>
        <div class="row info-row">
          <div class="sub">方格编号：{{ info.fgmc }}</div>
          <div class="sub">任务日期：{{ info.xfrq }}</div>
        </div>
        <div class="sub">
          打卡间隔时间：{{ info.dkjgsj ? info.dkjgsj : "100min" }}
        </div>
      </div>
      <!-- Point List -->
      <div class="list">
        <div v-for="(item, index) in pointsList" :key="index" class="card point-card">
          <div class="row header-row">
            <div class="name">{{ item.bxdMc }}</div>
            <div class="status-tag">{{ item.dkzt }}</div>
          </div>
          <!-- Checked In: Show Image -->
          <div v-if="item.imgUrlDkFj" class="img-container" @click="preview(item.imgUrlDkFj)">
            <img :src="item.imgUrlDkFj" alt="打卡图片" />
            <div class="time-overlay">打卡：{{ item.dksj }}</div>
          </div>
          <!-- Not Checked In: Show Button (Visual only) -->
          <div v-else class="btn-container">
            <div class="btn" @click="photoFn(item, index)">打卡拍照</div>
          </div>
          <!-- Leave Check-in Button: Show after checked in and not left yet -->
          <div v-if="item.imgUrlDkFj && !item.lkjd" class="btn-container leave-btn-container">
            <div class="btn leave-btn" @click="leavePhotoFn(item, index)">离开打卡</div>
          </div>
          <!-- Leave Image: Show if already left -->
          <div v-if="item.lkjd && item.lkImgUrl" class="img-container leave-img" @click="preview(item.lkImgUrl)">
            <img :src="item.lkImgUrl" alt="离开图片" />
            <div class="time-overlay leave-time-overlay">离开：{{ item.lksj }}</div>
          </div>
          <!-- Leave time without image -->
          <div v-else-if="item.lkjd && !item.lkImgUrl" class="leave-time">离开时间：{{ item.lksj }}</div>
        </div>
      </div>
      <!-- Map Section -->
      <div class="card map-card">
        <div class="map-title">当前位置</div>
        <div class="map-box">
          <MapWrapper />
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.page-container {
  min-height: 100vh;
  background: #f5f7fa;
  padding-bottom: 5vw;
}

.content {
  padding: 16vw 3vw 5vw; // Top padding for fixed nav
}

.card {
  background: #fff;
  border-radius: 3.73vw;
  padding: 4vw;
  margin-bottom: 3vw;
  box-shadow: 0 1.6vw 4vw rgba(0, 0, 0, 0.04);
}

.header-card {
  .title {
    font-size: 4.2vw;
    font-weight: bold;
    color: #333;
    margin-bottom: 3vw;
  }

  .info-row {
    display: flex;
    justify-content: space-between;
    margin-bottom: 1.5vw;
  }

  .sub {
    font-size: 3.4vw;
    color: #999;
  }
}

.point-card {
  .header-row {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    margin-bottom: 3vw;

    .name {
      font-size: 4vw;
      font-weight: bold;
      color: #333;
      margin-right: 2vw;
    }

    .status-tag {
      font-size: 3vw;
      color: #3e6ee8;
      border: 1px solid #3e6ee8;
      padding: 0.5vw 1.5vw;
      border-radius: 1vw;
    }
  }

  .img-container {
    position: relative;
    width: 100%;
    height: 40vw;
    border-radius: 2vw;
    overflow: hidden;

    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .time-overlay {
      position: absolute;
      top: 2vw;
      left: 2vw;
      color: #fff;
      font-size: 3.5vw;
      text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
    }
  }

  .leave-img {
    margin-top: 2vw;

    .leave-time-overlay {
      background: rgba(255, 107, 53, 0.8);
      padding: 0.5vw 1.5vw;
      border-radius: 1vw;
    }
  }

  .btn-container {
    margin-top: 2vw;

    .btn {
      height: 11vw;
      line-height: 11vw;
      text-align: center;
      border-radius: 6vw;
      color: #ffffff;
      background: linear-gradient(90deg, #28a5ff 0%, #3e6ee8 100%);
      font-size: 4vw;
      box-shadow: 0 2vw 4vw rgba(62, 110, 232, 0.3);
    }
  }

  .leave-btn-container {
    margin-top: 2vw;

    .leave-btn {
      background: linear-gradient(90deg, #ff8c28 0%, #ff6b35 100%);
      box-shadow: 0 2vw 4vw rgba(255, 107, 53, 0.3);
    }
  }

  .leave-time {
    margin-top: 2vw;
    font-size: 3.4vw;
    color: #ff6b35;
  }
}

.map-card {
  padding: 0; // Remove default padding for map card to let map fill or have custom padding
  overflow: hidden;

  .map-title {
    padding: 4vw;
    font-size: 4vw;
    font-weight: bold;
    color: #333;
    border-bottom: 1px solid #eee;
  }

  .map-box {
    height: 50vw;
    width: 100%;
    position: relative;

    // Adjust MapWrapper internal style via deep selector if needed,
    // but MapWrapper has fixed height in its scoped style usually.
    // We might need to override it.
    :deep(.mapWrapper) {
      margin-top: 0;
      height: 100%;
    }
  }
}
</style>
