<template>
  <div>
    <PageHero
      kicker=""
      title="QHSE"
      subtitle="以合规为底线，以数据为驱动，实现风险隐患闭环与作业全过程可控，助力管理升级。"
    >
      <template #actions>
        <RouterLink
          class="btn btn-primary"
          style="border-radius: 0"
          to="/contact"
          >获取产品资料</RouterLink
        >
      </template>
    </PageHero>

    <main class="case-content">
      <div class="caseLayout">
        <aside class="timelineCol" aria-label="项目实施时间线">
          <div class="timeline">
            <div class="timelineTrack" aria-hidden="true">
              <div class="timelineRail"></div>
              <div
                class="timelineFill"
                :style="{ transform: `scaleY(${progress})` }"
              ></div>
            </div>

            <ol class="timelineSteps" role="list">
              <li
                v-for="(s, idx) in steps"
                :key="s.key"
                class="timelineStep"
                :data-state="stepState(idx)"
              >
                <button
                  type="button"
                  class="timelineBtn"
                  :aria-current="activeIndex === idx ? 'step' : 'false'"
                  @click="scrollToStep(s.key)"
                >
                  <span class="dot" aria-hidden="true"></span>
                  <span class="stepText">
                    <span class="stepTitle">{{ s.title }}</span>
                    <span class="stepSub muted">{{ s.sub }}</span>
                  </span>
                </button>
              </li>
            </ol>
          </div>
        </aside>

        <div class="contentCol">
          <!-- 项目背景 -->
          <section
            :ref="setStepEl('background')"
            id="step-background"
            class="case-section case-section--odd"
          >
            <div class="case-section__image">
              <img src="../../assets/images/case1.png" alt="设备管理场景" />
            </div>
            <div class="case-section__content">
              <h2>项目背景 破解QHSE管理痛点</h2>
              <p>
                托我方工业互联网平台，为XX油服公司上线QHSE系统，全面覆盖风险与隐患管理、作业许可与过程监督、应急与健康管理等核心模块，严格适配QHSE体系标准；同时与平台内设备管理、生产管理系统深度集成，实现数据互通、流程联动，构建一体化安全管控体系。
              </p>
            </div>
          </section>

          <!-- 核心落地成果 -->
          <section
            :ref="setStepEl('delivery')"
            id="step-delivery"
            class="case-section case-section--even"
          >
            <div class="case-section__image">
              <img src="../../assets/images/case2.png" alt="数字化管控系统" />
            </div>

            <div class="case-section__content">
              <h2>核心落地成果 实现合规化智能管控</h2>
              <p>
                托我方工业互联网平台，为XX油服公司上线QHSE系统，全面覆盖风险与隐患管理、作业许可与过程监督、应急与健康管理等核心模块，严格适配QHSE体系标准；同时与平台内设备管理、生产管理系统深度集成，实现数据互通、流程联动，构建一体化安全管控体系。
              </p>
            </div>
          </section>

          <!-- 预测性维护赋能 -->
          <section
            :ref="setStepEl('predictive')"
            id="step-predictive"
            class="case-section case-section--odd"
          >
            <div class="case-section__image">
              <img src="../../assets/images/case3.png" alt="预测性维护" />
            </div>
            <div class="case-section__content">
              <h2>核心落地成果 实现合规化智能管控</h2>
              <p>
                借助平台数采与数据处理能力，系统实现风险精准识别、隐患闭环治理，作业许可全程线上审批、过程实时监督；完善应急处置流程与健康管理体系，配套培训与体系支持功能，推动QHSE管理从被动应对向主动防控转型，全面提升现场作业安全水平。
              </p>
            </div>
          </section>

          <!-- 量化成效 -->
          <section
            :ref="setStepEl('kpi')"
            id="step-kpi"
            class="case-section case-section--even"
          >
            <div class="case-section__image">
              <img src="../../assets/images/case4.png" alt="量化成效展示" />
            </div>

            <div class="case-section__content">
              <h2>量化成效，降本增效成果显著</h2>
              <p>
                项目上线后，XX油服公司QHSE管理合规性与效能全面提升，各项核心指标均达成预期目标，具体成效如下：合规达标率提升至100%，风险隐患整改率提升60%，作业许可办理效率提升55%，应急处置响应时间缩短45%，安全事故发生率下降70%，人均安全管理效能提升35%，全面满足行业监管要求，筑牢安全生产防线。
              </p>
            </div>
          </section>
        </div>
      </div>
    </main>
  </div>
