<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useTokenStore } from '@/store/token'
import { useUserStore } from '@/store'
import { workflowAPI } from '@/api/workflow'
import { bindPhone } from '@/api/appointment'
import { TMPL_CANCEL, TMPL_VISIT, TMPL_RESULT } from '@/utils/constants'

definePage({
  style: { navigationBarTitleText: '访客预约' },
})

const tokenStore = useTokenStore()
const userStore = useUserStore()
const { isEmployee, isGuard, isVisitor, userInfo } = storeToRefs(userStore)

// ==================== 引导页状态 ====================
/** 是否已调起订阅 API（含跳过） */
const subscribeDone = ref(false)
/** 是否主动跳过了订阅 */
const hasSkippedSubscribe = ref(true)
/** 订阅 API 请求中 */
const subscribing = ref(false)
/** 手机号绑定请求中 */
const bindingPhone = ref(false)

/** 用户是否已有手机号 */
const hasPhone = computed(() => !!userInfo.value?.phone)
/** 订阅步骤是否视为已完成（订阅成功或跳过） */
const subscribeEffectiveDone = computed(() => subscribeDone.value || hasSkippedSubscribe.value)
/** 两步全部完成 */
const allDone = computed(() => !!(userInfo.value?.phone && subscribeEffectiveDone.value))

// ==================== 入场动画 ====================
/** 入场动画 */
const guideReady = ref(false)
onMounted(async () => {
  // 检查是否已订阅通知（已订阅则自动跳过）
  // #ifdef MP-WEIXIN
  console.log('[订阅检测] 开始检查订阅状态')
  if (typeof (uni as any).getSubscribeMessageSetting === 'function') {
    try {
      const setting = await new Promise<any>((resolve, reject) => {
        (uni as any).getSubscribeMessageSetting({
          success: (res: any) => resolve(res),
          fail: (err: any) => reject(err),
        })
      })
      console.log('[订阅检测] 返回结果:', JSON.stringify(setting))
      if (setting?.settings) {
        SUBSCRIBE_TMPL_IDS.forEach(id => {
          console.log(`[订阅检测] 模板 ${id}:`, setting.settings[id]?.value)
        })
        const allAccepted = SUBSCRIBE_TMPL_IDS.every(id => setting.settings[id]?.value === 'accept')
        console.log('[订阅检测] 全部已接受:', allAccepted)
        if (allAccepted) {
          subscribeDone.value = true
          console.log('[订阅检测] 已标记订阅完成')
        }
      } else {
        console.log('[订阅检测] setting.settings 不存在')
      }
    } catch (err: any) {
      console.warn('[订阅检测] 接口调用失败:', err.errMsg || err)
    }
  } else {
    console.log('[订阅检测] getSubscribeMessageSetting 接口不可用')
  }
  // #endif
  setTimeout(() => { guideReady.value = true }, 30)
})

// ==================== 订阅通知 ====================
/** 订阅模板 ID */
const SUBSCRIBE_TMPL_IDS = [
  TMPL_VISIT,
  TMPL_RESULT,
  TMPL_CANCEL,
]

async function handleSubscribe() {
  // #ifdef MP-WEIXIN
  subscribing.value = true
  try {
    const res = await uni.requestSubscribeMessage({
      tmplIds: SUBSCRIBE_TMPL_IDS,
    })
    console.log('订阅结果:', res)
    subscribeDone.value = true
    uni.showToast({ title: '订阅成功，审核结果及时知', icon: 'success' })
  } catch (err: any) {
    // 用户拒绝订阅也是正常情况，不阻断流程
    console.warn('订阅失败或取消:', err)
    subscribeDone.value = true
  } finally {
    subscribing.value = false
  }
  // #endif
  // #ifndef MP-WEIXIN
  subscribeDone.value = true
  // #endif
}

/** 跳过订阅 */
function skipSubscribe() {
  hasSkippedSubscribe.value = true
  uni.showToast({ title: '可在设置中重新开启通知', icon: 'none' })
}

// ==================== 手机号绑定（微信 getPhoneNumber） ====================
async function onGetPhoneNumber(e: any) {
  if (e.detail.errMsg !== 'getPhoneNumber:ok') {
    uni.showToast({ title: '请授权手机号以接收通知', icon: 'none' })
    return
  }
  bindingPhone.value = true
  try {
    // 先获取微信 code
    const loginRes = await uni.login()
    await bindPhone({
      code: loginRes.code!,
      encrypted_data: e.detail.encryptedData,
      iv: e.detail.iv,
    })
    await userStore.fetchUserInfo()
    uni.showToast({ title: '手机号绑定成功，可接收通知提醒', icon: 'success' })
  } catch (err: any) {
    uni.showToast({ title: err.message || '手机号绑定失败', icon: 'error' })
  } finally {
    bindingPhone.value = false
  }
}

