<template>
  <div class="measurement-page">
    <PageCanvas>
      <section class="module-topbar">
        <div class="field">
          <span class="field-label">计量状态</span>
          <label class="chip chip-status chip-yellow">
            <input type="checkbox" v-model="statusFilters.month_done" />
            月计量结算完成
          </label>
          <label class="chip chip-status chip-green">
            <input type="checkbox" v-model="statusFilters.cum_done" />
            累计计量结算完成结构
          </label>
          <label class="chip chip-status chip-red">
            <input type="checkbox" v-model="statusFilters.value_not_settled" />
            有产值未完成计量结算构件
          </label>
        </div>
      </section>

      <SidePanel v-model:collapsed="sideCollapsed" title="计量｜左侧区">
        <section class="placeholder">
          <div class="placeholder-top">
            <div class="placeholder-title">计量期次：<b>{{ periodId }}</b></div>
            <button class="btn btn-sm" type="button" @click="openPeriodModal">切换期次</button>
          </div>
        </section>

        <div class="tree">
          <div
            class="tree-item"
            :class="{ 'is-active': row.leaf && row.id === selectedStructureId }"
            :style="{ paddingLeft: `${10 + row.level * 14}px` }"
            v-for="row in visibleTreeRows"
            :key="row.id"
            @click="onTreeRowClick(row)"
          >
            <button
              class="tree-caret"
              type="button"
              :class="{ 'is-leaf': row.leaf }"
              :disabled="row.leaf"
              @click.stop="toggleTreeExpand(row)"
            >
              {{ row.leaf ? "•" : row.open ? "▾" : "▸" }}
            </button>
            <span class="tree-bullet"></span>
            <span class="tree-text">{{ row.name }}</span>
          </div>
        </div>
      </SidePanel>

      <BottomPanel v-model:collapsed="bottomCollapsed">
        <template #header>
          <div class="tabs">
            <button class="tab" :class="{ 'is-on': activeTab === 'pay' }" type="button" @click="activeTab = 'pay'">计量支付</button>
            <button class="tab" :class="{ 'is-on': activeTab === 'boq' }" type="button" @click="activeTab = 'boq'">分解清单</button>
            <button class="tab" :class="{ 'is-on': activeTab === 'materials' }" type="button" @click="activeTab = 'materials'">项目主材</button>
          </div>
        </template>

        <table class="table" v-if="activeTab === 'pay'">
          <thead>
            <tr>
              <th>序号</th>
              <th>期次</th>
              <th>清单编号</th>
              <th>清单名称</th>
              <th>单位</th>
              <th>单价</th>
              <th>上期末计量数量</th>
              <th>本期计量数量</th>
              <th>本期计量金额</th>
              <th>开累计量数量</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="r in payRows" :key="r.no">
              <td>{{ r.no }}</td>
              <td>{{ r.period }}</td>
              <td>{{ r.code }}</td>
              <td>{{ r.name }}</td>
              <td>{{ r.unit }}</td>
              <td>{{ formatYuan(r.unitPrice) }}</td>
              <td>{{ formatNumber(r.prevQty, 2) }}</td>
              <td>{{ formatNumber(r.curQty, 2) }}</td>
              <td>{{ formatMoney(r.curAmt) }}</td>
              <td>{{ formatNumber(r.cumQty, 2) }}</td>
            </tr>
          </tbody>
        </table>

        <table class="table" v-else-if="activeTab === 'boq'">
          <thead>
            <tr><th>编码</th><th>细目内容</th><th>单位</th><th>数量</th><th>金额</th></tr>
          </thead>
          <tbody>
            <tr v-for="r in boqRows" :key="r.code">
              <td>{{ r.code }}</td>
              <td>{{ r.item }}</td>
              <td>{{ r.unit }}</td>
              <td>{{ r.qty }}</td>
              <td>{{ formatMoney(r.amount) }}</td>
            </tr>
          </tbody>
        </table>

        <table class="table" v-else>
          <thead>
            <tr><th>材料编码</th><th>名称</th><th>单位</th><th>数量</th></tr>
          </thead>
          <tbody>
            <tr v-for="r in materialRows" :key="r.code">
              <td>{{ r.code }}</td>
              <td>{{ r.name }}</td>
              <td>{{ r.unit }}</td>
              <td>{{ r.qty }}</td>
            </tr>
          </tbody>
        </table>
      </BottomPanel>

      <div class="modal-mask" v-show="periodModalOpen" @click.self="periodModalOpen = false">
        <div class="period-modal">
          <div class="period-modal-head">
            <div class="period-modal-title">切换计量期次</div>
            <button class="iconbtn" type="button" @click="periodModalOpen = false">✕</button>
          </div>

          <div class="period-list">
            <div
              class="tree-item"
              :class="{ 'is-active': p === periodDraft }"
              v-for="p in measurementPeriods"
              :key="p"
              @click="periodDraft = p"
            >
              <span class="tree-bullet"></span>
              <span class="tree-text">{{ p }}</span>
            </div>
          </div>

          <div class="period-actions">
            <button class="btn btn-ghost" type="button" @click="periodModalOpen = false">取消</button>
            <button class="btn" type="button" @click="confirmPeriod">确认</button>
          </div>
        </div>
      </div>
    </PageCanvas>
  </div>
