<template>
  <div class="admin-layout">
    <header class="admin-header">

      <!-- 管理端：显示 Logo / 医院端：显示医院名 -->
      <div class="logo-bar">
        <span v-if="!isHospitalMode" class="logo-text admin"> 康策CSM系统管理平台<span class="version">v1.0</span> </span>
        <span v-else class="logo-text hospital">{{ userStore.userInfo?.hospitalName || "医院端" }}</span>
      </div>

      <div class="header-middle">
        <!-- 顶部水平菜单：管理端 / 医院端共用，按当前顶层路由动态生成 -->
        <el-menu class="header-menu" mode="horizontal" :default-active="$route.path" :ellipsis="false" router>
          <el-menu-item v-for="item in sideRoutes" :key="item.path" :index="item.path">
            <SvgIcon :name="item.iconName" class="nav-icon" />
            <template #title>
              <span>{{ item.title }}</span>
            </template>
          </el-menu-item>
        </el-menu>

        <!-- 医院端：顶部菜单旁的快速提交按钮 -->
        <div v-if="isHospitalMode" class="header-quick-submit">
          <el-button type="primary" class="quick-submit-btn" @click="orderDialogStore.open()">
            <img src="@/assets/image/hospital/quick.svg" class="quick-icon" alt="" />
            <span>快速提交</span>
          </el-button>
        </div>
      </div>

      <div class="header-right">
        <el-dropdown trigger="hover" @command="handleCommand">
          <div class="user-trigger">
            <!-- <SvgIcon name="bell-filled" :size="20" color="#fff" /> -->
            <span class="username">{{
              userStore.userInfo?.name ||
              userStore.userInfo?.userName ||
              "管理员"
            }}</span>
            <el-avatar :size="40" :src="avatarSrc"></el-avatar>

            <!-- <el-icon>
              <ArrowDown />
            </el-icon> -->
          </div>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="password">修改密码</el-dropdown-item>
              <el-dropdown-item command="theme">更换主题</el-dropdown-item>
              <el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </header>

    <main class="admin-content">
      <slot />
    </main>

    <!-- 更换主题弹窗 -->
    <el-dialog v-model="themeDialogVisible" class="theme-dialog" :close-on-click-modal="false" align-center
      destroy-on-close>
      <div class="theme-body">
        <div class="theme-header">
          <span class="theme-title">更换主题</span>
          <img src="@/assets/image/close-btn.svg" alt="" class="close-btn" @click="themeDialogVisible = false">
        </div>
        <div class="theme-grid">
                    <div v-for="t in presetThemes" :key="t.value" class="theme-card"
            :class="{ active: themeStore.themeValue === t.value }" :style="{
              '--brand-color': t.borderColor
            }" @click="handlePresetTheme(t.value)">
            <div class="theme-preview" :style="{ background: t.preview, boxShadow: t.boxShadow }"></div>
            <div class="theme-name">{{ t.name }}</div>
            <div class="theme-desc">{{ t.desc }}</div>
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- 全局工单表单弹窗（医院端快速提交 / 列表编辑统一使用） -->
    <OrderFormDialog v-model="orderDialogStore.visible" :order-id="orderDialogStore.orderId"
      @success="onOrderDialogSuccess" />

    <!-- 修改密码弹窗（管理端 / 医院端共用，根据 role 走对应接口） -->
    <PasswordDialog v-model="passwordDialogVisible" :role="passwordRole" />

    <!-- 全局签到弹窗（医院端登录后自动触发，未签到时弹出） -->
    <SignInDialog v-model="signInDialogStore.visible" :signed-in="signInDialogStore.summary.isSignIn"
      :total-points="signInDialogStore.summary.totalPoints"
      :consecutive-sign-in-days="signInDialogStore.summary.consecutiveSignInDays"
      :sign-in-rank="signInDialogStore.summary.signInRank" :beat-percent="signInDialogStore.summary.beatPercent"
      :has-drawn="signInDialogStore.summary.isDraw" @success="onSignInDialogSuccess" />

    <!-- 全局奖励结果弹窗（抽奖/签到/提交工单 共用） -->
    <RewardResultDialog />

    <!-- 全局查看我的资产弹窗（由 RewardResultDialog 中点击"查看我的资产"触发） -->
    <AssetsDialog v-model="assetDialogStore.visible" :total-points="assetDialogStore.totalPoints"
      :exchange-goal="assetDialogStore.exchangeGoal" :reward-name="assetDialogStore.rewardName"
      :today-order="assetDialogStore.todayOrder" :today-sign-in="assetDialogStore.todaySignIn"
      :today-draw="assetDialogStore.todayDraw" />
  </div>
