<template>
  <div
    ref="platformScreenRef"
    class="large-screen platform-screen"
    :class="{
      'is-home': activeModule.key === 'home',
      'is-forest-grass-wet': activeModule.key === 'forest-grass-wet',
      'is-ecological-protection': activeModule.key === 'ecological-protection',
      'is-grass-livestock-balance': activeModule.key === 'grass-livestock-balance',
      'is-yak-management': activeModule.key === 'yak-management',
      'is-pasture-management': activeModule.key === 'pasture-management',
      'is-yak-industry-chain': activeModule.key === 'yak-industry-chain',
      'is-smart-management': activeModule.key === 'smart-management',
      'is-ecology-national-park': activeModule.key === 'ecological-protection' && activeBottomKey === 'national-park',
    }"
    id="large-screen"
  >
    <div
      v-if="renderedModules.home"
      v-show="activeModule.key === 'home'"
      class="platform-module-pane"
    >
      <home-dashboard
        ref="homeDashboardRef"
        :active="activeModule.key === 'home'"
        @loading-progress="handleHomeLoadingProgress"
        @map-ready="handleHomeMapReady"
        @module-stats="handleModuleStats"
      />
    </div>
    <div
      v-if="renderedModules['forest-grass-wet']"
      v-show="activeModule.key === 'forest-grass-wet'"
      class="platform-module-pane"
    >
      <forest-grass-wet
        ref="forestGrassWetRef"
        :active="activeModule.key === 'forest-grass-wet'"
        :show-loading="false"
        @topic-stats="handleModuleStats"
      />
    </div>
    <div
      v-if="renderedModules['ecological-protection']"
      v-show="activeModule.key === 'ecological-protection'"
      class="platform-module-pane"
    >
      <ecological-protection
        ref="ecologicalProtectionRef"
        :active="activeModule.key === 'ecological-protection'"
        :active-view="activeEcologyView"
        :show-loading="false"
        @module-stats="handleModuleStats"
        @view-change="handleEcologyViewChange"
      />
    </div>
    <div
      v-if="renderedModules['grass-livestock-balance']"
      v-show="activeModule.key === 'grass-livestock-balance'"
      class="platform-module-pane"
    >
      <grass-livestock-balance
        :active="activeModule.key === 'grass-livestock-balance'"
        @loading-progress="handleHomeLoadingProgress"
        @map-ready="handleHomeMapReady"
        @module-stats="handleModuleStats"
      />
    </div>
    <div
      v-if="renderedModules['yak-management']"
      v-show="activeModule.key === 'yak-management'"
      class="platform-module-pane"
    >
      <yak-management
        ref="yakManagementRef"
        :active="activeModule.key === 'yak-management'"
        @module-stats="handleModuleStats"
      />
    </div>
    <div
      v-if="renderedModules['pasture-management']"
      v-show="activeModule.key === 'pasture-management'"
      class="platform-module-pane"
    >
      <pasture-management
        ref="pastureManagementRef"
        :active="activeModule.key === 'pasture-management'"
        @loading-progress="handleHomeLoadingProgress"
        @map-ready="handleHomeMapReady"
        @module-stats="handleModuleStats"
      />
    </div>
    <div
      v-if="renderedModules['yak-industry-chain']"
      v-show="activeModule.key === 'yak-industry-chain'"
      class="platform-module-pane"
    >
      <yak-industry-chain
        ref="yakIndustryChainRef"
        :active="activeModule.key === 'yak-industry-chain'"
        @loading-progress="handleHomeLoadingProgress"
        @map-ready="handleHomeMapReady"
        @module-stats="handleModuleStats"
      />
    </div>
    <div
      v-if="renderedModules['smart-management']"
      v-show="activeModule.key === 'smart-management'"
      class="platform-module-pane"
    >
      <wisdom-management :active="activeModule.key === 'smart-management'" />
    </div>

    <div class="large-screen-wrap">
      <m-header
        title="红原县数字畜牧业监管平台"
        sub-text="Hongyuan Digital Animal Husbandry Supervision Platform"
      >
        <template #right>
          <div class="m-header-tools">
            <button class="logout-button" aria-label="退出登录" title="退出登录" type="button" @click="handleLogout">
              <svg class="logout-icon" viewBox="0 0 24 24" aria-hidden="true">
                <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
                <path d="M16 17l5-5-5-5" />
                <path d="M21 12H9" />
              </svg>
            </button>
          </div>
        </template>
      </m-header>

      <div class="top-menu">
        <m-menu :default-active="activeModuleKey" @select="handleMenuSelect">
          <template v-for="(item, index) in platformModules" :key="item.key">
            <m-menu-item :index="item.key">{{ item.label }}</m-menu-item>
            <div v-if="index === 3" class="top-menu-mid-space"></div>
          </template>
        </m-menu>
      </div>

      <div
        v-if="totalView.length && !['smart-management', 'grass-livestock-balance'].includes(activeModule.key)"
        class="top-count-card"
        :class="{
          'is-four': totalView.length > 3 && totalView.length <= 4,
          'is-multi': totalView.length > 4,
          'is-national-park-stats': activeModule.key === 'ecological-protection' && activeBottomKey === 'national-park',
        }"
      >
        <div v-if="isNationalParkTopStats" class="np-stat-shell">
          <div class="np-stat-primary-row">
            <div v-for="item in nationalParkPrimaryStats" :key="item.zh" class="np-stat np-stat-primary">
              <div class="np-stat-name">{{ item.zh }}</div>
              <div class="np-stat-value-line">
                <span class="np-stat-value">{{ formatTopStatValue(item) }}</span>
                <span class="np-stat-unit">{{ item.unit }}</span>
              </div>
            </div>
          </div>
          <div class="np-stat-secondary-row">
            <div v-for="item in nationalParkSecondaryStats" :key="item.zh" class="np-stat np-stat-secondary">
              <span class="np-stat-name">{{ item.zh }}</span>
              <span class="np-stat-value">{{ formatTopStatValue(item) }}</span>
              <span class="np-stat-unit">{{ item.unit }}</span>
            </div>
          </div>
        </div>
        <template v-else>
          <m-count-card v-for="item in totalView" :key="item.zh" :info="item" />
        </template>
      </div>

      <div v-if="mapToolsVisible" class="platform-map-tools" aria-label="地图工具">
        <button type="button" :title="platformFullscreenLabel" :aria-label="platformFullscreenLabel" @click="handlePlatformFullscreen">
          <span class="platform-map-tool-icon is-fullscreen" aria-hidden="true"></span>
        </button>
        <button type="button" title="复位地图" aria-label="复位地图" @click="handleActiveMapReset">
          <span class="platform-map-tool-icon is-reset" aria-hidden="true"></span>
        </button>
      </div>

      <div v-if="activeModule.status !== 'ready'" class="module-coming">
        <div class="module-coming-title">{{ activeModule.label }}</div>
        <div class="module-coming-text">模块建设中，平台框架已预留入口</div>
      </div>

      <div
        v-if="!['home', 'forest-grass-wet', 'ecological-protection', 'grass-livestock-balance', 'yak-management', 'pasture-management', 'yak-industry-chain', 'smart-management'].includes(activeModule.key)"
        class="bottom-tray"
      >
        <m-svgline-animation
          class="bottom-svg-line-left"
          :width="721"
          :height="57"
          color="#30DCFF"
          :strokeWidth="2"
          :dir="[0, 1]"
          :length="50"
          path="M1 56.6105C1 31.5123 185.586 10.0503 451.904 1.35519C458.942 1.12543 465.781 4.00883 470.505 9.22964L484.991 25.2383C487.971 28.4775 492.938 30.4201 498.254 30.4201H720.142"
        />
        <m-svgline-animation
          class="bottom-svg-line-left bottom-svg-line-right"
          :width="721"
          :height="57"
          color="#30DCFF"
          :strokeWidth="2"
          :dir="[0, 1]"
          :length="50"
          path="M1 56.6105C1 31.5123 185.586 10.0503 451.904 1.35519C458.942 1.12543 465.781 4.00883 470.505 9.22964L484.991 25.2383C487.971 28.4775 492.938 30.4201 498.254 30.4201H720.142"
        />
        <div class="bottom-tray-arrow">
          <img src="@/assets/images/bottom-menu-arrow-big.svg" alt="" />
          <img src="@/assets/images/bottom-menu-arrow-small.svg" alt="" />
        </div>
        <div class="bottom-menu">
          <div
            v-for="item in bottomMenuItems"
            :key="item.key"
            class="bottom-menu-item"
            :class="{ 'is-active': item.key === activeBottomKey }"
            @click="handleBottomMenuSelect(item)"
          >
            <span>{{ item.bottomLabel }}</span>
          </div>
        </div>
        <div class="bottom-tray-arrow is-reverse">
          <img src="@/assets/images/bottom-menu-arrow-big.svg" alt="" />
          <img src="@/assets/images/bottom-menu-arrow-small.svg" alt="" />
        </div>
      </div>

      <div class="large-screen-left-zsline"></div>
      <div class="large-screen-right-zsline"></div>
    </div>

    <div v-if="loadingVisible" class="loading platform-loading">
      <div class="loading-text">
        <span style="--index: 1">L</span>
        <span style="--index: 2">O</span>
        <span style="--index: 3">A</span>
        <span style="--index: 4">D</span>
        <span style="--index: 5">I</span>
        <span style="--index: 6">N</span>
        <span style="--index: 7">G</span>
      </div>
      <div class="loading-progress">
        <span class="value">{{ loadingProgress }}</span>
        <span class="unit">%</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from "vue"