// ==================== 子功能入口 ====================
interface SubMenu {
  title: string
  desc: string
  icon: string
  path: string
  show: boolean
  color: string
}

const subMenus = computed<SubMenu[]>(() => [
  {
    title: '创建预约',
    desc: '为访客创建来访预约',
    icon: 'i-carbon-edit',
    path: '/subpackages/appointment/notice',
    show: isVisitor.value || isEmployee.value,
    color: '#2979ff',
  },
  {
    title: '我的预约',
    desc: '查看和管理我的预约记录',
    icon: 'i-carbon-list',
    path: '/subpackages/appointment/appointment-list',
    show: true,
    color: '#18bc37',
  },
  {
    title: '待审批',
    desc: '我的待审批任务',
    icon: 'i-carbon-checkmark',
    path: '/subpackages/appointment/pending-approvals',
    show: isEmployee.value,
    color: '#e67e22',
  },
  {
    title: '我关注的',
    desc: '预约到我的及我审批过的',
    icon: 'i-carbon-list-boxes',
    path: '/subpackages/appointment/approval-list',
    show: isEmployee.value,
    color: '#2979ff',
  },
  {
    title: '保安工作台',
    desc: '扫码核验、登记进出场',
    icon: 'i-carbon-scan',
    path: '/subpackages/appointment/guard-workbench',
    show: isGuard.value,
    color: '#ff9900',
  },
])

const visibleMenus = computed(() => {
  // 保安：只有「保安工作台」
  if (isGuard.value) {
    return subMenus.value.filter(m => m.title === '保安工作台')
  }
  // 员工/访客：依据 subMenus 各自的 show 条件
  return subMenus.value.filter(m => m.show)
})

// ==================== 待审批任务计数 ====================
const pendingCount = ref(0)

async function loadPendingCount() {
  if (!isEmployee.value) return
  try {
    const tasks = await workflowAPI.getPendingTasks()
    pendingCount.value = (tasks as any)?.length || 0
  } catch { /* ignore */ }
}

onMounted(() => {
  loadPendingCount()
})

function goPage(path: string) {
  if (!tokenStore.hasLogin) {
    uni.navigateTo({ url: `/pages/auth/login?redirect=${encodeURIComponent(path)}` })
    return
  }
  uni.navigateTo({ url: path })
}
</script>

