<template>
  <Water></Water>
  <view class="nav" :style="{ paddingTop: statusBarHeight + 'px' }">
    <text
      class="nav-back"
      :style="{ top: statusBarHeight + 'px' }"
      @click="onBack"
    ></text>
    <text class="nav-title">药品追溯码查询</text>
  </view>
  <view
    class="page"
    :style="{
      marginTop: statusBarHeight + 44 + 'px',
      height: pageHeight + 'px',
    }"
  >
    <view class="scan-tip" @click="handleScanTipClick">
      <uni-icons type="help" size="18" color="#2c69ff"></uni-icons>
      <text :style="{ marginLeft: '5rpx', paddingBottom: '5rpx' }"
        >可扫码生产企业及药品</text
      >
    </view>
    <view class="scan-card" @click="handleScan">
      <view class="scan-card-content">
        <image
          src="../../static/images/camera.png"
          mode="scaleToFill"
          class="scan-icon"
        />
        <text class="scan-text">扫码查询</text>
      </view>
    </view>
    <view class="hint">请扫描药品最小销售包装上的追溯码</view>
    <view class="input-wrap">
      <input
        class="input"
        v-model="traceCode"
        maxlength="23"
        @input="onTraceInput"
        placeholder="请输入 20 位药品追溯码"
      />
    </view>
    <view class="count"
      >已输入 {{ traceCode.replace(/\s+/g, "").length }}/20 位</view
    >
    <button class="query-btn" :class="{ disabled: !canQuery }" @click="onQuery">
      查询
    </button>
    <text class="tip">若扫码失败，可手动输入追溯码查询</text>
    <view class="section-title">扫码历史</view>

    <scroll-view
      class="history-scroll"
      v-if="history.length != 0 && !loading"
      scroll-y="true"
      @scrolltolower="onHistoryScrollToLower"
    >
      <view class="history-list">
        <view
          class="history-item"
          v-for="item in history"
          :key="item.code"
          @click="onTapHistory(item)"
        >
          <view class="history-left">
            <view class="history-title">{{ item.physicName }}</view>
            <view class="history-sub">追溯码：{{ item.tracCode }}</view>
          </view>
          <text class="arrow">›</text>
        </view>
        <view class="loading-row" v-if="history.length < totalCount">
          <view class="loading-wrapper">
            <image class="loading-icon" :src="loadingImg" />
          </view>
        </view>
      </view>
    </scroll-view>
    <view v-else-if="!loading" style="margin-top: 20rpx">
      <Empty text="暂无扫码历史" />
    </view>
    <view class="loading-view" v-else>
      <image
        class="loading-icon"
        src="../../static/images/loading.png"
        mode="scaleToFill"
        :style="{ width: '50rpx', height: '50rpx' }"
      />
    </view>
  </view>
</template>

<script>
import loadingImg from "../../static/images/loading.png";
import Empty from "../../wigets/empty.vue";
import Water from "@/components/water/water.vue";
import request from "../../request/index.js";
export default {
  components: {
    Empty,
    Water,
  },
  data() {
    return {
      statusBarHeight: 20,
      pageHeight: 0,
      traceCode: "",
      history: [],
      totalCount: 0,
      pageNum: 1,
      pageSize: 7,
      loading: true,
      isLoading: false,
    };
  },
  onShow() {
    this.history = [];
    this.totalCount = 0;
    this.pageNum = 1;
    this.isLoading = false;
    this.getHistoryData();
  },
  onLoad() {
    const info = uni.getSystemInfoSync();
    this.statusBarHeight = info.statusBarHeight || 20;
    const navH = 44 + this.statusBarHeight;
    const winH =
      info.windowHeight ||
      (info.screenHeight ? info.screenHeight - this.statusBarHeight : 0);
    if (winH) {
      this.pageHeight = Math.max(0, winH - navH);
    }
  },
  computed: {
    canQuery() {
      return this.traceCode.replace(/\s+/g, "").length === 20;
    },
  },
  methods: {
    onBack() {
      try {
        uni.navigateBack();
      } catch (e) {}
    },
    handleScanTipClick() {
      uni.navigateTo({
        url: "/traceCodePackages/traceabilityCodeQuery/pages/scanRange/index",
      });
    },
    formatTraceCode(code) {
      const raw = code.replace(/\s+/g, "").slice(0, 20);
      const parts = raw.match(/.{1,5}/g) || [];
      return parts.join(" ");
    },
    onTraceInput(e) {
      const val = (e && e.detail && e.detail.value) || "";
      this.traceCode = this.formatTraceCode(val);
    },
    getHistoryData() {
      request("/bills/getScanHistory", {
        pageNum: this.pageNum,
        pageSize: this.pageSize,
        path: "/traceabilityCodeQuery/pages/index.vue",
      }).then((res) => {
        if (res.code == 200) {
          const { total, list } = res.data || {};
          this.totalCount = total || 0;
          this.history = Array.isArray(list)
            ? [...this.history, ...list]
            : [...this.history];
        }
        this.isLoading = false;
        this.loading = false;
      });
    },
    handleScan() {
      uni.scanCode({
        onlyFromCamera: false,
        success: (res) => {
          if (!res.result) {
            console.log("scanCode fail", res);
            uni.showToast({
              title: "扫码失败，请重试",
              icon: "none",
              duration: 2000,
            });
            return;
          }

          this.traceCode = this.formatTraceCode(res.result || "");
          if (res.result.length !== 20) {
            uni.showToast({
              title: "追溯码通常为20位，请尝试重新扫描完整的条形码",
              icon: "none",
              duration: 2000,
            });
          } else {
            uni.showToast({
              title: "扫码成功，点击查询查看详情",
              icon: "none",
              duration: 2000,
            });
            this.onTapHistory({ tracCode: res.result });
          }
        },
        fail: (err) => {
          if (err.errMsg.includes("scanCode:fail cancel")) {
            console.log("用户取消了扫码");
            console.log("scan fail", err);
          } else {
            uni.showToast({
              title: "扫码失败，请重试",
              icon: "none",
              duration: 2000,
            }); // 这里可以看到具体失败原因
          }
        },
      });
    },
    onQuery() {
      if (!this.canQuery) return;
      this.onTapHistory({ tracCode: this.traceCode.replace(/\s+/g, "") });
    },
    onHistoryScrollToLower() {
      if (this.isLoading) return;
      if (this.history.length >= this.totalCount) return;
      this.isLoading = true;
      this.pageNum++;
      this.getHistoryData();
    },
    onTapHistory(item) {
      uni.navigateTo({
        url:
          "/traceCodePackages/traceabilityCodeQuery/pages/detail/index" +
          (item ? "?traceCode=" + item.tracCode : ""),
      });
    },
  },
};
</script>