</template>

<script setup>
import { computed, reactive, ref } from "vue";
import PageCanvas from "../../components/layout/PageCanvas.vue";
import SidePanel from "../../components/layout/SidePanel.vue";
import BottomPanel from "../../components/layout/BottomPanel.vue";
import { structures, elementTree } from "../../constants/structures.js";
import { measurementPeriods, getPayRows, getMaterialRows } from "../../constants/mock.js";
import { formatNumber, formatPercent, formatMoney, formatYuan } from "../../utils/format.js";

const periodId = ref("2025-12");
const periodModalOpen = ref(false);
const periodDraft = ref(periodId.value);

const sideCollapsed = ref(false);
const bottomCollapsed = ref(false);
const selectedStructureId = ref("S-001");
const activeTab = ref("pay");
const expanded = ref(new Set(["E-G-bridge", "E-G-main-bridge", "E-G-approach", "E-G-road"]));

const statusFilters = reactive({
  month_done: true,
  cum_done: true,
  value_not_settled: true,
});

const structureIndex = computed(() => Math.max(0, structures.findIndex((s) => s.id === selectedStructureId.value)));
const selectedStructureName = computed(() => structures.find((s) => s.id === selectedStructureId.value)?.name || "");

const visibleTreeRows = computed(() => {
  const rows = [];
  const walk = (node, level) => {
    const leaf = !node.children || node.children.length === 0;
    const open = expanded.value.has(node.id);
    rows.push({ id: node.id, name: node.name, level, leaf, open });
    if (!leaf && open) node.children.forEach((c) => walk(c, level + 1));
  };
  elementTree.forEach((n) => walk(n, 0));
  return rows;
});

const payRows = computed(() => getPayRows(periodId.value, structureIndex.value, selectedStructureName.value));

const boqRows = [
  { code: "BOQ-001", item: "混凝土浇筑", unit: "m³", qty: 120.5, amount: 385000 },
  { code: "BOQ-002", item: "钢筋制安", unit: "t", qty: 18.2, amount: 246000 },
  { code: "BOQ-003", item: "模板工程", unit: "㎡", qty: 560, amount: 112000 },
];

const materialRows = computed(() => getMaterialRows(structureIndex.value));

function toggleTreeExpand(row) {
  if (row.leaf) return;
  if (expanded.value.has(row.id)) expanded.value.delete(row.id);
  else expanded.value.add(row.id);
}

function onTreeRowClick(row) {
  if (row.leaf) {
    selectedStructureId.value = row.id;
    return;
  }
  toggleTreeExpand(row);
}

function openPeriodModal() {
  periodDraft.value = periodId.value;
  periodModalOpen.value = true;
}

function confirmPeriod() {
  periodId.value = periodDraft.value;
  periodModalOpen.value = false;
}
</script>

<style scoped>
.measurement-page {
  min-height: 100vh;
  font-family: var(--bim-font-cn);
}

.module-topbar {
  position: absolute;
  left: 514px;
  top: 36px;
  max-width: calc(100% - 554px);
  z-index: 99;
}

.field {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap;
  border-radius: 18px;
  border: 1px solid rgba(83, 214, 206, 0.26);
  background:
    radial-gradient(420px 120px at 18% 0%, rgba(83, 214, 206, 0.22), transparent 70%),
    linear-gradient(180deg, rgba(18, 32, 40, 0.94), rgba(15, 25, 32, 0.88));
  box-shadow:
    0 20px 56px rgba(0, 0, 0, 0.28),
    0 0 0 1px rgba(83, 214, 206, 0.12) inset;
  padding: 10px 14px;
}

.field-label {
  font-weight: 900;
  color: rgba(244, 252, 255, 0.92);
  font-size: 14px;
  white-space: nowrap;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(0, 0, 0, 0.2);
  color: rgba(255, 255, 255, 0.88);
  font-weight: 800;
  font-size: 13px;
  white-space: nowrap;
}

.chip input {
  width: 13px;
  height: 13px;
  margin: 0;
  accent-color: rgba(64, 224, 208, 0.92);
}

.chip-status::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 3px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: transparent;
}

