<template>
  <div v-show="open" class="issue-overlay">
    <section
      ref="modalRef"
      class="issue-modal"
      :class="{ 'is-detail': view === 'detail' }"
      role="dialog"
      aria-modal="true"
      aria-label="设计问题智能管理"
      :style="style"
    >
      <header ref="headerRef" class="issue-modal-header" @pointerdown="onHeaderPointerDown"
        >
        <div class="issue-modal-left"
          >
            <button v-show="view === 'detail'" class="issue-back" type="button" aria-label="返回" @click="backToList"
              >←</button
            >
            <div class="issue-modal-title">{{ view === 'detail' ? '问题报告' : '设计问题智能管理' }}</div>
          </div>
        <button class="issue-close" type="button" aria-label="关闭" @click="$emit('close')">×</button>
      </header>

      <div class="issue-modal-body"
        >
        <div v-show="view === 'list'" class="issue-screen"
          >
            <section class="issue-card issue-card-form" aria-label="记录新问题"
              >
                <header class="issue-card-head"
                  >
                    <span class="issue-warn-dot" aria-hidden="true">!</span>
                    <div class="issue-card-title">记录新问题</div>
                  </header>

                <div class="issue-field"
                  >
                    <div class="issue-label">选中的构件</div>
                    <div class="issue-pick"
                      >
                        <div class="issue-picked" :class="{ 'is-picking': awaitingPick }" @click="enterPickMode"
                          >
                            <span class="issue-picked-icon" aria-hidden="true">⌖</span>
                            <span class="issue-picked-text">{{ selectedStructure ? selectedStructure.name : '未选择' }}</span>
                          </div>
                        <button class="issue-repick" type="button" @click="enterPickMode">重新选择</button>
                      </div>
                    <div v-show="awaitingPick" class="issue-pick-select"
                      >
                        <div class="issue-select-wrap"
                          >
                            <select class="issue-select" aria-label="下拉选择构件" v-model="pickId"
                              >
                                <option value="">（在模型中点击选择，或下拉选择）</option>
                                <option v-for="s in structures" :key="s.id" :value="s.id">{{ s.name }}</option>
                              </select>
                          </div>
                        <div class="issue-pick-hint">提示：也可直接在模型中点击构件进行选择</div>
                      </div>
                  </div>

                <div class="issue-field"
                  >
                    <div class="issue-label">问题描述</div>
                    <textarea
                      class="issue-textarea"
                      placeholder="描述设计问题，AI将自动补充构件名称、位置、专业等信息并整理为正式表述…"
                      v-model="descRaw"
                    />
                  </div>

                <button
                  class="issue-submit"
                  type="button"
                  :disabled="!canSubmit"
                  @click="submit"
                >提交问题（AI自动整理）</button>
              </section>

            <section class="issue-list" aria-label="问题列表" v-show="issues.length > 0"
              >
                <header class="issue-list-head"
                  >
                    <div class="issue-list-title">问题列表（{{ issues.length }}）</div>
                    <div class="issue-list-sub">可定位 · 可追溯 · 可统计</div>
                  </header>
                <div class="issue-list-body"
                  >
                    <div
                      class="issue-item"
                      v-for="it in issues"
                      :key="it.id"
                      @click="openDetail(it.id)"
                    
                      >
                        <div class="issue-item-top"
                          >
                            <div class="issue-item-title"
                              >
                                <div class="issue-item-name">{{ it.structureName || it.structureId || '构件' }}</div>
                                <div class="issue-tag">{{ it.discipline || '结构专业' }}</div>
                              </div>
                            <div class="issue-chevron" aria-hidden="true">›</div>
                          </div>
                        <div class="issue-item-meta"
                          >
                            <div class="issue-item-loc"
                              >
                                <span aria-hidden="true">⌁</span>
                                <span>{{ it.location || '空间位置待确认' }}</span>
                              </div>
                            <div>{{ formatDateTimeCN(it.createdAt) }}</div>
                          </div>
                        <div class="issue-item-desc">{{ it.descRaw || '（无描述）' }}</div>
                      </div>
                  </div>
              </section>
          </div>

        <div v-show="view === 'detail'" class="issue-screen"
          >
            <div v-if="activeIssue" class="issue-detail"
              >
                <div class="issue-detail-grid"
                  >
                    <div class="issue-kv"
                      ><div class="issue-k">构件名称</div><div class="issue-v">{{ activeIssue.structureName || activeIssue.structureId || '构件' }}</div></div>
                    <div class="issue-kv"
                      ><div class="issue-k">所属专业</div><div class="issue-v">{{ activeIssue.discipline || '结构专业' }}</div></div>
                    <div class="issue-kv"
                      ><div class="issue-k">空间位置</div><div class="issue-v">{{ activeIssue.location || '空间位置待确认' }}</div></div>
                    <div class="issue-kv"
                      ><div class="issue-k">问题状态</div><div class="issue-v">待整改（占位）</div></div>
                  </div>

                <div class="issue-box"
                  >
                    <div class="issue-box-title">原始问题描述</div>
                    <div class="issue-box-content">{{ activeIssue.descRaw || '（无）' }}</div>
                  </div>

                <div class="issue-box"
                  >
                    <div class="issue-box-title issue-ai-label">AI整理后的正式表述</div>
                    <div class="issue-ai-box">{{ activeIssue.descAi || '（AI整理占位）' }}</div>
                  </div>

                <div class="issue-views"
                  >
                    <div class="issue-box"
                      >
                        <div class="issue-box-title">模型视图｜三维视图</div>
                        <div class="issue-viewbox"
                          >3D 模型视图<br />{{ activeIssue.structureName || activeIssue.structureId || '构件' }}</div>
                      </div>
                    <div class="issue-box"
                      >
                        <div class="issue-box-title">二维视图</div>
                        <div class="issue-viewbox">2D 平面视图<br />{{ activeIssue.location || '空间位置待确认' }}</div>
                      </div>
                  </div>

                <div class="issue-footer-time">创建时间：{{ formatDateTimeCN(activeIssue.createdAt) }}</div>
              </div>
          </div>
      </div>
    </section>
  </div>
