<template>
  <div class="subcontract-page">
    <div class="canvas">
      <header class="topbar">
        <div class="topbar-center">
          <div class="model-title">{{ modelCenterStore.activeModelName }}</div>
        </div>
      </header>

      <section class="model-stage">
        <ModelPlaceholder />
      </section>

      <aside class="sidepanel" :class="{ 'is-collapsed': sideCollapsed }">
        <header class="sidepanel-header">
          <div class="sidepanel-title">分包｜左侧区</div>
          <button class="iconbtn" type="button" @click="sideCollapsed = !sideCollapsed">{{ sideCollapsed ? "▸" : "▾" }}</button>
        </header>
        <div class="sidepanel-body" v-show="!sideCollapsed">
          <section class="placeholder">
            <div class="placeholder-top">
              <div class="placeholder-title">合同分包构件树</div>
              <button class="btn btn-sm" type="button" @click="openContractModal">选择合同</button>
            </div>
            <div class="placeholder-sub">当前合同：<b>{{ selectedContractId }}</b></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>
        </div>
      </aside>

      <section class="bottompanel" :class="{ 'is-collapsed': bottomCollapsed }">
        <header class="bottompanel-header">
          <div class="tabs">
            <button class="tab" :class="{ 'is-on': activeTab === 'sub_boq' }" type="button" @click="activeTab = 'sub_boq'">分包清单</button>
            <button class="tab" :class="{ 'is-on': activeTab === 'sub_measure' }" type="button" @click="activeTab = 'sub_measure'">分包计量</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>
        </header>
        <button class="iconbtn bottompanel-toggle" type="button" @click="bottomCollapsed = !bottomCollapsed">{{ bottomCollapsed ? "▴" : "▾" }}</button>

        <div class="bottompanel-body" v-show="!bottomCollapsed">
          <table class="table" v-if="activeTab === 'sub_boq'">
            <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 subcontractRows" :key="r.code">
                <td>{{ r.code }}</td>
                <td>{{ r.name }}</td>
                <td>{{ r.unit }}</td>
                <td>{{ r.content }}</td>
                <td>{{ r.vendor }}</td>
                <td>{{ formatYuan(r.unitPrice) }}</td>
                <td>{{ formatNumber(r.qty, 2) }}</td>
                <td>{{ formatMoney(r.amount) }}</td>
                <td>{{ formatMoney(r.cumValue) }}</td>
              </tr>
            </tbody>
          </table>

          <div class="placeholder" v-else>
            <div class="placeholder-sub">当前合同：{{ selectedContractId }}；选中结构：{{ selectedStructureName || "未选择" }}（占位）。</div>
          </div>
        </div>
      </section>

      <div class="modal-mask" v-show="contractModalOpen" @click.self="closeContractModal">
        <div class="contract-modal">
          <div class="contract-modal-head">
            <div class="contract-modal-title">协作合同选择</div>
            <button class="iconbtn" type="button" @click="closeContractModal">✕</button>
          </div>

          <div class="contract-filters">
            <input class="input" placeholder="合同编号" v-model="contractFilterNo" />
            <input class="input" placeholder="队伍名称" v-model="contractFilterTeam" />
            <input class="input" placeholder="签订日期（YYYY-MM-DD）" v-model="contractFilterDate" />
          </div>

          <div class="contract-list">
            <table class="table">
              <thead>
                <tr>
                  <th>合同编号</th>
                  <th>合同名称</th>
                  <th>协作队伍名称</th>
                  <th>合同额</th>
                  <th>合同签订日期</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="c in filteredContracts" :key="c.id" :class="{ 'is-active': c.id === contractDraftId }" @click="contractDraftId = c.id">
                  <td>{{ c.no }}</td>
                  <td>{{ c.name }}</td>
                  <td>{{ c.team }}</td>
                  <td>{{ formatMoney(c.amount) }}</td>
                  <td>{{ c.date }}</td>
                </tr>
              </tbody>
            </table>
          </div>

          <div class="contract-actions">
            <button class="btn btn-ghost" type="button" @click="closeContractModal">取消</button>
            <button class="btn" type="button" @click="confirmContract">确认</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, ref } from "vue";
import ModelPlaceholder from "../../components/model-placeholder/index.vue";
import { useModelCenterStore } from "../../stores/modelCenter.js";

const modelCenterStore = useModelCenterStore();

const structures = [
  { id: "S-001", name: "主桥-0#墩" },
  { id: "S-002", name: "主桥-1#墩" },
  { id: "S-003", name: "主桥-2#墩" },
  { id: "S-004", name: "引桥-桩基" },
  { id: "S-005", name: "引桥-承台" },
  { id: "S-006", name: "引桥-盖梁" },
  { id: "S-007", name: "路基-填筑" },
  { id: "S-008", name: "路面-基层" },
  { id: "S-009", name: "路面-面层" },
];