.chip-status.chip-yellow::before { border-color: rgba(212, 136, 6, 0.4); background: rgba(212, 136, 6, 0.22); }
.chip-status.chip-green::before { border-color: rgba(47, 143, 47, 0.4); background: rgba(47, 143, 47, 0.22); }
.chip-status.chip-red::before { border-color: rgba(217, 54, 62, 0.4); background: rgba(217, 54, 62, 0.22); }

.placeholder {
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(0, 0, 0, 0.14);
  border-radius: 14px;
  padding: 10px;
  margin-bottom: 10px;
}

.placeholder-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.placeholder-title {
  color: rgba(222, 238, 244, 0.9);
  font-size: 13px;
  font-weight: 900;
}

.btn {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.88);
  border-radius: 12px;
  padding: 8px 10px;
  cursor: pointer;
}

.btn-sm {
  padding: 6px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 800;
}

.btn-ghost {
  background: rgba(255, 255, 255, 0.04);
}

.tree {
  display: grid;
  gap: 8px;
}

.tree-item {
  display: grid;
  grid-template-columns: 20px 10px 1fr;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  border-radius: 14px;
  border: 1px solid rgba(154, 186, 198, 0.22);
  background: linear-gradient(180deg, rgba(44, 58, 68, 0.58), rgba(37, 49, 58, 0.54));
  cursor: pointer;
}

.tree-item:hover {
  border-color: rgba(83, 214, 206, 0.32);
  background: linear-gradient(180deg, rgba(51, 67, 78, 0.66), rgba(43, 57, 67, 0.62));
}

.tree-item.is-active {
  border-color: rgba(132, 188, 255, 0.3);
  background: linear-gradient(180deg, rgba(112, 146, 198, 0.34), rgba(95, 128, 180, 0.28));
}

.tree-caret {
  border: 0;
  background: transparent;
  color: rgba(203, 230, 236, 0.88);
  cursor: pointer;
  font-size: 14px;
}

.tree-caret.is-leaf {
  cursor: default;
}

.tree-bullet {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(83, 214, 206, 0.85);
}

.tree-text {
  font-size: 13px;
  font-weight: 800;
  color: rgba(222, 238, 244, 0.9);
}

.tabs {
  display: flex;
  gap: 10px;
}

.tab {
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.08);
  color: rgba(214, 235, 241, 0.9);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  font-weight: 900;
  font-size: 12px;
}

.tab.is-on {
  border-color: rgba(83, 214, 206, 0.32);
  background: rgba(83, 214, 206, 0.24);
}

.table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}

.table th,
.table td {
  text-align: left;
  padding: 12px 14px;
  border-bottom: 1px solid rgba(178, 206, 216, 0.16);
}

.table th {
  color: rgba(219, 240, 246, 0.86);
  font-weight: 900;
  background: linear-gradient(90deg, rgba(12, 38, 52, 0.92), rgba(16, 47, 61, 0.86));
  position: sticky;
  top: 0;
  z-index: 2;
}

.table td {
  color: rgba(222, 238, 244, 0.86);
  background: linear-gradient(90deg, rgba(37, 51, 61, 0.42), rgba(31, 45, 54, 0.36));
}

.table tbody tr:hover td {
  background: linear-gradient(90deg, rgba(69, 102, 130, 0.36), rgba(56, 86, 113, 0.32));
}

.modal-mask {
  position: absolute;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  background: rgba(13, 36, 74, 0.08);
  backdrop-filter: blur(3px);
}

.period-modal {
  width: min(520px, calc(100% - 32px));
  border-radius: 18px;
  border: 1px solid rgba(83, 214, 206, 0.24);
  background:
    radial-gradient(260px 160px at 18% 0%, rgba(83, 214, 206, 0.14), transparent 62%) padding-box,
    linear-gradient(180deg, rgba(18, 26, 31, 0.94), rgba(14, 20, 25, 0.86)) padding-box;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.3);
  padding: 14px;
}

.period-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.period-modal-title {
  font-weight: 900;
  color: rgba(255, 255, 255, 0.9);
  font-size: 14px;
}

.period-list {
  margin-top: 12px;
  border-top: 1px solid rgba(83, 214, 206, 0.2);
  padding-top: 12px;
  display: grid;
  gap: 8px;
}

.period-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 12px;
}

.iconbtn {
  width: 30px;
  height: 30px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.42);
  color: rgba(11, 27, 58, 0.86);
  font-weight: 900;
  cursor: pointer;
}

@media (max-width: 1300px) {
  .module-topbar {
    left: 24px;
    right: 24px;
    top: 108px;
    max-width: none;
  }

  .field {
    flex-wrap: wrap;
  }
}
</style>