</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
import PageHero from "../../components/PageHero.vue";
import { Icon } from "@iconify/vue";

const steps = [
  { key: "background", title: "项目背景", sub: "问题识别与痛点分析" },
  { key: "delivery", title: "落地成果", sub: "系统上线与流程闭环" },
  { key: "predictive", title: "安全赋能", sub: "风险精准识别、隐患闭环治理" },
  { key: "kpi", title: "量化成效", sub: "指标提升与降本增效" },
];

const activeIndex = ref(0);
const progress = ref(0);
const stepEls = ref({});

const setStepEl = (key) => (el) => {
  if (!el) return;
  stepEls.value = { ...stepEls.value, [key]: el };
};

const prefersReducedMotion = () =>
  typeof window !== "undefined" &&
  window.matchMedia &&
  window.matchMedia("(prefers-reduced-motion: reduce)").matches;

const headerOffset = () => {
  if (typeof window === "undefined") return 72;
  const raw = getComputedStyle(document.documentElement)
    .getPropertyValue("--header-h")
    .trim();
  const n = Number.parseInt(raw, 10);
  return Number.isFinite(n) ? n : 72;
};

const clamp01 = (n) => Math.max(0, Math.min(1, n));

const orderedEls = computed(() =>
  steps.map((s) => stepEls.value[s.key]).filter(Boolean),
);

const computeActiveIndex = (y) => {
  let idx = 0;
  for (let i = 0; i < steps.length; i++) {
    const el = stepEls.value[steps[i].key];
    if (!el) continue;
    const top = el.getBoundingClientRect().top + window.scrollY;
    if (y >= top) idx = i;
  }
  return idx;
};

const computeProgress = (y) => {
  const els = orderedEls.value;
  if (els.length < 2) return 0;

  const first = els[0];
  const last = els[els.length - 1];
  const start = first.getBoundingClientRect().top + window.scrollY;
  const end = last.getBoundingClientRect().bottom + window.scrollY;
  const span = Math.max(1, end - start);
  return clamp01((y - start) / span);
};

let raf = 0;
const updateFromScroll = () => {
  raf = 0;
  if (typeof window === "undefined") return;
  const y = window.scrollY + headerOffset() + 130;
  activeIndex.value = computeActiveIndex(y);
  progress.value = computeProgress(y);
};

const onScroll = () => {
  if (raf) return;
  raf = window.requestAnimationFrame(updateFromScroll);
};

const scrollToStep = (key) => {
  const el = document.getElementById(`step-${key}`);
  if (!el) return;
  el.scrollIntoView({
    behavior: prefersReducedMotion() ? "auto" : "smooth",
    block: "start",
  });
};

const stepState = (idx) =>
  idx < activeIndex.value
    ? "done"
    : idx === activeIndex.value
      ? "active"
      : "todo";

onMounted(() => {
  updateFromScroll();
  window.addEventListener("scroll", onScroll, { passive: true });
  window.addEventListener("resize", onScroll, { passive: true });
});

onBeforeUnmount(() => {
  window.removeEventListener("scroll", onScroll);
  window.removeEventListener("resize", onScroll);
  if (raf) window.cancelAnimationFrame(raf);
});
</script>

<style scoped>
.case-content {
  max-width: 1300px;
  margin: 0 auto;
  padding: 60px 20px;
}

.caseLayout {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 26px;
  align-items: start;
}

.timelineCol {
  position: relative;
  height: 100%;
  min-height: 100vh;
}