const contracts = [
  { id: "sc-001", no: "SC-2025-001", name: "桥梁下部结构劳务分包", team: "一分包队伍", amount: 8600000, date: "2025-03-12" },
  { id: "sc-002", no: "SC-2025-002", name: "引桥上部结构劳务分包", team: "二分包队伍", amount: 6250000, date: "2025-04-08" },
  { id: "sc-003", no: "SC-2025-003", name: "路基路面专业分包", team: "三分包队伍", amount: 9800000, date: "2025-05-20" },
];

const elementTree = [
  {
    id: "E-G-bridge",
    name: "桥梁工程",
    children: [
      { id: "E-G-main-bridge", name: "主桥", children: ["S-001", "S-002", "S-003"].map((id) => ({ id, name: structures.find((s) => s.id === id)?.name || id })) },
      { id: "E-G-approach", name: "引桥", children: ["S-004", "S-005", "S-006"].map((id) => ({ id, name: structures.find((s) => s.id === id)?.name || id })) },
    ],
  },
  { id: "E-G-road", name: "道路工程", children: ["S-007", "S-008", "S-009"].map((id) => ({ id, name: structures.find((s) => s.id === id)?.name || id })) },
];

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

const contractModalOpen = ref(false);
const contractDraftId = ref(selectedContractId.value);
const contractFilterNo = ref("");
const contractFilterTeam = ref("");
const contractFilterDate = ref("");

const selectedStructureName = computed(() => structures.find((s) => s.id === selectedStructureId.value)?.name || "");
const selectedVendor = computed(() =>
  selectedContractId.value === "sc-001" ? "一分包队伍" : selectedContractId.value === "sc-002" ? "二分包队伍" : "三分包队伍"
);

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 filteredContracts = computed(() => {
  const qNo = contractFilterNo.value.trim();
  const qTeam = contractFilterTeam.value.trim();
  const qDate = contractFilterDate.value.trim();
  return contracts
    .filter((c) => (qNo ? c.no.includes(qNo) : true))
    .filter((c) => (qTeam ? c.team.includes(qTeam) : true))
    .filter((c) => (qDate ? c.date.includes(qDate) : true));
});

const subcontractRows = computed(() => {
  const structure = selectedStructureName.value;
  return Array.from({ length: 14 }, (_, i) => {
    const qty = 20 + i * 3;
    const unitPrice = 680 + i * 35;
    const amount = qty * unitPrice;
    const cumValue = amount * (0.2 + (i % 5) * 0.12);
    return {
      code: `SUB-${String(2001 + i)}`,
      name: `${["钢筋制安", "混凝土浇筑", "模板工程", "支架搭设", "土方外运", "路基填筑"][i % 6]}${structure ? `（${structure}）` : ""}`,
      unit: ["t", "m³", "㎡", "m³", "m³", "m³"][i % 6],
      content: ["劳务分包", "专业分包", "机械配合", "材料辅材"][i % 4],
      vendor: selectedVendor.value,
      unitPrice,
      qty,
      amount,
      cumValue,
    };
  });
});

function formatMoney(value) {
  if (value == null || Number.isNaN(value)) return "--";
  const abs = Math.abs(value);
  const sign = value < 0 ? "-" : "";
  if (abs >= 1e8) return `${sign}${(abs / 1e8).toFixed(2)}亿`;
  if (abs >= 1e4) return `${sign}${(abs / 1e4).toFixed(2)}万`;
  return `${sign}${abs.toFixed(2)}元`;
}

function formatYuan(value) {
  if (value == null || Number.isNaN(value)) return "--";
  return `${Number(value).toFixed(2)}元`;
}

function formatNumber(value, digits = 0) {
  return Number(value).toLocaleString("zh-CN", { minimumFractionDigits: digits, maximumFractionDigits: digits });
}

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 closeContractModal() {
  contractModalOpen.value = false;
}

function openContractModal() {
  contractDraftId.value = selectedContractId.value;
  contractModalOpen.value = true;
}

function confirmContract() {
  selectedContractId.value = contractDraftId.value;
  contractModalOpen.value = false;
}
</script>

<style scoped>
.subcontract-page {
  min-height: 100vh;
  font-family: "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", sans-serif;
}