import autofit from "autofit.js"
import gsap from "gsap"
import mHeader from "@/components/mHeader/index.vue"
import mMenu from "@/components/mMenu/index.vue"
import mMenuItem from "@/components/mMenuItem/index.vue"
import mCountCard from "@/components/mCountCard/index.vue"
import mSvglineAnimation from "@/components/mSvglineAnimation/index.vue"
import HomeDashboard from "@/views/home/index.vue"
import ForestGrassWet from "@/views/forestGrassWet/index.vue"
import EcologicalProtection from "@/views/ecologicalProtection/index.vue"
import GrassLivestockBalance from "@/views/grassLivestockBalance/index.vue"
import YakManagement from "@/views/yakManagement/index.vue"
import PastureManagement from "@/views/pastureManagement/index.vue"
import YakIndustryChain from "@/views/yakIndustryChain/index.vue"
import WisdomManagement from "@/views/wisdomManagement/index.vue"
import { getModuleByKey, platformModules } from "@/config/modules"
import { ecologicalProtectionMenu } from "@/views/ecologicalProtection/data"
import { logout } from "@/services/auth"
import "@/assets/style/home.scss"

const activeModuleKey = ref("home")
const activeEcologyView = ref("national-park")
const renderedModules = ref({ home: true })
const moduleTopStats = ref({})
const loadingVisible = ref(true)
const loadingProgress = ref(0)
const platformScreenRef = ref(null)
const homeDashboardRef = ref(null)
const forestGrassWetRef = ref(null)
const ecologicalProtectionRef = ref(null)
const yakManagementRef = ref(null)
const pastureManagementRef = ref(null)
const yakIndustryChainRef = ref(null)
const platformFullscreen = ref(false)
let screenAutofit = null
let loadingHideStarted = false
let pendingModuleRenderTimer = null
let pendingModuleRenderFrame = null
const loadingStartedAt = Date.now()
const minLoadingVisibleMs = 1200
const loadingTweenState = { progress: 0 }