</template>

<script setup>
import { computed, ref, watch } from "vue";
import { useDraggableModal } from "../../composables/useDraggableModal.js";
import { structures } from "../../constants/structures.js";

const props = defineProps({
  open: Boolean,
});

const emit = defineEmits(["close", "toast", "save"]);

const STORAGE_KEY = "bim.issueManager.v1";

const view = ref("list");
const activeId = ref(null);
const issues = ref([]);
const pickId = ref("");
const awaitingPick = ref(false);
const descRaw = ref("");

const { modalRef, headerRef, style, onHeaderPointerDown, resetPosition } = useDraggableModal({ x: 0, y: 140 });

const selectedStructure = computed(() => structures.find((s) => s.id === pickId.value) || null);
const canSubmit = computed(() => !!selectedStructure.value && !!String(descRaw.value || "").trim());
const activeIssue = computed(() => issues.value.find((x) => x.id === activeId.value) || null);

watch(
  () => props.open,
  (val) => {
    if (val) {
      loadIssues();
      view.value = "list";
      activeId.value = null;
      awaitingPick.value = false;
      descRaw.value = "";
      pickId.value = "";
      resetPosition(window.innerWidth - 350, 140);
    }
  }
);

function loadIssues() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (!raw) return;
    const parsed = JSON.parse(raw);
    if (Array.isArray(parsed?.issues)) issues.value = parsed.issues;
  } catch {
    // ignore
  }
}

function saveIssues() {
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify({ issues: issues.value }));
  } catch {
    // ignore
  }
}

function formatDateTimeCN(iso) {
  const d = new Date(iso || Date.now());
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")} ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
}

function buildAiStatement({ discipline, structureName, location, descRaw }) {
  const d = (discipline || "结构专业").trim();
  const n = (structureName || "构件").trim();
  const loc = (location || "空间位置待确认").trim();
  const raw = (descRaw || "").trim();
  const core = raw ? raw.replace(/[。；;]+$/g, "") : "存在设计问题";
  return `【${d}-${n}】${n}(${loc})存在${core}，实际情况与设计要求不一致，需核查并修正。`;
}

function enterPickMode() {
  awaitingPick.value = true;
  emit("toast", "选取中：请在模型里点击构件");
}

function submit() {
  const s = selectedStructure.value;
  const raw = String(descRaw.value || "").trim();
  if (!s || !raw) return;
  const issue = {
    id: `ISS-${Date.now()}-${Math.floor(Math.random() * 1e6)}`,
    createdAt: new Date().toISOString(),
    structureId: s.id,
    structureName: s.name,
    discipline: s.discipline,
    location: s.location,
    descRaw: raw,
    descAi: buildAiStatement({ discipline: s.discipline, structureName: s.name, location: s.location, descRaw: raw }),
  };
  issues.value.unshift(issue);
  descRaw.value = "";
  awaitingPick.value = false;
  saveIssues();
  emit("toast", "已提交问题（AI整理占位）");
}