.canvas {
  position: relative;
  min-height: 100vh;
  overflow: hidden;
  border-radius: 24px;
  border: 1px solid rgba(98, 191, 206, 0.34);
  background: radial-gradient(circle at 50% 30%, #bcc9d6 0%, #b2c3d2 60%, #a8b8c9 100%);
  box-shadow: inset 0 0 0 8px rgba(214, 230, 241, 0.55);
}

.topbar {
  position: absolute;
  inset: 0 0 auto;
  height: 120px;
  z-index: 30;
}

.topbar-center {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 16px;
  display: grid;
  justify-items: center;
}

.model-title {
  font-size: 20px;
  letter-spacing: 1px;
  font-weight: 700;
  color: rgba(255, 128, 52, 0.95);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}

.model-stage {
  position: absolute;
  inset: 0;
}

.sidepanel {
  position: absolute;
  left: 16px;
  top: 175px;
  width: 320px;
  bottom: 100px;
  border-radius: 18px;
  border: 1px solid rgba(83, 214, 206, 0.24);
  background:
    radial-gradient(260px 140px at 8% 0%, rgba(63, 203, 191, 0.16), transparent 62%) padding-box,
    linear-gradient(180deg, rgba(20, 31, 37, 0.92), rgba(15, 23, 29, 0.88)) padding-box;
  box-shadow:
    0 22px 60px rgba(0, 0, 0, 0.34),
    0 0 0 1px rgba(83, 214, 206, 0.12) inset;
  overflow: hidden;
  z-index: 25;
}

.sidepanel.is-collapsed {
  width: 64px;
}

.sidepanel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 10px 10px 12px;
  border-bottom: 1px solid rgba(83, 214, 206, 0.16);
  background:
    radial-gradient(360px 100px at 10% 0%, rgba(83, 214, 206, 0.24), transparent 68%),
    linear-gradient(180deg, rgba(28, 134, 122, 0.84), rgba(15, 60, 74, 0.62));
}

.sidepanel-title {
  font-size: 14px;
  font-weight: 900;
  color: rgba(207, 247, 242, 0.96);
}

.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;
}

.sidepanel-body {
  height: calc(100% - 52px);
  overflow: auto;
  padding: 8px;
}

.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;
}

.placeholder-sub {
  margin-top: 8px;
  color: rgba(222, 238, 244, 0.74);
  font-size: 12px;
  line-height: 1.5;
}

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

.bottompanel {
  position: absolute;
  left: 370px;
  right: 16px;
  bottom: 100px;
  height: 390px;
  border-radius: 18px;
  border: 1px solid rgba(83, 214, 206, 0.24);
  background:
    radial-gradient(420px 180px at 14% 0%, rgba(83, 214, 206, 0.2), transparent 66%) padding-box,
    radial-gradient(520px 220px at 82% 0%, rgba(40, 156, 228, 0.14), transparent 70%) padding-box,
    linear-gradient(180deg, rgba(18, 33, 40, 0.94), rgba(14, 24, 31, 0.9)) padding-box;
  box-shadow:
    0 24px 70px rgba(0, 0, 0, 0.36),
    0 0 0 1px rgba(83, 214, 206, 0.14) inset;
  overflow: hidden;
  z-index: 26;
}

.bottompanel-header {
  padding: 12px 52px 12px 12px;
  border-bottom: 1px solid rgba(83, 214, 206, 0.28);
  background:
    radial-gradient(380px 120px at 18% 0%, rgba(83, 214, 206, 0.28), transparent 70%),
    linear-gradient(180deg, rgba(25, 137, 124, 0.86), rgba(16, 66, 82, 0.64));
}

.bottompanel-toggle {
  position: absolute;
  right: 12px;
  top: 12px;
}

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

.bottompanel.is-collapsed {
  height: 70px;
}

.bottompanel-body {
  padding: 0 12px 12px;
  overflow: auto;
  height: calc(100% - 66px);
}

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

.table tbody tr.is-active td {
  background: linear-gradient(90deg, rgba(60, 110, 132, 0.46), rgba(54, 98, 120, 0.42));
}

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

.contract-modal {
  width: min(640px, 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;
}

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

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

.contract-filters {
  display: flex;
  gap: 10px;
  margin-top: 12px;
  flex-wrap: wrap;
}

.contract-filters .input {
  flex: 1;
  min-width: 160px;
  padding: 10px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.88);
  outline: none;
}

.contract-list {
  margin-top: 12px;
  border-top: 1px solid rgba(83, 214, 206, 0.2);
  padding-top: 12px;
  max-height: 340px;
  overflow: auto;
}

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

@media (max-width: 1300px) {
  .sidepanel {
    width: 280px;
  }

  .bottompanel {
    left: 330px;
  }
}
</style>
