<template>
  <u-popup
    :show="show"
    mode="bottom"
    :round="10"
    :closeable="true"
    @close="cancel"
    bgColor="#fff"
    :customStyle="{ maxHeight: '85vh', overflowY: 'auto' }"
  >
    <view class="report_wrap">
      <view class="title">{{ title }}</view>

      <view class="section_title">报工信息</view>
      <view class="form_row">
        <view class="label required">实际开始时间</view>
        <picker
          mode="multiSelector"
          v-if="false"
        ></picker>
        <view class="picker_box" @click="!inputDis && openTimePicker('realStartTime')">
          <text v-if="form.realStartTime" class="val">{{ form.realStartTime }}</text>
          <text v-else class="placeholder">请选择实际开始时间</text>
        </view>
      </view>

      <view class="form_row">
        <view class="label required">实际结束时间</view>
        <view class="picker_box" @click="!inputDis && openTimePicker('realEndTime')">
          <text v-if="form.realEndTime" class="val">{{ form.realEndTime }}</text>
          <text v-else class="placeholder">请选择实际结束时间</text>
        </view>
      </view>

      <view class="form_row">
        <view class="label required">报工数</view>
        <input
          class="ipt"
          type="digit"
          v-model="form.reportQuantity"
          :disabled="inputDis"
          placeholder="请输入"
          @input="(e) => handleQuantityInput(e.detail.value, 'reportQuantity')"
        />
      </view>

      <view class="form_row">
        <view class="label required">损耗数</view>
        <input
          class="ipt"
          type="digit"
          v-model="form.lossQuantity"
          :disabled="inputDis"
          placeholder="请输入"
          @input="(e) => handleQuantityInput(e.detail.value, 'lossQuantity')"
        />
      </view>

      <view class="form_row">
        <view class="label">备注信息</view>
        <textarea
          class="ipt textarea"
          v-model="form.remark"
          :disabled="inputDis"
          placeholder="请输入"
          maxlength="-1"
        />
      </view>

      <view class="tip" v-if="!inputDis">
        任务剩余可报数量：{{ remaining }}
      </view>

      <view class="section_title">工单信息</view>
      <view class="info_grid">
        <view class="info_item" v-for="item in fieldMap.orderList" :key="item.prop">
          <view class="info_label">{{ item.label }}</view>
          <view class="info_val">{{ current[item.prop] || '-' }}</view>
        </view>
      </view>

      <view class="section_title">任务信息</view>
      <view class="info_grid">
        <view class="info_item" v-for="item in fieldMap.taskList" :key="item.prop">
          <view class="info_label">{{ item.label }}</view>
          <view class="info_val">{{ current[item.prop] || '-' }}</view>
        </view>
      </view>

      <view v-if="title === '详情'" class="section_title">报工记录</view>
      <view v-if="title === '详情'" class="record_list">
        <view v-if="list.length === 0" class="empty">暂无记录</view>
        <view v-for="(rec, idx) in list" :key="idx" class="record_item">
          <view class="rec_row"><text class="rec_label">实际开始：</text>{{ rec.realStartTime || '-' }}</view>
          <view class="rec_row"><text class="rec_label">实际结束：</text>{{ rec.realEndTime || '-' }}</view>
          <view class="rec_row"><text class="rec_label">工时：</text>{{ rec.durationText || '-' }}</view>
          <view class="rec_row"><text class="rec_label">报工数：</text>{{ rec.reportQuantity || 0 }}</view>
          <view class="rec_row"><text class="rec_label">损耗数：</text>{{ rec.lossQuantity || 0 }}</view>
          <view class="rec_row"><text class="rec_label">备注：</text>{{ rec.remark || '-' }}</view>
        </view>
      </view>

      <view class="btns">
        <button class="btn cancel" @click="cancel">关闭</button>
        <button v-if="!inputDis" class="btn confirm" :disabled="loadingBtn" @click="submitAdd">报工</button>
      </view>
    </view>

    <u-datetime-picker
      :show="timeShow"
      v-model="timeValue"
      mode="datetime"
      @confirm="onTimeConfirm"
      @cancel="timeShow = false"
      @close="timeShow = false"
      :closeOnClickOverlay="true"
    ></u-datetime-picker>
  </u-popup>