const topStatIconPool = [
  "town",
  "area",
  "wetland",
  "yield",
  "rate",
  "stack",
  "leaf",
  "risk",
  "grass-basic",
  "grass-general",
  "forest",
  "park",
  "project",
  "length",
  "device",
  "certificate",
]
const topStatIconSet = new Set(topStatIconPool)

const activeModule = computed(() => getModuleByKey(activeModuleKey.value))
const platformFullscreenLabel = computed(() => (platformFullscreen.value ? "退出" : "全屏"))
const mapToolsVisible = computed(() => !["smart-management", "grass-livestock-balance"].includes(activeModule.value.key))
const bottomMenuItems = computed(() => {
  if (activeModuleKey.value === "ecological-protection") return ecologicalProtectionMenu
  return platformModules
})
const activeBottomKey = computed(() => {
  if (activeModuleKey.value === "ecological-protection") return activeEcologyView.value
  return activeModuleKey.value
})
const isNationalParkTopStats = computed(
  () => activeModule.value.key === "ecological-protection" && activeBottomKey.value === "national-park",
)
const totalView = computed(() => {
  const currentStats = moduleTopStats.value[activeModuleKey.value]
  if (Array.isArray(currentStats)) return currentStats
  if (currentStats?.length) {
    return currentStats
  }
  return buildTopCountItems([
    {
      zh: "草地面积",
      en: "",
      value: 756.37,
      unit: "万亩",
      decimals: 2,
    },
    {
      zh: "林地总面积",
      en: "",
      value: 177.92,
      unit: "万亩",
      decimals: 2,
    },
    {
      zh: "湿地面积",
      en: "",
      value: 291.82,
      unit: "万亩",
      decimals: 2,
    },
  ])
})
const nationalParkPrimaryStats = computed(() => totalView.value.slice(0, 5))
const nationalParkSecondaryStats = computed(() => totalView.value.slice(5, 10))

onMounted(() => {
  screenAutofit = autofit.init({
    dh: 1080,
    dw: 1920,
    el: "#large-screen",
    resize: true,
  })
  bindPlatformFullscreenEvents()
  syncPlatformFullscreenState()
  resetRootScroll()
})

onBeforeUnmount(() => {
  screenAutofit?.off?.("#large-screen")
  unbindPlatformFullscreenEvents()
  if (pendingModuleRenderTimer) window.clearTimeout(pendingModuleRenderTimer)
  if (pendingModuleRenderFrame) window.cancelAnimationFrame(pendingModuleRenderFrame)
  gsap.killTweensOf(loadingTweenState)
})

function handleMenuSelect(key) {
  if (key === activeModuleKey.value) return
  const alreadyRendered = Boolean(renderedModules.value[key])
  activeModuleKey.value = key
  if (!alreadyRendered) scheduleActiveModuleRender(key)
  nextTick(resetRootScroll)
}

function handleBottomMenuSelect(item) {
  if (!item?.key) return
  if (activeModuleKey.value === "ecological-protection") {
    handleEcologyViewChange(item.key)
    return
  }
  handleMenuSelect(item.key)
}

function handleEcologyViewChange(key) {
  const nextKey = ecologicalProtectionMenu.some((item) => item.key === key) ? key : "national-park"
  if (nextKey === activeEcologyView.value && activeModuleKey.value === "ecological-protection") return
  activeEcologyView.value = nextKey
  nextTick(resetRootScroll)
}

function handleModuleStats(payload) {
  const moduleKey = payload.moduleKey || (payload.topicKey ? "forest-grass-wet" : activeModuleKey.value)
  moduleTopStats.value = {
    ...moduleTopStats.value,
    [moduleKey]: buildTopCountItems(payload.items || []),
  }
}

function handleHomeLoadingProgress(payload = {}) {
  const nextProgress = typeof payload === "number" ? payload : payload.progress
  updateLoadingProgress(nextProgress)
}