</template>

<script setup>
import { computed, onMounted, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessageBox } from "element-plus";
import { ArrowDown } from "@element-plus/icons-vue";
import SvgIcon from "@/components/SvgIcon/index.vue";
import { useUserStore } from "@/stores/api/user";
import { useThemeStore } from "@/stores/theme";
import { PRESET_THEMES } from "@/stores/theme/buildThemeVars.js";
import { useOrderDialogStore } from "@/stores/orderDialog";
import { useSignInDialogStore } from "@/stores/signInDialog";
import { useRewardResultStore } from "@/stores/rewardResult";
import { useAssetDialogStore } from "@/stores/assetDialog";
import OrderFormDialog from "@/views/hospital/orders/OrderFormDialog.vue";
import PasswordDialog from "@/components/PasswordDialog.vue";
import SignInDialog from "@/views/hospital/SignInDialog.vue";
import RewardResultDialog from "@/components/RewardResultDialog.vue";
import AssetsDialog from "@/views/hospital/AssetsDialog.vue";
import { getPoints, getPointsDetails } from "@/service/modular/hospital";
import dayjs from "dayjs";

// 头像(按性别)
import avatarMale from "@/assets/image/avatar-male.svg";
import avatarFemale from "@/assets/image/avatar-female.svg";

const route = useRoute();
const router = useRouter();
const userStore = useUserStore();
const themeStore = useThemeStore();
const orderDialogStore = useOrderDialogStore();
const signInDialogStore = useSignInDialogStore();
const rewardResultStore = useRewardResultStore();
const assetDialogStore = useAssetDialogStore();

// 当前是否为医院端（用于切换头部布局样式）
const isHospitalMode = computed(() => route.path.startsWith("/hospital"));

// 头部快速提交 / 列表编辑成功后通知当前路由对应的列表页刷新
const onOrderDialogSuccess = () => {
  // 触发全局事件，由 list.vue / detail.vue 监听
  window.dispatchEvent(new CustomEvent("hospital-order-saved"));
};

// 全局签到弹窗：签到成功后(已由 SignInDialog 自己 fireSigned + open reward result)
// 这里只负责同步刷新 summary 给后续 /hospital/points 页面用
const onSignInDialogSuccess = () => {
  signInDialogStore.refreshSummary();
  // 通知积分页同步刷新(向后兼容)
  window.dispatchEvent(new CustomEvent("hospital-signin-success"));
};

// 主题弹窗显隐
const themeDialogVisible = ref(false);

// 修改密码弹窗显隐
const passwordDialogVisible = ref(false);
// 修改密码：根据当前所在端选择对应接口
const passwordRole = computed(() => (isHospitalMode.value ? "hospital" : "admin"));

// 注册全局回调(只在第一次挂载时注册)
onMounted(() => {
  // 1) 签到成功(外层) -> 关闭签到弹窗 + 打开全局奖励结果弹窗
  //    (SignInDialog 内部已经自己关闭 + 打开 result; 这里只刷新 summary)
  if (typeof signInDialogStore.onSigned !== "function" || !signInDialogStore.onSigned.__layoutHook) {
    const hook = async () => {
      await signInDialogStore.refreshSummary();
    };
    hook.__layoutHook = true;
    signInDialogStore.onSigned = hook;
  }

  // 2) 奖励结果弹窗"查看我的资产" -> 取最新数据后打开 AssetsDialog
  if (typeof rewardResultStore.onViewAccount !== "function" || !rewardResultStore.onViewAccount.__layoutHook) {
    const hook = async () => {
      await openAssetsDialogWithFreshData();
    };
    hook.__layoutHook = true;
    rewardResultStore.onViewAccount = hook;
  }

  // 3) 医院端:第一次进入 layout 时检查一次今日签到状态
  if (!userStore.token) return;
  if (userStore.userInfo?.userType !== "Hospital") return;
  signInDialogStore.checkAndShow();
});