function openDetail(id) {
  activeId.value = id;
  view.value = "detail";
}

function backToList() {
  view.value = "list";
  activeId.value = null;
}
</script>

<style scoped>
.issue-overlay {
  position: absolute;
  inset: 0;
  z-index: 92;
  pointer-events: none;
}

.issue-modal {
  pointer-events: auto;
  position: fixed;
  right: 18px;
  top: 140px;
  width: min(820px, calc(100vw - 60px));
  max-height: min(820px, calc(100vh - 60px));
  transform-origin: right top;
  border-radius: 18px;
  border: 1px solid transparent;
  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,
    linear-gradient(135deg, rgba(83, 214, 206, 0.42), rgba(83, 214, 206, 0.14), rgba(0, 0, 0, 0)) border-box;
  box-shadow:
    0 32px 96px rgba(0, 0, 0, 0.48),
    0 0 28px rgba(83, 214, 206, 0.12),
    0 0 0 1px rgba(83, 214, 206, 0.12) inset,
    0 0 0 2px rgba(0, 0, 0, 0.1) inset;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto 1fr;
  backdrop-filter: blur(18px);
}

.issue-modal.is-detail {
  background:
    radial-gradient(260px 160px at 18% 0%, rgba(212, 136, 6, 0.1), transparent 62%) padding-box,
    radial-gradient(260px 160px at 18% 0%, rgba(83, 214, 206, 0.1), transparent 62%) padding-box,
    linear-gradient(180deg, rgba(18, 26, 31, 0.94), rgba(14, 20, 25, 0.86)) padding-box,
    linear-gradient(135deg, rgba(212, 136, 6, 0.42), rgba(212, 136, 6, 0.14), rgba(83, 214, 206, 0.1), rgba(0, 0, 0, 0)) border-box;
}

.issue-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  background:
    radial-gradient(520px 120px at 18% 0%, rgba(83, 214, 206, 0.14), transparent 70%),
    linear-gradient(180deg, rgba(18, 26, 31, 0.96), rgba(14, 20, 25, 0.86));
  user-select: none;
  cursor: grab;
}

.issue-modal.is-detail .issue-modal-header {
  border-bottom-color: rgba(212, 136, 6, 0.14);
  background:
    radial-gradient(520px 120px at 18% 0%, rgba(212, 136, 6, 0.12), transparent 70%),
    radial-gradient(520px 120px at 40% 0%, rgba(83, 214, 206, 0.1), transparent 72%),
    linear-gradient(180deg, rgba(18, 26, 31, 0.96), rgba(14, 20, 25, 0.86));
}

.issue-modal-header:active {
  cursor: grabbing;
}

.issue-modal-left {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.issue-modal-title {
  font-size: 22px;
  font-weight: 950;
  letter-spacing: 0.6px;
  color: rgba(255, 255, 255, 0.92);
}

.issue-modal.is-detail .issue-modal-title {
  background: linear-gradient(90deg, rgba(255, 190, 92, 0.98), rgba(255, 214, 122, 0.96));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.issue-back,
.issue-close {
  appearance: none;
  border: 0;
  background: transparent;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  color: rgba(255, 255, 255, 0.7);
  font-size: 28px;
  line-height: 1;
  font-weight: 900;
  cursor: pointer;
}

.issue-back {
  font-size: 22px;
}

.issue-back:hover,
.issue-close:hover {
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.92);
}

.issue-modal-body {
  padding: 20px;
  overflow: auto;
}

.issue-card,
.issue-list,
.issue-box {
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(0, 0, 0, 0.14);
  border-radius: 16px;
  padding: 14px;
}

.issue-card-head,
.issue-list-head,
.issue-item-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.issue-card-title,
.issue-list-title,
.issue-item-name,
.issue-box-title,
.issue-v {
  color: rgba(255, 255, 255, 0.9);
  font-weight: 900;
}

.issue-warn-dot {
  width: 22px;
  height: 22px;
  border-radius: 8px;
  background: rgba(212, 136, 6, 0.18);
  border: 1px solid rgba(212, 136, 6, 0.42);
  color: rgba(212, 136, 6, 0.95);
  display: grid;
  place-items: center;
}

.issue-field {
  display: grid;
  gap: 10px;
  margin-bottom: 18px;
}

.issue-label,
.issue-list-sub,
.issue-item-meta,
.issue-pick-hint {
  color: rgba(255, 255, 255, 0.62);
  font-weight: 900;
}

.issue-pick {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
}

.issue-pick-select {
  margin-top: 10px;
  display: grid;
  gap: 8px;
}

.issue-picked {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  min-height: 44px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.86);
  border-radius: 12px;
  cursor: pointer;
}