<style>
.scan-tip {
  margin-top: 30rpx;
  color: #2c69ff;
  font-size: 24rpx;
  width: 100%;
  text-align: right;
  padding-bottom: 40rpx;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 44px;
  background-color: #2c69ff;
  display: flex;
  align-items: center;
  justify-content: center;
}

.nav-back {
  position: absolute;
  left: 40rpx;
  top: 12rpx;
  width: 20rpx;
  height: 20rpx;
  color: #fff;
  border-left: 3rpx solid #fff;
  border-bottom: 3rpx solid #fff;
  transform: rotate(45deg) translateY(49rpx);
  margin-left: 34rpx;
}

.nav-title {
  font-size: 36rpx;
  color: #fff;
  font-weight: 700;
}

.page {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 55rpx;
  padding-bottom: env(safe-area-inset-bottom);
  background-color: rgb(243, 246, 249);
  overflow: hidden;
}

.scan-card {
  flex-shrink: 0;
  width: 100%;
  display: flex;
  justify-content: center;
}

.scan-card-content {
  width: 320rpx;
  height: 320rpx;
  background-color: #fff;
  border-radius: 20rpx;
  box-shadow: 0 1rpx 16rpx rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.scan-icon {
  width: 100rpx;
  height: 100rpx;
  margin-bottom: 16rpx;
}

.scan-text {
  font-size: 32rpx;
  color: #2c69ff;
  font-weight: 1000;
}

.hint {
  margin-top: 35rpx;
  color: #727a86;
  font-size: 24rpx;
  width: 100%;
  text-align: center;
  border-bottom: 1rpx dashed #727a8663;
  padding-bottom: 40rpx;
}

.input-wrap {
  width: 640rpx;
  margin-top: 40rpx;
}

.input {
  box-sizing: border-box;
  width: 100%;
  height: 80rpx;
  border: 2rpx solid #2c69ff;
  border-radius: 12rpx;
  padding: 0 20rpx;
  font-size: 28rpx;
}

.count {
  width: 640rpx;
  text-align: right;
  color: #99a1ad;
  font-size: 22rpx;
  margin-top: 8rpx;
}

.query-btn {
  flex-shrink: 0;
  width: 640rpx;
  height: 80rpx;
  line-height: 80rpx;
  text-align: center;
  margin-top: 40rpx;
  background-color: #2c69ff;
  color: #fff;
  font-size: 30rpx;
}

.query-btn.disabled {
  background-color: rgb(192, 210, 224);
  color: #fff;
}

.tip {
  margin-top: 12rpx;
  color: #99a1ad;
  font-size: 22rpx;
}

.section-title {
  width: 640rpx;
  margin-top: 30rpx;
  font-size: 28rpx;
  color: #000;
  font-weight: 1000;
}

.history-list {
  width: 640rpx;
}

.history-scroll {
  flex: 1;
  height: 0;
  width: 640rpx;
}

.history-item {
  background-color: #fff;
  border-radius: 16rpx;
  padding: 24rpx;
  margin-top: 16rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.history-title {
  font-size: 28rpx;
  color: #2c69ff;
}

.history-sub {
  margin-top: 6rpx;
  font-size: 24rpx;
  color: #727a86;
}

.arrow {
  font-size: 40rpx;
  color: #cbd3e6;
}

.loading-row {
  justify-content: center;
}

.loading-wrapper {
  width: 100%;
  height: 76rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-icon {
  width: 40rpx;
  height: 40rpx;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

.loading-view {
  margin-top: 20rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
}
</style>
