<template>
  <div class="project-page">
    <PageCanvas>
      <SidePanel v-model:collapsed="sideCollapsed" title="项目｜左侧区">
        <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 === 'boq_decompose' }" type="button" @click="activeTab = 'boq_decompose'">分解清单</button>
            <button class="tab" :class="{ 'is-on': activeTab === 'materials' }" type="button" @click="activeTab = 'materials'">项目主材</button>
            <button class="tab" type="button" disabled>模型汇总（未选择）</button>
          </div>
        </template>

        <table class="table" v-if="activeTab === 'boq_decompose'">
          <thead>
            <tr>
              <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 decomposeRows" :key="r.code">
              <td>{{ r.code }}</td>
              <td>{{ r.name }}</td>
              <td>{{ r.unit }}</td>
              <td>{{ formatNumber(r.decomposeQty, 2) }}</td>
              <td>{{ formatNumber(r.changedQty, 2) }}</td>
              <td>{{ formatNumber(r.measuredQty, 2) }}</td>
              <td>{{ formatPercent(r.measureRate) }}</td>
              <td>{{ formatNumber(r.doneQty, 2) }}</td>
              <td>{{ formatPercent(r.doneRate) }}</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>
    </PageCanvas>
  </div>
</template>

<script setup>
import { computed, 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 { projects, getDecomposeRows, getMaterialRows } from "../../constants/mock.js";
import { formatNumber, formatPercent } from "../../utils/format.js";

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

const currentProject = computed(() => projects.find((p) => p.id === currentProjectId.value) || projects[0]);

const structureIndex = computed(() => Math.max(0, structures.findIndex((s) => s.id === selectedStructureId.value)));

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 decomposeRows = computed(() => getDecomposeRows(structureIndex.value, currentProject.value.scale));
const materialRows = computed(() => getMaterialRows(structureIndex.value, currentProject.value.scale));

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);
}
</script>

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

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

.tree-item {
  display: grid;
  grid-template-columns: 20px 10px 1fr;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  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);
}

.tab:disabled {
  opacity: 0.7;
  cursor: default;
}

.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));
}
</style>