.issue-picked.is-picking {
  border-color: rgba(83, 214, 206, 0.34);
  box-shadow: 0 0 0 3px rgba(83, 214, 206, 0.1);
}

.issue-picked-icon {
  width: 28px;
  height: 28px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  background: rgba(212, 136, 6, 0.18);
  border: 1px solid rgba(212, 136, 6, 0.28);
  color: rgba(212, 136, 6, 0.95);
}

.issue-picked-text {
  font-weight: 900;
  color: rgba(255, 255, 255, 0.88);
}

.issue-repick {
  appearance: none;
  border: 0;
  background: transparent;
  color: rgba(212, 136, 6, 0.95);
  font-weight: 900;
  cursor: pointer;
  padding: 8px 10px;
  border-radius: 10px;
}

.issue-repick:hover {
  background: rgba(212, 136, 6, 0.12);
}

.issue-select {
  width: 100%;
  height: 52px;
  padding: 0 56px 0 12px;
  font-size: 16px;
  font-weight: 800;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.86);
  border-radius: 12px;
}

.issue-select-wrap {
  position: relative;
}

.issue-select-wrap::after {
  content: "▾";
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.08);
  display: grid;
  place-items: center;
  color: rgba(255, 255, 255, 0.7);
  font-weight: 900;
  pointer-events: none;
}

.issue-textarea {
  width: 100%;
  min-height: 88px;
  resize: vertical;
  padding: 12px;
  font-size: 16px;
  line-height: 1.55;
  outline: none;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.86);
  border-radius: 12px;
}

.issue-textarea:focus {
  border-color: rgba(83, 214, 206, 0.3);
  box-shadow: 0 0 0 4px rgba(83, 214, 206, 0.1);
}

.issue-submit {
  width: 100%;
  margin-top: 14px;
  height: 52px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.72);
  font-weight: 900;
  letter-spacing: 0.6px;
  cursor: not-allowed;
}

.issue-submit:not(:disabled) {
  cursor: pointer;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.88);
  box-shadow: 0 0 18px rgba(83, 214, 206, 0.12);
}

.issue-list-body {
  display: grid;
  gap: 10px;
  margin-top: 10px;
}

.issue-item {
  padding: 12px;
  cursor: pointer;
  display: grid;
  gap: 8px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.06);
  border-radius: 12px;
}

.issue-item:hover {
  border-color: rgba(83, 214, 206, 0.22);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.22);
}

.issue-item-title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.issue-chevron {
  color: rgba(255, 255, 255, 0.36);
  font-size: 20px;
  font-weight: 900;
}

.issue-tag {
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid rgba(83, 214, 206, 0.18);
  background: rgba(43, 191, 178, 0.14);
  color: rgba(83, 214, 206, 0.92);
  font-size: 12px;
  font-weight: 900;
}

.issue-item-meta {
  display: flex;
  align-items: center;
  gap: 10px;
}

.issue-item-loc {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.issue-item-desc {
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.14);
  padding: 10px;
  color: rgba(255, 255, 255, 0.74);
}

.issue-detail {
  display: grid;
  gap: 14px;
}

.issue-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.issue-k {
  color: rgba(255, 255, 255, 0.62);
  font-weight: 900;
  font-size: 12px;
}

.issue-box-content {
  padding: 12px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.86);
}

.issue-ai-label {
  color: rgba(212, 136, 6, 0.95);
}

.issue-ai-box {
  padding: 12px;
  border-color: rgba(255, 255, 255, 0.12);
  background: rgba(255, 248, 236, 0.16);
  color: rgba(255, 255, 255, 0.88);
  border-radius: 12px;
}

.issue-views {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.issue-viewbox {
  min-height: 224px;
  display: grid;
  place-items: center;
  color: rgba(255, 255, 255, 0.56);
  font-weight: 900;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(0, 0, 0, 0.14);
  border-radius: 12px;
}

.issue-footer-time {
  text-align: right;
  color: rgba(255, 255, 255, 0.46);
  font-weight: 800;
  font-size: 12px;
  padding: 6px 2px 0;
}

@media (max-width: 820px) {
  .issue-views,
  .issue-detail-grid {
    grid-template-columns: 1fr;
  }
}
</style>
