<template>
  <div class="launchpad-container">
    <div class="header">
      <h2>快捷导航</h2>
      <div class="actions">
        <el-switch
          v-model="showCategory"
          active-text="显示分类"
          inactive-text=""
          @change="handleCategoryToggle"
          style="margin-right: 10px;"
        />
        <el-button @click="fetchMappings" :icon="Refresh" circle title="刷新" />
        <el-button @click="showSettings = true" :icon="Setting" circle title="图标设置" />
      </div>
    </div>

    <div v-loading="loading">
      <!-- 最近打开 -->
      <div v-if="recentApps.length > 0" class="recent-section">
        <h3 class="section-title">最近打开</h3>
        <div class="apps-grid">
          <div
            v-for="app in recentApps"
            :key="app.app_id"
            class="app-item"
            :style="{ width: iconSize + 'px' }"
          >
            <PlatformIcon
              :text="app.app_name"
              :size="iconSize"
              :icon-url="app.icon_url"
              :app-id="app.app_id"
              :icon-object-key="app.icon_object_key"
              @click="handleAppClick(app)"
            />
          </div>
        </div>
      </div>

      <!-- 按分类显示 -->
      <template v-if="showCategory">
        <div
          v-for="category in categorizedApps"
          :key="category.categoryId || 'uncategorized'"
          class="category-section"
        >
          <h3 class="category-title">{{ category.categoryName }}</h3>
          <div class="apps-grid">
            <div
              v-for="app in category.apps"
              :key="app.app_id"
              class="app-item"
              :style="{ width: iconSize + 'px' }"
            >
              <PlatformIcon
                :text="app.app_name"
                :size="iconSize"
                :icon-url="app.icon_url"
                :app-id="app.app_id"
                :icon-object-key="app.icon_object_key"
                @click="handleAppClick(app)"
              />
            </div>
          </div>
        </div>
      </template>

      <!-- 不按分类显示（原有方式） -->
      <div v-else>
        <h3 class="section-title">全部应用</h3>
        <div class="apps-grid">
          <div
            v-for="app in activeApps"
            :key="app.app_id"
            class="app-item"
            :style="{ width: iconSize + 'px' }"
          >
            <PlatformIcon
              :text="app.app_name"
              :size="iconSize"
              :icon-url="app.icon_url"
              :app-id="app.app_id"
              :icon-object-key="app.icon_object_key"
              @click="handleAppClick(app)"
            />
          </div>
        </div>
      </div>

      <div v-if="activeApps.length === 0 && !loading" class="empty-state">
        <el-empty description="暂无已配置的平台账号" />
        <el-button type="primary" @click="$router.push('/dashboard/apps')">去配置</el-button>
      </div>
    </div>

    <!-- Settings Drawer -->
    <el-drawer v-model="showSettings" title="显示设置" size="300px">
      <div class="setting-item">
        <span class="label">图标大小 ({{ iconSize }}px)</span>
        <el-slider v-model="iconSize" :min="60" :max="200" @change="saveSettings" />
      </div>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, onActivated } from 'vue'
import { Setting, Refresh } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import api from '../utils/request'
import { ssoLogin } from '../api/public'
import PlatformIcon from '../components/PlatformIcon.vue'

// 检测是否为移动端设备
const isMobile = () => {
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}

// Types
interface Mapping {
  app_name: string
  app_id: string
  protocol_type: string
  mapped_key: string
  mapped_email?: string
  is_active: boolean
  description?: string
  category_id?: number
  category_name?: string
  /** 解析后的 Logo URL */
  icon_url?: string | null
  icon_object_key?: string | null
}

interface CategoryGroup {
  categoryId: number | null
  categoryName: string
  apps: Mapping[]
}

interface RecentAppRecord {
  app_id: string
  app_name: string
  count: number
  lastOpenTime: number
}

// State
const mappings = ref<Mapping[]>([])
const loading = ref(false)
const showSettings = ref(false)
const showCategory = ref(false)

// Settings
const iconSize = ref(100)

// 新接口已经过滤了激活状态和协议类型，直接使用返回的应用列表
const activeApps = computed(() => {
  return mappings.value
})

// 按分类分组
const categorizedApps = computed(() => {
  const groups: Map<number | null, CategoryGroup> = new Map()
  
  // 初始化"未分类"组
  groups.set(null, {
    categoryId: null,
    categoryName: '未分类',
    apps: []
  })
  
  // 按分类分组
  activeApps.value.forEach(app => {
    const categoryId = app.category_id ?? null
    const categoryName = app.category_name || '未分类'
    
    if (!groups.has(categoryId)) {
      groups.set(categoryId, {
        categoryId,
        categoryName,
        apps: []
      })
    }
    
    groups.get(categoryId)!.apps.push(app)
  })
  
  // 转换为数组并排序：有分类的在前，未分类在最后
  const result = Array.from(groups.values())
  result.sort((a, b) => {
    if (a.categoryId === null) return 1
    if (b.categoryId === null) return -1
    return a.categoryName.localeCompare(b.categoryName, 'zh-CN')
  })
  
  return result
})