function handleHomeMapReady() {
  gsap.killTweensOf(loadingTweenState)
  loadingTweenState.progress = 100
  loadingProgress.value = 100
  const elapsed = Date.now() - loadingStartedAt
  const delay = Math.max(180, minLoadingVisibleMs - elapsed)
  window.setTimeout(hidePlatformLoading, delay)
}

function updateLoadingProgress(progress) {
  if (!loadingVisible.value) return
  const nextProgress = Math.max(0, Math.min(100, Math.floor(Number(progress) || 0)))
  if (nextProgress < loadingProgress.value) return
  gsap.to(loadingTweenState, {
    progress: nextProgress,
    duration: 0.35,
    ease: "power2.out",
    onUpdate: () => {
      loadingProgress.value = Math.floor(loadingTweenState.progress)
    },
  })
}

function hidePlatformLoading() {
  if (!loadingVisible.value || loadingHideStarted) return
  loadingHideStarted = true
  const tl = gsap.timeline({
    onComplete: () => {
      loadingVisible.value = false
    },
  })
  tl.to(".platform-loading .loading-text span", {
    y: "200%",
    opacity: 0,
    ease: "power4.inOut",
    duration: 1.4,
    stagger: 0.14,
  })
  tl.to(
    ".platform-loading .loading-progress",
    { opacity: 0, ease: "power4.inOut", duration: 1.2 },
    "<",
  )
  tl.to(
    ".platform-loading",
    { opacity: 0, ease: "power4.inOut", duration: 0.8 },
    "-=0.55",
  )
}

function buildTopCountItems(items = []) {
  const usedIcons = new Set()
  return items.slice(0, 10).map((item, index) => {
    const value = Number(item.value) || 0
    const normalized = {
      zh: item.zh || item.name || `指标${index + 1}`,
      en: item.en || "",
      value,
      unit: item.unit || "",
      decimals: item.decimals ?? (Number.isInteger(value) ? 0 : 2),
    }
    const icon = resolveUniqueTopStatIcon({ ...item, ...normalized }, index, usedIcons)
    usedIcons.add(icon)
    return {
      icon,
      ...normalized,
    }
  })
}

function resolveUniqueTopStatIcon(item = {}, index = 0, usedIcons = new Set()) {
  const candidates = getTopStatIconCandidates(item, index)
  const freshIcon = candidates.find((icon) => topStatIconSet.has(icon) && !usedIcons.has(icon))
  if (freshIcon) return freshIcon
  return topStatIconPool.find((icon) => !usedIcons.has(icon)) || topStatIconPool[index % topStatIconPool.length]
}

function getTopStatIconCandidates(item = {}, index = 0) {
  const text = `${item.zh || item.name || ""}${item.unit || ""}`
  const candidates = []
  const pushIcons = (...icons) => {
    icons.forEach((icon) => {
      if (icon && !candidates.includes(icon)) candidates.push(icon)
    })
  }

  pushIcons(item.icon)
  if (/风险|预警|告警/.test(text)) pushIcons("risk", "rate")
  if (/模型|修正|共识|预测|变化|净/.test(text)) pushIcons("rate", "stack")
  if (/率|占比|比例|超载/.test(text)) pushIcons("rate", "project")
  if (/生态牧场|家庭生态/.test(text)) pushIcons("leaf", "town")
  if (/出证|证书|证/.test(text)) pushIcons("certificate", "project")
  if (/交易|销售/.test(text)) pushIcons("yield", "certificate")
  if (/流通|出栏|流出/.test(text)) pushIcons("length", "certificate", "project")
  if (/运输|车辆|无人机|识别|设备|监测/.test(text)) pushIcons("device", "length")
  if (/工程长度|长度|公里/.test(text)) pushIcons("length", "project")
  if (/修复项目|项目|工程|治理/.test(text)) pushIcons("project", "length")
  if (/国家公园|保护范围|保护区|划定/.test(text)) pushIcons("park", "leaf")
  if (/产量|库容|鲜草|饲草|收入|产值|繁殖|补充/.test(text)) pushIcons("yield", "leaf")
  if (/湿地/.test(text)) pushIcons("wetland", "leaf")
  if (/基本草原/.test(text)) pushIcons("grass-basic", "area")
  if (/一般草原/.test(text)) pushIcons("grass-general", "area")
  if (/林地|森林|公益林/.test(text)) pushIcons("forest", "leaf")
  if (/面积|草地|草原|草场|万亩|亩/.test(text)) pushIcons("area", "grass-basic", "grass-general")
  if (/牦牛|存栏|头|结构/.test(text)) pushIcons("stack", "yield", "leaf")
  if (/乡镇|镇域|村|点位|主体|牧户|农户|联户|户|个|覆盖/.test(text)) pushIcons("town", "project")
  if (/生态|林草/.test(text)) pushIcons("leaf", "wetland")

  const start = index % topStatIconPool.length
  pushIcons(...topStatIconPool.slice(start), ...topStatIconPool.slice(0, start))
  return candidates
}

function formatTopStatValue(item = {}) {
  const value = Number(item.value) || 0
  const decimals = item.decimals ?? (Number.isInteger(value) ? 0 : 2)
  return value.toFixed(decimals)
}

