<template>
  <div class="report-page">
    <h2 class="title">Report</h2>
    <div style="width: 200px; margin: 10px 0">
      <el-input v-model="sceneNum" placeholder="请输入场景码"></el-input>
    </div>
    <div class="category-tabs">
      <el-button
        v-for="floor in floors"
        :key="floor"
        size="small"
        :type="floor === activeFloor ? 'primary' : 'default'"
        @click="setActiveFloor(floor)"
      >
        {{ floor }}
      </el-button>
    </div>

    <div class="button-list">
      <el-button
        v-for="item in filteredList"
        :key="item.id"
        :class="[
          'report-btn',
          { 'is-active': activeReportItem && activeReportItem.id === item.id },
        ]"
        type="primary"
        plain
        :loading="reportingId === item.id"
        @click="onReport(item)"
      >
        <span class="btn-content">
          <span class="btn-name">{{ item.name }}</span>
          <span class="btn-id">#{{ item.id }}</span>
        </span>
      </el-button>

      <el-button
        class="report-btn stop-btn"
        type="danger"
        plain
        :disabled="!activeReportItem"
        @click="onStopReport()"
      >
        <span class="btn-content">
          <span class="btn-name">结束上报</span>
        </span>
      </el-button>
      <!-- 
      <div class="fetch-link" @click="getReportInfo">
        获取数据{{ servicesData }}
      </div> -->
    </div>

    <p v-if="activeReportItem" class="status-text">
      Reporting: {{ activeReportItem.name }} #{{ activeReportItem.id }} (every
      1s)
    </p>

    <div v-if="lastReportedItem" class="report-result">
      <h3>Last Report Payload</h3>
      <pre>{{ JSON.stringify(lastReportedItem, null, 2) }}</pre>
    </div>
  </div>
</template>

<script>
import { ElMessage } from "element-plus";
import { reportTagInfo } from "@/api.js";
import tagCoordinateList from "./tagCoordinateList.json";
import reportInfoStream from "./reportInfoStream.js";

export default {
  name: "ReportPage",
  data() {
    return {
      tagList: tagCoordinateList,
      reportingId: null,
      activeReportItem: null,
      lastReportedItem: null,
      reportTimer: null,
      isRequesting: false,
      reportStream: null,
      servicesData: null,
      floors: [],
      activeFloor: "",
      sceneNum: "SG-t-rQ14yS9VjVp",
    };
  },
  computed: {
    filteredList() {
      if (!this.activeFloor) {
        return this.tagList;
      }
      return this.tagList.filter((item) => item.floor === this.activeFloor);
    },
  },
  beforeUnmount() {
    this.clearReportTimer();
    this.closeReportStream();

    this.unsubData && this.unsubData();
    this.unsubErr && this.unsubErr();
  },
  mounted() {
    const floorList = Array.from(
      new Set(this.tagList.map((item) => item.floor).filter(Boolean)),
    );
    this.floors = floorList.sort((a, b) => {
      const aMatch = String(a).match(/\d+/);
      const bMatch = String(b).match(/\d+/);
      const aNum = aMatch ? parseInt(aMatch[0], 10) : Number.NaN;
      const bNum = bMatch ? parseInt(bMatch[0], 10) : Number.NaN;
      const aIsNum = !Number.isNaN(aNum);
      const bIsNum = !Number.isNaN(bNum);

      if (aIsNum && bIsNum) {
        return aNum - bNum;
      }
      if (aIsNum) {
        return -1;
      }
      if (bIsNum) {
        return 1;
      }
      return String(a).localeCompare(String(b), "zh-Hans-CN");
    });
    this.activeFloor = this.floors[0] || "";

    this.unsubData = reportInfoStream.subscribe((data) => {
      this.servicesData = data;
    });

    this.unsubErr = reportInfoStream.onError((err) => {
      console.error(err);
    });
  },
  methods: {
    setActiveFloor(floor) {
      this.activeFloor = floor;
    },
    closeReportStream() {
      if (this.reportStream) {
        this.reportStream.close();
        this.reportStream = null;
      }
    },
    getReportInfo() {
      reportInfoStream.start();
    },
    clearReportTimer() {
      if (this.reportTimer) {
        clearInterval(this.reportTimer);
        this.reportTimer = null;
      }
    },
    sendReportOnce() {
      if (!this.activeReportItem || this.isRequesting) {
        return;
      }

      const item = this.activeReportItem;
      this.reportingId = item.id;
      this.isRequesting = true;
      item.sceneNum = this.sceneNum;
      reportTagInfo(item)
        .then(() => {
          this.lastReportedItem = item;
        })
        .catch((err) => {
          ElMessage({
            message: err?.message || err || "report failed",
            type: "error",
          });
        })
        .finally(() => {
          this.isRequesting = false;
          this.reportingId = null;
        });
    },
    onReport(item) {
      const switched =
        !this.activeReportItem || this.activeReportItem.id !== item.id;
      this.activeReportItem = item;

      this.clearReportTimer();
      this.sendReportOnce();
      this.reportTimer = setInterval(() => {
        this.sendReportOnce();
      }, 1000);

      if (switched) {
        // ElMessage({
        //   message: `start reporting ${item.name} #${item.id}`,
        //   type: 'success',
        // })
      }
    },
    onStopReport() {
      this.clearReportTimer();
      this.activeReportItem = null;
      this.reportingId = null;
      this.isRequesting = false;
      ElMessage({
        message: "report stopped",
        type: "info",
      });
    },
  },
};
</script>

<style scoped>
.report-page {
  padding: calc(12px + env(safe-area-inset-top)) 12px
    calc(16px + env(safe-area-inset-bottom));
  max-width: 920px;
  margin: 0 auto;
}

.title {
  margin: 0 0 12px;
  font-size: 20px;
  line-height: 1.2;
}

.category-tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.button-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
}

.report-btn {
  width: 100%;
  min-height: 42px;
  margin: 0;
  padding: 8px 10px;
  margin-left: 0 !important;
}

.report-btn .btn-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  text-align: left;
}

.report-btn .btn-name {
  font-size: 13px;
  line-height: 1.1;
  padding-right: 8px;
}

.report-btn .btn-id {
  margin-left: 0;
  opacity: 0.8;
  font-size: 12px;
  min-width: 34px;
  text-align: right;
}

.report-btn.is-active {
  border-color: #409eff;
  background-color: #ecf5ff;
}

.stop-btn :deep(span) {
  justify-content: center;
}

.fetch-link {
  font-size: 12px;
  color: #409eff;
  cursor: pointer;
}

.status-text {
  margin: 10px 0 0;
  color: #606266;
  font-size: 12px;
}

.report-result {
  margin-top: 20px;
}

.report-result pre {
  background: #f5f7fa;
  padding: 12px;
  border-radius: 6px;
  overflow-x: auto;
  font-size: 12px;
  line-height: 1.5;
}

@media (min-width: 640px) {
  .report-page {
    padding: 20px;
  }

  .button-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }

  .report-btn {
    min-height: 40px;
    padding: 7px 10px;
  }
}
</style>