<template>
  <view class="appointment-page">
    <!-- ============ 引导页：订阅 + 手机号（合并展示） ============ -->
    <view v-if="!allDone" class="guide-page min-h-screen bg-[#f5f7fa]">

      <!-- 入场包装器 -->
      <view
        :class="[
          'transition-all duration-500 ease-out',
          guideReady ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-6',
        ]"
      >
        <!-- ────── 顶部 Hero ────── -->
        <view class="guide-hero relative overflow-hidden px-6 pb-14 pt-14"
          style="background: linear-gradient(150deg, #2979ff 0%, #0d47a1 100%);"
        >
          <!-- 装饰圆 -->
          <view class="absolute -right-16 -top-16 h-52 w-52 rounded-full bg-white/6" />
          <view class="absolute -bottom-12 -left-12 h-36 w-36 rounded-full bg-white/6" />
          <view class="absolute right-12 top-1/2 h-20 w-20 rounded-full bg-white/4" />

          <view class="relative z-10 flex flex-col items-center">
            <!-- 图标 -->
            <view
              class="hero-icon mb-5 flex h-22 w-22 items-center justify-center rounded-full bg-white/18"
            >
              <view class="i-carbon-notification text-5xl text-white" />
            </view>
            <!-- 标题 -->
            <text class="text-2xl font-bold text-white">开启消息通知</text>
            <!-- 话术描述 -->
            <text class="mt-3 max-w-xs text-center text-sm leading-relaxed text-white/75">
              订阅通知并绑定手机号，第一时间收取
              <text class="text-white/90 font-medium">预约审核结果、访客到访提醒</text>，
              重要信息不错过
            </text>
          </view>
        </view>

        <!-- ────── 步骤卡片区 ────── -->
        <view class="-mt-6 px-4 pb-8">

          <!-- 进度指示 -->
          <view class="mb-6 flex items-center justify-center gap-3">
            <!-- 步骤 1 点 -->
            <view class="flex items-center gap-1.5">
              <view
                class="step-dot h-2.5 w-2.5 rounded-full transition-colors duration-300"
                :class="subscribeEffectiveDone ? 'bg-green-500' : 'bg-blue-500'"
              />
              <text
                class="text-xs font-medium transition-colors duration-300"
                :class="subscribeEffectiveDone ? 'text-green-600' : 'text-blue-600'"
              >
                {{ subscribeEffectiveDone ? '已订阅' : '订阅通知' }}
              </text>
            </view>
            <!-- 连接线 -->
            <view
              class="step-line h-0.5 w-10 rounded transition-colors duration-300"
              :class="hasPhone ? 'bg-green-400' : 'bg-gray-300'"
            />
            <!-- 步骤 2 点 -->
            <view class="flex items-center gap-1.5">
              <view
                class="step-dot h-2.5 w-2.5 rounded-full transition-colors duration-300"
                :class="
                  hasPhone
                    ? 'bg-green-500'
                    : subscribeEffectiveDone
                      ? 'bg-blue-500'
                      : 'bg-gray-300'
                "
              />
              <text
                class="text-xs font-medium transition-colors duration-300"
                :class="
                  hasPhone
                    ? 'text-green-600'
                    : subscribeEffectiveDone
                      ? 'text-blue-600'
                      : 'text-gray-400'
                "
              >
                {{ hasPhone ? '已绑定' : '绑定手机' }}
              </text>
            </view>
          </view>

          <!-- ════════ 步骤 1：订阅通知 ════════ -->
          <view
            class="step-card mb-3 overflow-hidden rounded-2xl bg-white shadow-sm transition-all duration-300"
            :class="subscribeEffectiveDone ? 'ring-1 ring-green-100' : ''"
          >
            <!-- 卡片头部 -->
            <view class="flex items-center px-5 py-4">
              <!-- 序号 / 勾选 -->
              <view
                class="step-badge flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-sm font-bold transition-all duration-300"
                :class="subscribeEffectiveDone ? 'bg-green-500' : 'bg-blue-500'"
              >
                <view
                  v-if="subscribeEffectiveDone"
                  class="i-carbon-checkmark text-base text-white animate-scale-in"
                />
                <text v-else class="text-white">1</text>
              </view>
              <!-- 信息 -->
              <view class="ml-3 flex-1 min-w-0">
                <view class="flex items-center gap-1.5">
                  <view class="i-carbon-notification text-base text-[#2979ff]" />
                  <text class="block text-[15px] font-semibold text-[#1a1a1a]">订阅消息通知</text>
                </view>
                <text class="mt-0.5 block text-xs text-[#999]">
                  {{ subscribeEffectiveDone ? '已开启，审核结果及时推送' : '预约审核、访客到访即时送达' }}
                </text>
              </view>
              <!-- 状态 -->
              <view v-if="subscribeEffectiveDone" class="shrink-0">
                <text class="text-xs font-medium text-green-500">
                  {{ subscribeDone ? '已订阅' : '已跳过' }}
                </text>
              </view>
            </view>

            <!-- 操作区（未完成时展开） -->
            <view
              v-if="!subscribeEffectiveDone"
              class="step-action border-t border-gray-50 px-5 py-3.5"
            >
              <view class="flex gap-3">
                <wd-button
                  plain
                  round
                  class="flex-1"
                  @click="skipSubscribe"
                >
                  暂不开启
                </wd-button>
                <wd-button
                  type="primary"
                  round
                  class="flex-1"
                  :loading="subscribing"
                  @click="handleSubscribe"
                >
                  开启订阅
                </wd-button>
              </view>
            </view>
          </view>

          <!-- ════════ 步骤 2：绑定手机号 ════════ -->
          <view
            class="step-card overflow-hidden rounded-2xl bg-white shadow-sm transition-all duration-300"
            :class="[
              hasPhone ? 'ring-1 ring-green-100' : '',
              !subscribeEffectiveDone && !hasPhone ? 'opacity-55' : '',
            ]"
          >
            <!-- 卡片头部 -->
            <view class="flex items-center px-5 py-4">
              <!-- 序号 / 勾选 -->
              <view
                class="step-badge flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-sm font-bold transition-all duration-300"
                :class="
                  hasPhone
                    ? 'bg-green-500'
                    : subscribeEffectiveDone
                      ? 'bg-blue-500'
                      : 'bg-gray-300'
                "
              >
                <view
                  v-if="hasPhone"
                  class="i-carbon-checkmark text-base text-white animate-scale-in"
                />
                <text
                  v-else
                  class="text-white"
                  :class="subscribeEffectiveDone ? '' : 'text-white/60'"
                >
                  2
                </text>
              </view>
              <!-- 信息 -->
              <view class="ml-3 flex-1 min-w-0">
                <view class="flex items-center gap-1.5">
                  <view class="i-carbon-phone text-base" :style="{ color: hasPhone ? '#18bc37' : '#999' }" />
                  <text
                    class="block text-[15px] font-semibold transition-colors"
                    :class="hasPhone ? 'text-[#1a1a1a]' : 'text-[#999]'"
                  >
                    绑定手机号
                  </text>
                </view>
                <text
                  class="mt-0.5 block text-xs transition-colors"
                  :class="hasPhone ? 'text-[#999]' : 'text-[#bbb]'"
                >
                  {{ hasPhone ? '已绑定，可正常接收通知' : '完成身份验证，保障账号安全' }}
                </text>
              </view>
              <!-- 状态 -->
              <view v-if="hasPhone" class="shrink-0">
                <text class="text-xs font-medium text-green-500">已绑定</text>
              </view>
            </view>

            <!-- 操作区 -->
            <view v-if="!hasPhone" class="step-action border-t border-gray-50 px-5 py-3.5">
              <!-- 可操作：展示微信一键获取按钮 -->
              <button
                v-if="subscribeEffectiveDone"
                class="phone-btn w-full"
                open-type="getPhoneNumber"
                @getphonenumber="onGetPhoneNumber"
              >
                <wd-button
                  block
                  type="success"
                  round
                  :loading="bindingPhone"
                >
                  <view class="flex items-center gap-1.5">
                    <view class="i-carbon-phone text-sm text-white" />
                    <text>微信手机号一键获取</text>
                  </view>
                </wd-button>
              </button>
              <!-- 不可操作：提示先完成上一步 -->
              <text v-else class="block text-center text-xs text-[#bbb]">
                请先完成「订阅消息通知」
              </text>
            </view>
          </view>

          <!-- ────── 底部行动点 ────── -->
          <view class="mt-8 flex flex-col items-center">
            <wd-button
              size="large"
              block
              round
              type="primary"
              :disabled="!allDone"
              :class="[allDone ? '' : 'opacity-40']"
              @click="goPage('/subpackages/appointment/appointment-list')"
            >
              开启访客预约之旅 →
            </wd-button>
          </view>
        </view>
      </view>
    </view>

    <!-- ═══════════════════════════════════════════
         ============ 完成：展示功能入口 ============
         ═══════════════════════════════════════════ -->
    <template v-if="allDone">
      <!-- ────── 头部 Banner ────── -->
      <view class="main-hero px-5 pb-8 pt-6"
        style="background: linear-gradient(150deg, #2979ff 0%, #0d47a1 100%);"
      >
        <text class="text-xl font-bold text-white">访客预约</text>
      </view>

      <!-- ────── 子功能入口列表 ────── -->
      <view class="-mt-4 px-4 pb-6">

        <view class="flex flex-col gap-3">
          <view
            v-for="(menu, idx) in visibleMenus"
            :key="menu.title"
            class="menu-card flex items-center rounded-xl bg-white p-4 shadow-sm active:scale-[0.97] transition-all duration-150"
            :style="{ animationDelay: `${idx * 60}ms` }"
            @click="goPage(menu.path)"
          >
            <view
              class="flex h-11 w-11 items-center justify-center rounded-xl"
              :style="{ backgroundColor: menu.color + '15' }"
            >
              <view :class="[menu.icon, 'text-xl']" :style="{ color: menu.color }" />
            </view>
            <view class="ml-3 flex-1">
              <text class="block text-sm font-semibold text-[#1a1a1a]">{{ menu.title }}</text>
              <text class="mt-0.5 block text-xs text-[#999]">{{ menu.desc }}</text>
            </view>
            <view v-if="menu.title === '待审批' && pendingCount > 0" class="mr-1">
              <wd-badge :model-value="pendingCount" :max="99" />
            </view>
            <view class="i-carbon-chevron-right text-sm text-[#ccc]" />
          </view>
        </view>
      </view>
    </template>

  </view>