function renderModule(key) {
  if (!["home", "forest-grass-wet", "ecological-protection", "grass-livestock-balance", "yak-management", "pasture-management", "yak-industry-chain", "smart-management"].includes(key)) return
  if (renderedModules.value[key]) return
  renderedModules.value = {
    ...renderedModules.value,
    [key]: true,
  }
}

function scheduleActiveModuleRender(key) {
  cancelActiveModuleRender()
  pendingModuleRenderTimer = window.setTimeout(() => {
    pendingModuleRenderTimer = null
    pendingModuleRenderFrame = window.requestAnimationFrame(() => {
      pendingModuleRenderFrame = null
      pendingModuleRenderTimer = null
      if (activeModuleKey.value !== key) return
      renderModule(key)
    })
  }, 180)
}

function cancelActiveModuleRender() {
  if (pendingModuleRenderTimer) {
    window.clearTimeout(pendingModuleRenderTimer)
    pendingModuleRenderTimer = null
  }
  if (pendingModuleRenderFrame) {
    window.cancelAnimationFrame(pendingModuleRenderFrame)
    pendingModuleRenderFrame = null
  }
}

function resetRootScroll() {
  window.scrollTo(0, 0)
  document.documentElement.scrollTop = 0
  document.body.scrollTop = 0
  const app = document.querySelector("#app")
  if (app) app.scrollTop = 0
}

const platformFullscreenEvents = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"]

function getPlatformFullscreenElement() {
  if (typeof document === "undefined") return null
  return document.fullscreenElement
    || document.webkitFullscreenElement
    || document.mozFullScreenElement
    || document.msFullscreenElement
    || null
}

function syncPlatformFullscreenState() {
  const fullscreenElement = getPlatformFullscreenElement()
  const root = platformScreenRef.value
  platformFullscreen.value = Boolean(root && fullscreenElement && (
    fullscreenElement === root
    || root.contains(fullscreenElement)
    || fullscreenElement.contains?.(root)
  ))
}

function bindPlatformFullscreenEvents() {
  if (typeof document === "undefined") return
  platformFullscreenEvents.forEach((eventName) => document.addEventListener(eventName, syncPlatformFullscreenState))
}

function unbindPlatformFullscreenEvents() {
  if (typeof document === "undefined") return
  platformFullscreenEvents.forEach((eventName) => document.removeEventListener(eventName, syncPlatformFullscreenState))
}

function refreshYakMapAfterResize() {
  getActiveMapModuleRef()?.refreshMapView?.()
}

async function handlePlatformFullscreen() {
  if (typeof document === "undefined") return
  const fullscreenElement = getPlatformFullscreenElement()
  try {
    if (fullscreenElement) {
      const exitFullscreen = document.exitFullscreen
        || document.webkitExitFullscreen
        || document.mozCancelFullScreen
        || document.msExitFullscreen
      await exitFullscreen?.call(document)
    } else {
      const target = platformScreenRef.value || document.documentElement
      const requestFullscreen = target.requestFullscreen
        || target.webkitRequestFullscreen
        || target.mozRequestFullScreen
        || target.msRequestFullscreen
      await requestFullscreen?.call(target)
    }
  } catch (error) {
    console.warn("[platform] fullscreen toggle failed", error)
  } finally {
    syncPlatformFullscreenState()
    window.setTimeout(refreshYakMapAfterResize, 80)
    window.setTimeout(refreshYakMapAfterResize, 280)
  }
}

function handleActiveMapReset() {
  getActiveMapModuleRef()?.resetMap?.()
}

function getActiveMapModuleRef() {
  if (activeModule.value.key === "home") return homeDashboardRef.value
  if (activeModule.value.key === "forest-grass-wet") return forestGrassWetRef.value
  if (activeModule.value.key === "ecological-protection") return ecologicalProtectionRef.value
  if (activeModule.value.key === "yak-management") return yakManagementRef.value
  if (activeModule.value.key === "pasture-management") return pastureManagementRef.value
  if (activeModule.value.key === "yak-industry-chain") return yakIndustryChainRef.value
  return null
}

function handleLogout() {
  logout()
}
</script>