// 打开 AssetsDialog 时先拉最新积分和今日明细
const openAssetsDialogWithFreshData = async () => {
  try {
    const [summaryRes, detailsRes] = await Promise.all([
      getPoints(),
      getPointsDetails({ page: 1, pageSize: 50 }),
    ]);
    const summary = summaryRes?.data ?? summaryRes ?? {};
    const detailsData = detailsRes?.data ?? detailsRes ?? {};
    const list = detailsData.list || [];

    const today = dayjs().format("YYYY-MM-DD");
    const sumBy = (test) =>
      list
        .filter(
          (r) =>
            r.createdAt &&
            String(r.createdAt).startsWith(today) &&
            test(r.source),
        )
        .reduce(
          (s, r) => s + Math.abs(Number(r.changeAmount) || 0),
          0,
        );

    assetDialogStore.open({
      totalPoints: Number(summary.totalPoints) || 0,
      todayOrder: sumBy((s) => /工单|order/i.test(s || "")),
      todaySignIn: sumBy((s) => /签到|签/i.test(s || "")),
      todayDraw: sumBy((s) => /抽奖|抽/i.test(s || "")),
    });
  } catch (_) {
    assetDialogStore.open();
  }
};

// 预设主题配置：颜色 / 渐变端点 / 阴影 / 名称 / 描述均来自 buildThemeVars.PRESET_THEMES；
// preview 按当前 brandColor + gradientTo 组装，保持 to bottom（卡片圆球视觉）。
const presetThemes = computed(() =>
  Object.entries(PRESET_THEMES).map(
    ([value, { borderColor, gradientTo, boxShadow, name, desc }]) => ({
      value,
      borderColor,
      preview: `linear-gradient(to bottom, ${borderColor} 0%, ${gradientTo} 100%)`,
      boxShadow,
      name,
      desc,
    }),
  ),
);

// 选择预设主题
const handlePresetTheme = (value) => {
  themeStore.setTheme(value);
};





// 顶部水平菜单：根据当前顶层路由（/admin 或 /hospital）动态生成
// 图标 name 直接使用 meta.icon(去掉 admin-/hospital- 前缀后即为 SvgIcon 的 name)
const sideRoutes = computed(() => {
  const groupPath = isHospitalMode.value ? "/hospital" : "/admin";
  const groupRoute = route.matched.find((r) => r.path === groupPath);
  if (!groupRoute || !groupRoute.children) return [];
  return groupRoute.children
    .filter((c) => c.meta?.title && !c.meta?.hidden && !c.path.includes(":"))
    .map((c) => ({
      path: `${groupPath}/${c.path}`,
      title: c.meta.title,
      iconName: (c.meta?.icon || "").replace(/^(admin|hospital)-/, ""),
    }));
});

const currentTitle = computed(() => {
  const last = [...route.matched].reverse().find((r) => r.meta?.title);
  return last?.meta?.title || "管理端";
});

// 头像：sex === 1 用男,否则用女
const avatarSrc = computed(() => {
  return userStore.userInfo?.gender === '女' ? avatarFemale : avatarMale;
});