.timeline {
  position: sticky;
  top: calc(var(--header-h) + 24px);
  padding: 10px 10px 12px 0;
  user-select: none;
  max-height: calc(100vh - var(--header-h) - 48px);
  overflow-y: auto;
}

.timelineTrack {
  position: absolute;
  left: 18px;
  top: 10px;
  bottom: 12px;
  border-radius: 1px;
  width: 2px;
}

.timelineRail {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.12);
  border-radius: 999px;
}

.timelineFill {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, #1d4ed8, #0ea5e9);
  border-radius: 999px;
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 140ms linear;
  will-change: transform;
}

.timelineSteps {
  margin: 0;
  padding: 0 0 0 2px;
  list-style: none;
  display: grid;
  gap: 10px;
}

.timelineStep {
  position: relative;
}

.timelineBtn {
  width: 100%;
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 12px;
  align-items: start;
  text-align: left;
  padding: 10px 12px 10px 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: inherit;
}

.timelineBtn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.14);
  border-radius: 12px;
}

.dot {
  width: 15px;
  height: 15px;
  border-radius: 999px;
  border: 1px solid rgba(15, 23, 42, 0.16);
  background: rgba(255, 255, 255, 0.92);
  display: grid;
  place-items: center;
  margin-left: 10px;
  margin-top: 2px;
  transition:
    background-color 220ms ease,
    border-color 220ms ease,
    box-shadow 220ms ease;
}
.stepText {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.stepTitle {
  /* font-weight: 900; */
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.stepSub {
  font-size: 12px;
  line-height: 1.35;
}

.timelineStep[data-state="active"] .dot {
  transform: scale(1.12);
  border-color: rgba(29, 78, 216, 0.38);
  box-shadow:
    0 0 0 6px rgba(37, 99, 235, 0.12),
    0 10px 24px rgba(29, 78, 216, 0.18);
  background: #1d4ed8;
}

.timelineStep[data-state="done"] .dot {
  background: linear-gradient(180deg, #1d4ed8, #0ea5e9);
  border-color: transparent;
  box-shadow: 0 4px 12px rgba(29, 78, 216, 0.3);
}

.timelineStep[data-state="todo"] .stepTitle {
  color: rgba(2, 6, 23, 0.72);
}

.case-section {
  display: flex;
  margin-bottom: 80px;
  position: relative;
  scroll-margin-top: calc(var(--header-h) + 120px);
}

.case-section--odd {
  flex-direction: row;
}

.case-section--even {
  flex-direction: row-reverse;
}

.case-section__image {
  flex: 1;
  min-width: 300px;

  overflow: hidden;
}

.case-section__image img {
  width: 100%;
  height: auto;
  display: block;
}

.case-section__content {
  flex: 1;
  padding: 30px;
  /* 
  box-shadow: 0 10px 40px rgba(15, 23, 42, 0.1); */
  margin-left: 20px;
  margin-right: 20px;
}

.case-section--even .case-section__content {
  margin-left: 20px;
  margin-right: 20px;
}

.case-section__content h2 {
  /* color: var(--brand-700); */
  font-size: 24px;
  margin-bottom: 16px;
  line-height: 1.3;
}

.case-section__content p {
  color: var(--slate-700);
  font-size: 16px;
  line-height: 1.8;
}

@media (max-width: 900px) {
  .caseLayout {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .timelineCol {
    display: none;
  }

  .case-section {
    flex-direction: column;
  }

  .case-section__image {
    order: 1;
    margin-bottom: 20px;
  }

  .case-section__content {
    order: 2;
    margin-left: 0;
    margin-right: 0;
    padding: 20px;
  }

  .case-section--even .case-section__content {
    order: 2;
  }
}

@media (max-width: 600px) {
  .case-content {
    padding: 40px 15px;
  }

  .case-section__content {
    padding: 15px;
  }
}

:deep(.pageHero) {
  background-image: url("../../assets/images/bg5.jpg");

  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  background-blend-mode: overlay;
  color: #111;
  border-bottom: none;
  padding: 80px 0;
}
:deep(.pageHero__subtitle) {
  color: #4f5055;
}
</style>