</template>

<script>
import {
  listWorkCenter,
  batchUpdateRealTime,
  listUpdateRealTimeRecord,
} from "@/api/pda/workReport.js";

export default {
  data() {
    return {
      show: false,
      title: "详情",
      timeShow: false,
      timeField: "",
      timeValue: Date.now(),
      form: {
        realEndTime: "",
        realStartTime: "",
        remark: "",
        reportQuantity: "",
        lossQuantity: "",
        workOrderCode: "",
        workOrderId: "",
        taskId: "",
      },
      current: {},
      list: [],
      reportNum: 0,
      lossNum: 0,
      loadingBtn: false,
      fieldMap: {
        orderList: [
          { label: "计划批次号", prop: "batchNo" },
          { label: "工单编码", prop: "mesWorkOrderCode" },
          { label: "产品编码", prop: "productCode" },
          { label: "产品名称", prop: "productName" },
          { label: "规格", prop: "specification" },
          { label: "生产订单编码", prop: "workOrderCode" },
          { label: "计划编号", prop: "productionPlanCode" },
          { label: "工艺路线", prop: "produceRoutingName" },
          { label: "要求生产数量", prop: "formingNum" },
          { label: "要求生产重量", prop: "formingWeight" },
          { label: "所属工厂", prop: "factoryName" },
          { label: "所属班组", prop: "assignTeamName" },
          { label: "计划开始时间", prop: "planStartTime" },
          { label: "计划结束时间", prop: "planCompleteTime" },
        ],
        taskList: [
          { label: "任务编码", prop: "assignCode" },
          { label: "工序名称", prop: "taskName" },
          { label: "执行类型", prop: "assigneeType" },
          { label: "执行对象", prop: "assigneeName" },
          { label: "工时", prop: "durationText" },
          { label: "任务开始时间", prop: "startTime" },
          { label: "任务结束时间", prop: "endTime" },
          { label: "任务数量", prop: "quantity" },
          { label: "任务重量", prop: "weight" },
        ],
      },
    };
  },
  computed: {
    inputDis() {
      return this.title === "详情";
    },
    remaining() {
      const req = Number(this.current.quantity) || 0;
      return Math.max(this.sub(req, this.add(this.reportNum, this.lossNum)), 0);
    },
  },
  methods: {
    open(type, row, form) {
      this.title = type === "report" ? "报工" : "详情";
      this.current = { ...row };
      this.list = [];
      if (form && form.realEndTime) {
        this.form = { ...form };
      } else {
        this.form = {
          realEndTime: form ? form.realEndTime || "" : "",
          realStartTime: form ? form.realStartTime || "" : "",
          remark: form ? form.remark || "" : "",
          reportQuantity: form ? form.reportQuantity : "",
          lossQuantity: form ? form.lossQuantity : 0,
          workOrderCode: form ? form.workOrderCode : "",
          workOrderId: form ? form.workOrderId : "",
          taskId: form ? form.taskId : "",
        };
      }
      this.reportNum = Number(this.current.reportQuantityReported) || 0;
      this.lossNum = Number(this.current.lossQuantityReported) || 0;

      if (type !== "report") {
        listUpdateRealTimeRecord(this.current.apsAssigneeId)
          .then((res) => {
            if (res) this.list = res;
          })
          .catch((err) => {
            uni.showToast({ title: err.message || "记录加载失败", icon: "none" });
          });
      }

      this.getFactory();
      this.show = true;
    },
    async getFactory() {
      if (!this.current.firstTaskId) return;
      try {
        const res = await listWorkCenter(this.current.firstTaskId);
        if (res && res.length) {
          this.$set(this.current, "factoryName", res[0].factoryName);
        }
      } catch (err) {
        // 忽略：仅展示字段
      }
    },
    cancel() {
      this.show = false;
      this.form = {
        realEndTime: "",
        realStartTime: "",
        remark: "",
        reportQuantity: "",
        lossQuantity: "",
        workOrderCode: "",
        workOrderId: "",
        taskId: "",
      };
      this.current = {};
      this.list = [];
    },
    openTimePicker(field) {
      this.timeField = field;
      const cur = this.form[field];
      this.timeValue = cur ? new Date(cur.replace(/-/g, "/")).getTime() : Date.now();
      this.timeShow = true;
    },
    onTimeConfirm(e) {
      const ts = e.value;
      const d = new Date(ts);
      const pad = (n) => String(n).padStart(2, "0");
      const val =
        d.getFullYear() +
        "-" +
        pad(d.getMonth() + 1) +
        "-" +
        pad(d.getDate()) +
        " " +
        pad(d.getHours()) +
        ":" +
        pad(d.getMinutes()) +
        ":" +
        pad(d.getSeconds());
      this.form[this.timeField] = val;
      this.timeShow = false;
      this.handleTimeChange();
    },
    handleTimeChange() {
      if (this.form.realStartTime && this.current.startTime) {
        const a = new Date(this.form.realStartTime.replace(/-/g, "/")).getTime();
        const b = new Date(String(this.current.startTime).replace(/-/g, "/")).getTime();
        if (a < b) {
          this.form.realStartTime = "";
          uni.showToast({ title: "实际开始时间不能早于任务开始时间", icon: "none" });
          return;
        }
      }
      if (this.form.realStartTime && this.form.realEndTime) {
        const a = new Date(this.form.realStartTime.replace(/-/g, "/")).getTime();
        const b = new Date(this.form.realEndTime.replace(/-/g, "/")).getTime();
        if (a > b) {
          this.form.realEndTime = "";
          uni.showToast({ title: "结束时间不能早于开始时间", icon: "none" });
        }
      }
    },
    handleQuantityInput(val, type) {
      let newVal = String(val || "").replace(/[^\d.]/g, "");
      if (newVal.startsWith(".")) newVal = "";
      const firstDot = newVal.indexOf(".");
      if (firstDot !== -1) {
        newVal =
          newVal.slice(0, firstDot + 1) +
          newVal.slice(firstDot + 1).replace(/\./g, "");
      }
      const match = newVal.match(/^(\d+)(\.\d{0,4})?/);
      this.form[type] = match ? match[0] : "";
      this.calculateQuantity(type);
    },
    calculateQuantity(type) {
      const curRep = Number(this.form.reportQuantity) || 0;
      const curLoss = Number(this.form.lossQuantity) || 0;
      if (this.add(curRep, curLoss) > this.remaining) {
        this.form[type] = "";
        uni.showToast({
          title: `本次报工数与损耗数之和不能超过任务剩余可报数量（剩余 ${this.remaining}）`,
          icon: "none",
        });
      }
    },
    getDecimalLength(num) {
      return (num.toString().split(".")[1] || "").length;
    },
    toInteger(num) {
      const len = this.getDecimalLength(num);
      return { int: Math.round(num * Math.pow(10, len)), factor: Math.pow(10, len) };
    },
    add(a, b) {
      const { int: aInt, factor: aFactor } = this.toInteger(a);
      const { int: bInt, factor: bFactor } = this.toInteger(b);
      const maxFactor = Math.max(aFactor, bFactor);
      return (aInt * (maxFactor / aFactor) + bInt * (maxFactor / bFactor)) / maxFactor;
    },
    sub(a, b) {
      const { int: aInt, factor: aFactor } = this.toInteger(a);
      const { int: bInt, factor: bFactor } = this.toInteger(b);
      const maxFactor = Math.max(aFactor, bFactor);
      return (aInt * (maxFactor / aFactor) - bInt * (maxFactor / bFactor)) / maxFactor;
    },
    submitAdd() {
      if (!this.form.realStartTime) {
        return uni.showToast({ title: "请选择实际开始时间", icon: "none" });
      }
      if (!this.form.realEndTime) {
        return uni.showToast({ title: "请选择实际结束时间", icon: "none" });
      }
      if (this.form.reportQuantity === "" || this.form.reportQuantity === null) {
        return uni.showToast({ title: "请输入报工数量", icon: "none" });
      }
      if (this.form.lossQuantity === "" || this.form.lossQuantity === null) {
        return uni.showToast({ title: "请输入损耗数量", icon: "none" });
      }
      const curRep = Number(this.form.reportQuantity) || 0;
      const curLoss = Number(this.form.lossQuantity) || 0;
      if (this.add(curRep, curLoss) > this.remaining) {
        return uni.showToast({
          title: `本次报工数与损耗数之和不能超过任务剩余可报数量（剩余 ${this.remaining}）`,
          icon: "none",
        });
      }
      const data = { ...this.form, apsAssigneeId: this.current.apsAssigneeId };
      this.loadingBtn = true;
      batchUpdateRealTime([data])
        .then(() => {
          this.loadingBtn = false;
          uni.showToast({ title: "操作成功", icon: "success" });
          this.$emit("success");
          this.cancel();
        })
        .catch((err) => {
          this.loadingBtn = false;
          uni.showToast({ title: err.message || "操作失败", icon: "none" });
        });
    },
  },
};
</script>