const handleCommand = async (cmd) => {
  if (cmd === "password") {
    passwordDialogVisible.value = true;
    return;
  }
  if (cmd === "theme") {
    themeDialogVisible.value = true;
    return;
  }
  if (cmd === "logout") {
    try {
      await ElMessageBox.confirm("确定要退出登录吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      });
      userStore.clear();
      router.push("/login");
    } catch (_) {
      /* canceled */
    }
  }
};
</script>

<style scoped lang="scss">
.admin-layout {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  background-color: #f9faff;
  padding: 32px;
  gap: 23px;
  background-image: url("@/assets/image/layout-bg.svg");
  background-repeat: no-repeat;
  background-size: 100% auto;
  background-position: right top;

  .admin-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0;
    height: 96px;
    border-radius: 16px 16px 16px 16px;
    border: 1px solid rgba(0, 0, 0, 0.1);
    background: linear-gradient(to right, #f9faff 0, #f9faff 75%, #a6cffe 100%);
    background: linear-gradient(to right, #f9faff 0, #f9faff 75%, var(--el-color-primary-light-8) 100%);

    .logo-bar {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 0 20px;
      font-size: 16px;
      font-weight: 600;
      white-space: nowrap;
      height: 100%;

      .logo-text {
        background: var(--linear-right);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        font-size: 22px;

        .version {
          font-size: 14px;
        }
      }
    }

    .header-middle {
      display: flex;
      align-items: center;
      height: 100%;
      min-width: 0;
    }

    .header-quick-submit {
      margin-left: 14px;
    }

    .quick-submit-btn {
      display: flex;
      align-items: center;
      gap: 6px;
      height: 36px;
      padding: 0 16px;
      border-radius: 18px;
      font-weight: 500;
      // background: linear-gradient(90deg, #3289FB 0%, #00B2FF 100%);
      background: var(--linear-right);
      border-radius: 28px 28px 28px 28px !important;
      border: 1px solid rgba(255, 255, 255, 0.15);
      width: 155px;
      height: 43px;
      font-weight: 400;
      font-size: 14px;
      color: #FFFFFF;

      .quick-icon {
        width: 16px;
        height: 16px;
        margin-right: 4px;
      }
    }

    .header-right {
      display: flex;
      align-items: center;
      height: 100%;
      padding-right: 30px;

      .user-trigger {
        display: flex;
        align-items: center;
        gap: 8px;
        cursor: pointer;
        font-weight: 600;
        font-size: 16px;
        color: #000000;
      }
    }

    .header-menu {
      height: 100%;
      flex-shrink: 0;
      flex-grow: 0;
      min-width: 0;

      background: transparent !important;
      border-bottom: none !important;
      height: 100%;
      display: flex;
      align-items: center !important;

      // 顶部一级菜单
      :deep(.el-menu-item) {
        font-weight: 400;
        font-size: 16px;
        color: #1d2129 !important;
        height: 60px;
        line-height: 60px;
        border-bottom: none !important;
        padding: 0 14px !important;
        display: flex;
        align-items: center;

        &:hover {
          // background-color: rgba(50, 137, 251, 0.08) !important;
          color: var(--brand-color) !important;
        }
      }

      // 一级激活
      :deep(.el-menu-item.is-active) {
        font-weight: 400;
        font-size: 16px;
        color: var(--brand-color) !important;
        background-color: transparent !important;
        border-bottom: none !important;

        &::after {
          display: none !important;
        }
      }
    }
  }

  .admin-content {
    flex: 1;
    overflow-x: hidden;
    overflow-y: auto;
  }
}

.nav-icon {
  width: 18px;
  height: 18px;
  margin-right: 6px;
  vertical-align: middle;
  object-fit: contain;
  flex-shrink: 0;
  color: currentColor;
}

// 医院端 Element Plus 图标尺寸
.el-icon.nav-icon {
  width: 18px;
  height: 18px;
  font-size: 18px;
  line-height: 18px;
  color: inherit;

  :deep(svg) {
    width: 18px;
    height: 18px;
  }
}
</style>

<style lang="scss">
.admin-layout {

  .el-menu-item:not(.is-disabled):focus,
  .el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
    background-color: transparent !important;
  }

}

.theme-dialog {
  width: max-content;
  border-radius: 24px 24px 24px 24px;

  .theme-body {
    padding: 24px 24px 33px;
    border-radius: 24px 24px 24px 24px;
    background-color: #fff;
    width: max-content;
    overflow: hidden;

    .theme-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-weight: 600;
      font-size: 20px;
      color: #1D2129;
      margin-bottom: 16px;

      .theme-title {
        font-weight: 600;
        font-size: 20px;
        color: #1D2129;
      }

      .close-btn {
        width: 30px;
        height: 30px;
        cursor: pointer;
      }
    }

    .theme-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 16px;

      .theme-card {
        width: 126px;
        height: 162px;
        border-radius: 12px 12px 12px 12px;
        border: 1px solid #E0E0E0;
        padding: 15px;
        cursor: pointer;
        transition: all 0.25s ease;
        text-align: center;
        background: #fff;
        white-space: nowrap;
        display: flex;
        flex-direction: column;
        align-items: center;

                &:hover {
          border-color: var(--brand-color);
        }

        &.active {
          border-color: var(--brand-color);
        }
      }

      .theme-preview {
        width: 64px;
        height: 64px;
        border: 4px solid #FFFFFF;
        border-radius: 50%;
        margin-bottom: 12px;
      }

      .theme-name {
        font-weight: 600;
        font-size: 14px;
        color: #1D2129;
        margin-bottom: 4px;
      }

      .theme-desc {
        font-weight: 400;
        font-size: 12px;
        color: #666666;
        white-space: pre-line;
      }
    }
  }
}
</style>