// 最近打开的应用记录
const recentApps = computed<Mapping[]>(() => {
  const records = loadRecentApps()
  if (records.length === 0) return []
  
  // 按最近打开时间排序，时间越近的越靠前
  const sortedRecords = records
    .sort((a, b) => {
      return b.lastOpenTime - a.lastOpenTime
    })
  
  // 从mappings中获取最新的应用信息，只返回仍然存在且激活的应用
  const result: Mapping[] = []
  for (const record of sortedRecords) {
    const app = mappings.value.find(a => a.app_id === record.app_id && a.is_active)
    if (app) {
      result.push(app)
      if (result.length >= 5) break
    }
  }
  
  return result
})

// 加载最近打开的应用记录
const loadRecentApps = (): RecentAppRecord[] => {
  try {
    const saved = localStorage.getItem('launchpad_recent_apps')
    if (saved) {
      return JSON.parse(saved)
    }
  } catch (e) {
    console.error('Failed to parse recent apps', e)
  }
  return []
}

// 保存最近打开的应用记录
const saveRecentApps = (records: RecentAppRecord[]) => {
  try {
    localStorage.setItem('launchpad_recent_apps', JSON.stringify(records))
  } catch (e) {
    console.error('Failed to save recent apps', e)
  }
}

// 记录应用打开
const recordAppOpen = (app: Mapping) => {
  if (!app.is_active) return
  
  const records = loadRecentApps()
  const existingIndex = records.findIndex(r => r.app_id === app.app_id)
  
  if (existingIndex >= 0) {
    // 更新现有记录：增加打开次数，更新最后打开时间
    records[existingIndex].count += 1
    records[existingIndex].lastOpenTime = Date.now()
    // 更新应用信息（名称等可能会变化）
    records[existingIndex].app_name = app.app_name
  } else {
    // 添加新记录
    records.push({
      app_id: app.app_id,
      app_name: app.app_name,
      count: 1,
      lastOpenTime: Date.now()
    })
  }
  
  saveRecentApps(records)
}

// Load Settings
const loadSettings = () => {
  const saved = localStorage.getItem('launchpad_settings')
  if (saved) {
    try {
      const parsed = JSON.parse(saved)
      if (parsed.iconSize) iconSize.value = parsed.iconSize
      if (parsed.showCategory !== undefined) showCategory.value = parsed.showCategory
    } catch (e) {
      console.error('Failed to parse settings', e)
    }
  }
}

// Save Settings
const saveSettings = () => {
  localStorage.setItem('launchpad_settings', JSON.stringify({
    iconSize: iconSize.value,
    showCategory: showCategory.value,
  }))
}

// 处理分类开关切换
const handleCategoryToggle = () => {
  saveSettings()
}

// Fetch Data
const fetchMappings = async () => {
  loading.value = true
  try {
    // 使用快捷导航专用接口，包含分类和描述信息
    const res = await api.get('/simple/me/launchpad-apps', { 
      params: { 
        _t: Date.now() 
      } 
    })
    if (res.data) {
      mappings.value = res.data.items
    }
  } catch (e) {
    console.error(e)
  } finally {
    loading.value = false
  }
}

// SSO / OIDC 进入逻辑
const handleAppClick = async (app: Mapping) => {
  if (!app.is_active) return
  
  // 记录应用打开
  recordAppOpen(app)
  
  const loadingMsg = ElMessage.info({
    message: `正在进入 ${app.app_name}...`,
    duration: 0
  })

  try {
    // 统一通过后端 /simple/sso-login 获取 redirect_url
    // SIMPLE_API: 返回带 ticket 的业务系统 URL
    // OIDC: 返回 Hydra 授权 URL
    const res = await ssoLogin(
      { app_id: app.app_id, username: '', password: '' },
      { 
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('access_token')}`
        }
      }
    )
    
    if (res.data && res.data.redirect_url) {
      if (isMobile()) {
        // 手机端直接在当前标签页打开
        window.location.href = res.data.redirect_url
      } else {
        // PC端在新标签页打开
        window.open(res.data.redirect_url, '_blank')
      }
      loadingMsg.close()
      ElMessage.success('已打开应用')
    } else {
      loadingMsg.close()
      ElMessage.error('SSO 登录失败：未返回跳转地址')
    }
  } catch (error: any) {
    loadingMsg.close()
    console.error('SSO 登录失败:', error)
    ElMessage.error(error.response?.data?.detail || 'SSO 登录失败')
  }
}

// Auto-refresh when tab becomes visible
const handleVisibilityChange = () => {
  if (!document.hidden) {
    fetchMappings()
  }
}

onMounted(() => {
  loadSettings()
  fetchMappings()
  document.addEventListener('visibilitychange', handleVisibilityChange)
})

onActivated(() => {
  fetchMappings()
})

onUnmounted(() => {
  document.removeEventListener('visibilitychange', handleVisibilityChange)
})
</script>

<style scoped>
.launchpad-container {
  padding: 20px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 30px;
}

.actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.apps-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
}

.app-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.category-section {
  margin-bottom: 40px;
}

.recent-section {
  margin-bottom: 40px;
}

.section-title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 2px solid #e4e7ed;
}

.category-title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 2px solid #e4e7ed;
}

.setting-item {
  margin-bottom: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.label {
  font-size: 14px;
  color: #606266;
}

.empty-state {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 50px;
}
</style>