<style lang="scss" scoped>
.report_wrap {
  padding: 30rpx;
  .title {
    font-size: 32rpx;
    font-weight: 600;
    text-align: center;
    margin-bottom: 20rpx;
  }
  .section_title {
    font-size: 28rpx;
    font-weight: 600;
    color: #333;
    margin: 20rpx 0 16rpx;
    padding-left: 16rpx;
    border-left: 6rpx solid $theme-color;
  }
  .form_row {
    margin-bottom: 20rpx;
    .label {
      font-size: 26rpx;
      color: #333;
      margin-bottom: 8rpx;
      &.required::before {
        content: "*";
        color: red;
        margin-right: 4rpx;
      }
    }
    .picker_box {
      border: 1rpx solid #e0e0e0;
      border-radius: 6rpx;
      padding: 14rpx 16rpx;
      font-size: 26rpx;
      min-height: 60rpx;
      .placeholder {
        color: #aaa;
      }
    }
    .ipt {
      border: 1rpx solid #e0e0e0;
      border-radius: 6rpx;
      padding: 14rpx 16rpx;
      font-size: 26rpx;
      width: 100%;
      box-sizing: border-box;
      min-height: 72rpx;
      line-height: 44rpx;
    }
    .textarea {
      min-height: 120rpx;
    }
  }
  .tip {
    color: #ff9c00;
    font-size: 24rpx;
    margin: -8rpx 0 16rpx;
  }
  .info_grid {
    display: flex;
    flex-wrap: wrap;
    background: #f7f9fa;
    padding: 16rpx;
    border-radius: 8rpx;
    .info_item {
      width: 50%;
      padding: 8rpx 6rpx;
      font-size: 24rpx;
      box-sizing: border-box;
      .info_label {
        color: #999;
        margin-bottom: 4rpx;
      }
      .info_val {
        color: #333;
        word-break: break-all;
      }
    }
  }
  .record_list {
    .empty {
      text-align: center;
      color: #999;
      font-size: 26rpx;
      padding: 30rpx 0;
    }
    .record_item {
      background: #f7f9fa;
      padding: 16rpx;
      border-radius: 8rpx;
      margin-bottom: 12rpx;
      .rec_row {
        font-size: 24rpx;
        color: #333;
        line-height: 40rpx;
        .rec_label {
          color: #999;
        }
      }
    }
  }
  .btns {
    display: flex;
    gap: 20rpx;
    margin-top: 30rpx;
    position: sticky;
    bottom: 0;
    background: #fff;
    padding-top: 16rpx;
    .btn {
      flex: 1;
      height: 80rpx;
      line-height: 80rpx;
      border-radius: 8rpx;
      font-size: 28rpx;
    }
    .cancel {
      background: #f5f5f5;
      color: #333;
    }
    .confirm {
      background: $theme-color;
      color: #fff;
    }
  }
}
</style>