</template>

<style lang="scss" scoped>
.appointment-page {
  min-height: 100vh;
  background-color: #f5f7fa;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

// ========== Guide Hero ==========
.guide-hero {
  position: relative;
  isolation: isolate;
}

.hero-icon {
  width: 88rpx;
  height: 88rpx;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

// ========== Step Card ==========
.step-card {
  transition: transform 0.2s, box-shadow 0.2s, opacity 0.3s;

  &:active {
    transform: scale(0.995);
  }
}

.step-badge {
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
}

.step-action {
  animation: fadeSlideIn 0.25s ease-out;
}

// ========== Menu Card ==========
.menu-card {
  animation: fadeInUp 0.35s ease-out both;
}

// ========== Phone Button Reset ==========
.phone-btn {
  background: transparent;
  border: none;
  padding: 0;
  margin: 0;
  line-height: inherit;

  &::after {
    border: none;
  }
}

// ========== Step Dot / Line ==========
.step-dot,
.step-line {
  flex-shrink: 0;
}

// ========== Keyframes ==========
@keyframes fadeSlideIn {
  from {
    opacity: 0;
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
  }
  to {
    opacity: 1;
    max-height: 120rpx;
    padding-top: 28rpx;
    padding-bottom: 28rpx;
  }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(12rpx);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes scaleIn {
  from {
    transform: scale(0);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

:global(.animate-scale-in) {
  animation: scaleIn 0.25s ease-out;
}
</style>