<style lang="scss">
.platform-screen {
  position: fixed !important;
  left: 0;
  top: 0;
  margin: 0;

  &.is-forest-grass-wet {
    .large-screen-wrap::after {
      opacity: 0.28;
    }

    .large-screen-left-zsline,
    .large-screen-right-zsline {
      filter: brightness(1.3) drop-shadow(0 0 14px rgba(48, 220, 255, 0.32));
    }
  }

  &.is-home {
    .large-screen-wrap::after {
      opacity: 0.34;
    }

    .large-screen-left-zsline,
    .large-screen-right-zsline {
      filter: brightness(1.32) drop-shadow(0 0 16px rgba(36, 246, 196, 0.28));
    }
  }

  &.is-ecological-protection {
    .large-screen-wrap::after {
      opacity: 0.22;
    }
  }

  &.is-ecology-national-park {
    .top-menu-mid-space {
      width: 920px;
    }
  }

  &.is-grass-livestock-balance {
    .large-screen-wrap::after {
      opacity: 0.24;
    }

    .large-screen-left-zsline,
    .large-screen-right-zsline {
      filter: brightness(1.24) drop-shadow(0 0 14px rgba(255, 215, 108, 0.18));
    }
  }

  &.is-yak-management {
    .large-screen-wrap::after {
      opacity: 0.24;
    }

    .large-screen-left-zsline,
    .large-screen-right-zsline {
      filter: brightness(1.22) drop-shadow(0 0 14px rgba(48, 220, 255, 0.26));
    }
  }

  &.is-pasture-management {
    .large-screen-wrap::after {
      opacity: 0.26;
    }

    .large-screen-left-zsline,
    .large-screen-right-zsline {
      filter: brightness(1.28) drop-shadow(0 0 14px rgba(36, 246, 196, 0.28));
    }
  }

  &.is-yak-industry-chain {
    .large-screen-wrap::after {
      opacity: 0.24;
    }

    .large-screen-left-zsline,
    .large-screen-right-zsline {
      filter: brightness(1.28) drop-shadow(0 0 14px rgba(255, 224, 107, 0.2));
    }
  }

  &.is-smart-management {
    .large-screen-wrap::after {
      opacity: 0.2;
    }
  }

  .platform-module-pane {
    position: absolute;
    inset: 0;
    z-index: 1;
  }

  .platform-map-tools {
    position: absolute;
    left: 448px;
    bottom: 168px;
    z-index: 80;
    display: flex;
    flex-direction: column;
    gap: 7px;
    pointer-events: all;
    transform: perspective(620px) rotateY(6deg);
    transform-origin: left center;

    button {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 34px;
      height: 34px;
      padding: 0;
      border: 1px solid rgba(126, 251, 246, 0.62);
      border-radius: 3px;
      color: #f0feff;
      font-weight: 900;
      background:
        linear-gradient(180deg, rgba(18, 99, 123, 0.92), rgba(4, 36, 56, 0.96)),
        rgba(4, 24, 37, 0.9);
      box-shadow:
        0 0 14px rgba(48, 220, 255, 0.32),
        0 0 3px rgba(126, 251, 246, 0.4),
        inset 0 0 0 1px rgba(255, 255, 255, 0.1),
        inset 0 -8px 14px rgba(48, 220, 255, 0.16);
      cursor: pointer;

      &:hover {
        border-color: rgba(126, 251, 246, 0.76);
        color: #ffffff;
        background:
          linear-gradient(180deg, rgba(25, 127, 148, 0.96), rgba(6, 48, 68, 0.98)),
          rgba(6, 35, 52, 0.92);
        box-shadow:
          0 0 18px rgba(48, 220, 255, 0.42),
          0 0 4px rgba(126, 251, 246, 0.5),
          inset 0 0 0 1px rgba(255, 255, 255, 0.12),
          inset 0 -8px 14px rgba(48, 220, 255, 0.18);
      }

      &:active {
        transform: translateY(1px);
      }
    }
  }

  .platform-map-tool-icon {
    position: relative;
    flex: 0 0 15px;
    width: 15px;
    height: 15px;
    color: #7efbf6;

    &.is-fullscreen {
      background:
        linear-gradient(currentColor, currentColor) left top / 5px 2px no-repeat,
        linear-gradient(currentColor, currentColor) left top / 2px 5px no-repeat,
        linear-gradient(currentColor, currentColor) right top / 5px 2px no-repeat,
        linear-gradient(currentColor, currentColor) right top / 2px 5px no-repeat,
        linear-gradient(currentColor, currentColor) left bottom / 5px 2px no-repeat,
        linear-gradient(currentColor, currentColor) left bottom / 2px 5px no-repeat,
        linear-gradient(currentColor, currentColor) right bottom / 5px 2px no-repeat,
        linear-gradient(currentColor, currentColor) right bottom / 2px 5px no-repeat;
    }

    &.is-reset {
      width: 15px;
      height: 15px;
      border: 2px solid currentColor;
      border-left-color: transparent;
      border-radius: 50%;
      box-sizing: border-box;

      &::after {
        content: "";
        position: absolute;
        left: -2px;
        top: 0;
        width: 0;
        height: 0;
        border-top: 3px solid transparent;
        border-bottom: 3px solid transparent;
        border-right: 5px solid currentColor;
        transform: rotate(-18deg);
      }
    }
  }

  .top-menu {
    position: absolute;
    left: 50%;
    top: 46px;
    z-index: 10;
    transform: translateX(-50%);

    .m-menu {
      justify-content: center;
      align-items: center;
    }

    .m-menu-item {
      min-width: 118px;
      height: 34px;
      padding: 0 18px;
      font-size: 14px;
      line-height: 34px;
      letter-spacing: 0;
    }

    .m-menu-item.is-active::after {
      width: calc(100% - 12px);
      height: 28px;
      margin-left: calc(-50% + 6px);
      margin-top: -14px;
      border-radius: 28px;
      transform: none;
      animation: platformMenuActivePulse 1.35s ease-in-out infinite;
    }

    .top-menu-mid-space {
      width: 820px;
      height: 1px;
      pointer-events: none;
    }
  }

  .m-header-right {
    top: 8px;
    right: 12px;
    z-index: 30;
  }

  .m-header-tools {
    display: flex;
    align-items: center;
    gap: 12px;
    pointer-events: auto;
  }

  .logout-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid rgba(92, 232, 255, 0.72);
    border-radius: 2px;
    background:
      linear-gradient(180deg, rgba(28, 126, 166, 0.62), rgba(3, 32, 55, 0.86)),
      rgba(2, 18, 34, 0.72);
    box-shadow: inset 0 0 13px rgba(48, 220, 255, 0.18), 0 0 12px rgba(48, 220, 255, 0.2);
    color: #e7fbff;
    cursor: pointer;
    transition: border-color 0.18s ease, color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
  }

  .logout-icon {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .logout-button:hover {
    border-color: rgba(48, 220, 255, 0.78);
    box-shadow: inset 0 0 14px rgba(48, 220, 255, 0.16), 0 0 14px rgba(48, 220, 255, 0.22);
    color: #fff;
    transform: translateY(-1px);
  }

  .top-count-card {
    left: 420px;
    right: 420px;
    top: 108px;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 28px;
    justify-content: stretch;

    & > div {
      min-width: 0;
      padding: 0 !important;
      justify-content: center;
    }

    .count-card {
      min-width: 0;
      min-height: 90px;
    }

    .count-card-title,
    .count-card-left,
    .count-card-right {
      min-width: 0;
    }

    .count-card-icon {
      width: 76px;
      height: 90px;
      flex-basis: 76px;
      margin-right: 2px;
    }

    .count-card-right {
      padding-left: 10px;
    }

    .count-card-right .value {
      min-height: 32px;
      margin-right: 6px;
      font-size: 26px;
      line-height: 32px;
      letter-spacing: 0;
    }

    .count-card-right .unit {
      padding-top: 10px;
      line-height: 1;
    }

    .count-card-title .title-zh {
      font-size: 17px;
    }

    .count-card-title .title-en {
      max-width: 112px;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    &.is-four {
      left: 450px;
      right: 450px;
      top: 102px;
      grid-template-columns: repeat(4, minmax(0, 1fr));
      column-gap: 10px;

      .count-card-icon {
        width: 72px;
        height: 86px;
        flex-basis: 72px;
        margin-right: 2px;
      }

      .count-card-right {
        padding-left: 6px;
      }

      .count-card-right .value {
        min-height: 30px;
        font-size: 24px;
        line-height: 30px;
      }

      .count-card-right .unit {
        padding-top: 9px;
      }

      .count-card-title .title-zh {
        font-size: 15px;
      }

      .count-card-title .title-en {
        max-width: 90px;
        font-size: 10px;
      }
    }

    &.is-multi {
      left: 390px;
      right: 390px;
      top: 102px;
      grid-template-columns: repeat(5, minmax(0, 1fr));
      grid-auto-rows: 40px;
      column-gap: 12px;
      row-gap: 16px;
      z-index: 8;

      & > div {
        justify-content: flex-start;
      }

      .count-card {
        min-height: 40px;
      }

      .count-card-left {
        flex: 0 1 auto;
      }

      .count-card-icon {
        display: none;
      }

      .count-card-right {
        flex: 0 0 auto;
        padding-left: 8px;
      }

      .count-card-right .value {
        min-height: 28px;
        margin-right: 4px;
        font-size: 22px;
        line-height: 28px;
      }

      .count-card-right .unit {
        padding-top: 11px;
        font-size: 12px;
        opacity: 0.62;
      }

      .count-card-title .title-zh {
        max-width: none;
        font-size: 14px;
        line-height: 1.18;
        white-space: nowrap;
      }

      .count-card-title .title-en {
        display: none;
      }

      & > div:nth-child(6) {
        grid-column: 2;
      }

      & > div:nth-child(7) {
        grid-column: 3;
      }

      & > div:nth-child(8) {
        grid-column: 4;
      }
    }

    &.is-national-park-stats {
      left: 50%;
      right: auto;
      top: 100px;
      width: 1100px;
      height: 112px;
      position: absolute;
      transform: translateX(-50%);
      display: block;
      z-index: 7;

      &::before {
        content: "";
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        height: 64px;
        pointer-events: none;
        border-top: 1px solid rgba(75, 230, 255, 0.26);
        border-bottom: 1px solid rgba(75, 230, 255, 0.12);
        background:
          radial-gradient(ellipse at 50% 0%, rgba(65, 230, 255, 0.18), transparent 64%),
          linear-gradient(90deg, transparent, rgba(40, 210, 255, 0.1) 14%, rgba(40, 210, 255, 0.045) 50%, rgba(40, 210, 255, 0.1) 86%, transparent),
          linear-gradient(180deg, rgba(6, 73, 103, 0.14), rgba(2, 20, 36, 0.02));
        box-shadow: inset 0 1px 0 rgba(205, 253, 255, 0.12), 0 0 18px rgba(34, 210, 255, 0.06);
        clip-path: polygon(14px 0, calc(100% - 14px) 0, 100% 16px, 100% 100%, 0 100%, 0 16px);
      }

      &::after {
        content: "";
        position: absolute;
        left: 80px;
        right: 80px;
        top: 66px;
        height: 1px;
        pointer-events: none;
        background: linear-gradient(90deg, transparent, rgba(64, 230, 255, 0.52), transparent);
      }

      & > div {
        padding: 0 !important;
      }

      .np-stat-shell {
        position: relative;
        display: flex;
        flex-direction: column;
        gap: 11px;
        width: 100%;
        height: 100%;
        box-sizing: border-box;
      }

      .np-stat-primary-row,
      .np-stat-secondary-row {
        display: grid;
        grid-template-columns: repeat(5, minmax(0, 1fr));
        width: 100%;
      }

      .np-stat-primary-row {
        position: relative;
        height: 64px;
        padding: 0 12px;
        box-sizing: border-box;
      }

      .np-stat-secondary-row {
        position: relative;
        height: 34px;
        padding: 0 20px;
        border-top: 1px solid rgba(56, 220, 255, 0.18);
        border-bottom: 1px solid rgba(56, 220, 255, 0.1);
        background:
          linear-gradient(90deg, transparent, rgba(42, 215, 255, 0.1) 10%, rgba(42, 215, 255, 0.025) 50%, rgba(42, 215, 255, 0.1) 90%, transparent),
          linear-gradient(180deg, rgba(13, 88, 116, 0.16), rgba(3, 24, 42, 0.03));
        clip-path: polygon(10px 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
        box-sizing: border-box;
      }

      .np-stat {
        position: relative;
        min-width: 0;
        box-sizing: border-box;
        text-align: center;
      }

      .np-stat-primary {
        display: flex;
        flex-direction: column;
        justify-content: center;
        gap: 5px;
        padding: 5px 8px 4px;
      }

      .np-stat-primary::after {
        content: "";
        position: absolute;
        right: 0;
        top: 14px;
        bottom: 14px;
        width: 1px;
        background: linear-gradient(180deg, transparent, rgba(88, 232, 255, 0.34), transparent);
      }

      .np-stat-primary:last-child::after {
        content: none;
      }

      .np-stat-secondary {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        padding: 0 8px;
      }

      .np-stat-secondary::before {
        content: "";
        width: 4px;
        height: 4px;
        border-radius: 50%;
        background: rgba(66, 238, 255, 0.96);
        box-shadow: 0 0 8px rgba(66, 238, 255, 0.52);
        flex: 0 0 auto;
      }

      .np-stat-name {
        overflow: hidden;
        color: rgba(206, 250, 255, 0.78);
        font-size: 14px;
        font-weight: 600;
        line-height: 1;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .np-stat-value-line {
        display: flex;
        align-items: baseline;
        justify-content: center;
        min-width: 0;
      }

      .np-stat-value {
        color: #f7feff;
        font-family: D-DIN;
        font-size: 31px;
        font-weight: 700;
        line-height: 1;
        text-shadow: 0 0 14px rgba(255, 255, 255, 0.42), 0 0 18px rgba(48, 220, 255, 0.16);
        white-space: nowrap;
      }

      .np-stat-unit {
        margin-left: 4px;
        color: rgba(220, 252, 255, 0.7);
        font-size: 11px;
        font-weight: 600;
        white-space: nowrap;
      }

      .np-stat-secondary .np-stat-name {
        flex: 0 1 auto;
        max-width: 78px;
        font-size: 12px;
        font-weight: 500;
      }

      .np-stat-secondary .np-stat-value {
        flex: 0 0 auto;
        font-size: 20px;
        text-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
      }

      .np-stat-secondary .np-stat-unit {
        flex: 0 0 auto;
        margin-left: 2px;
        font-size: 10px;
      }
    }
  }

  .bottom-menu-item {
    width: 96px !important;
    margin: 0 2px;

    span {
      width: 96px !important;
      font-size: 13px;
    }
  }

  .bottom-svg-line-left,
  .bottom-svg-line-right {
    position: absolute;
    right: 50%;
    bottom: -21px;
    width: 721px;
    height: 57px;
    margin-right: -5px;
  }

  .bottom-svg-line-right {
    left: 50%;
    right: inherit;
    margin-left: -5px;
    margin-right: inherit;
    transform: scaleX(-1);
  }

  .module-coming {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 12;
    width: 360px;
    height: 130px;
    padding-top: 28px;
    border: 1px solid rgba(48, 220, 255, 0.28);
    background: rgba(3, 18, 30, 0.72);
    color: #fff;
    text-align: center;
    transform: translate(-50%, -50%);
    pointer-events: none;
    box-sizing: border-box;
  }

  .module-coming-title {
    font-size: 24px;
    font-weight: 700;
  }

  .module-coming-text {
    margin-top: 12px;
    color: rgba(255, 255, 255, 0.62);
    font-size: 14px;
  }

  .platform-loading {
    position: absolute;
    z-index: 99;

    .loading-text {
      gap: 10px;
      letter-spacing: 0;
    }
  }
}

@keyframes platformMenuActivePulse {
  0% {
    opacity: 0.68;
    box-shadow: 0 0 0 rgba(0, 170, 255, 0);
  }

  58% {
    opacity: 0.38;
    box-shadow: 0 0 14px rgba(48, 220, 255, 0.36);
  }

  100% {
    opacity: 0;
    box-shadow: 0 0 22px rgba(48, 220, 255, 0.12);
  }
}
</style>
