<template>
  <div class="art-full-height">
    <ElCard class="flex flex-col flex-1 min-h-0 art-table-card" shadow="never">
      <!-- 提示警告 -->
      <ElAlert type="warning" :closable="false">
        仅支持上传由插件市场下载的zip压缩包进行安装，请您务必确认插件包文件来自官方渠道或经由官方认证的插件作者！
      </ElAlert>

      <!-- 工具栏 -->
      <div class="flex flex-wrap items-center my-2">
        <ElButton @click="getList" v-ripple>
          <template #icon>
            <ArtSvgIcon icon="ri:refresh-line" />
          </template>
        </ElButton>
        <ElButton @click="handleUpload" v-ripple>
          <template #icon>
            <ArtSvgIcon icon="ri:upload-line" />
          </template>
          上传插件包
        </ElButton>
        <ElButton type="danger" @click="handleTerminal" v-ripple>
          <template #icon>
            <ArtSvgIcon icon="ri:terminal-box-line" />
          </template>
        </ElButton>

        <div class="flex items-center gap-1 ml-auto">
          <div class="version-title">saiadmin版本</div>
          <div class="version-value">{{ version?.saiadmin_version?.describe }}</div>
          <div class="version-title">状态</div>
          <div
            class="version-value"
            :class="[
              version?.saiadmin_version?.notes === '正常' ? 'text-green-500' : 'text-red-500'
            ]"
          >
            {{ version?.saiadmin_version?.notes }}
          </div>
          <div class="version-title">saipackage安装器</div>
          <div class="version-value">{{ version?.saipackage_version?.describe }}</div>
          <div class="version-title">状态</div>
          <div
            class="version-value"
            :class="[
              version?.saipackage_version?.notes === '正常' ? 'text-green-500' : 'text-red-500'
            ]"
          >
            {{ version?.saipackage_version?.notes }}
          </div>
        </div>
      </div>

      <!-- Tab切换 -->
      <ElTabs v-model="activeTab" type="border-card">
        <!-- 本地安装 Tab -->
        <ElTabPane label="本地安装" name="local">
          <ArtTable
            :loading="loading"
            :data="installList"
            :columns="columns"
            :show-table-header="false"
          >
            <!-- 插件标识列 -->
            <template #app="{ row }">
              <ElLink :href="row.website" target="_blank" type="primary">{{ row.app }}</ElLink>
            </template>

            <!-- 状态列 -->
            <template #state="{ row }">
              <ElTag v-if="row.state === 0" type="danger">已卸载</ElTag>
              <ElTag v-else-if="row.state === 1" type="success">已安装</ElTag>
              <ElTag v-else-if="row.state === 2" type="primary">等待安装</ElTag>
              <ElTag v-else-if="row.state === 4" type="warning">等待安装依赖</ElTag>
            </template>

            <!-- 前端依赖列 -->
            <template #npm="{ row }">
              <ElLink
                v-if="row.npm_dependent_wait_install === 1"
                type="primary"
                @click="handleExecFront(row)"
              >
                <ArtSvgIcon icon="ri:download-line" class="mr-1" />点击安装
              </ElLink>
              <ElTag v-else-if="row.state === 2" type="info">-</ElTag>
              <ElTag v-else type="success">已安装</ElTag>
            </template>

            <!-- 后端依赖列 -->
            <template #composer="{ row }">
              <ElLink
                v-if="row.composer_dependent_wait_install === 1"
                type="primary"
                @click="handleExecBackend(row)"
              >
                <ArtSvgIcon icon="ri:download-line" class="mr-1" />点击安装
              </ElLink>
              <ElTag v-else-if="row.state === 2" type="info">-</ElTag>
              <ElTag v-else type="success">已安装</ElTag>
            </template>

            <!-- 操作列 -->
            <template #operation="{ row }">
              <ElSpace>
                <ElPopconfirm
                  title="确定要安装当前插件吗?"
                  @confirm="handleInstall(row)"
                  confirm-button-text="确定"
                  cancel-button-text="取消"
                >
                  <template #reference>
                    <ElLink type="warning">
                      <ArtSvgIcon icon="ri:apps-2-add-line" class="mr-1" />安装
                    </ElLink>
                  </template>
                </ElPopconfirm>
                <ElPopconfirm
                  title="确定要卸载当前插件吗?"
                  @confirm="handleUninstall(row)"
                  confirm-button-text="确定"
                  cancel-button-text="取消"
                >
                  <template #reference>
                    <ElLink type="danger">
                      <ArtSvgIcon icon="ri:delete-bin-5-line" class="mr-1" />卸载
                    </ElLink>
                  </template>
                </ElPopconfirm>
              </ElSpace>
            </template>
          </ArtTable>
        </ElTabPane>

        <!-- 在线商店 Tab -->
        <ElTabPane label="在线商店" name="online">
          <!-- 搜索栏 -->
          <div class="flex flex-wrap items-center gap-4 mb-4">
            <ElInput
              v-model="searchForm.keywords"
              placeholder="请输入关键词"
              clearable
              class="!w-48"
              @keyup.enter="fetchOnlineApps"
            >
              <template #prefix>
                <ArtSvgIcon icon="ri:search-line" />
              </template>
            </ElInput>
            <ElSelect v-model="searchForm.type" placeholder="类型" clearable class="!w-32">
              <ElOption label="全部" value="" />
              <ElOption label="插件" :value="1" />
              <ElOption label="系统" :value="2" />
              <ElOption label="组件" :value="3" />
              <ElOption label="项目" :value="4" />
            </ElSelect>
            <ElSelect v-model="searchForm.price" placeholder="价格" class="!w-32">
              <ElOption label="全部" value="all" />
              <ElOption label="免费" value="free" />
              <ElOption label="付费" value="paid" />
            </ElSelect>
            <ElButton type="primary" @click="fetchOnlineApps">搜索</ElButton>

            <!-- 商店账号 -->
            <div class="ml-auto flex items-center gap-2">
              <template v-if="storeUser">
                <ElAvatar :size="24">
                  <img v-if="storeUser.avatar" :src="storeUser.avatar" />
                  <ArtSvgIcon v-else icon="ri:user-line" />
                </ElAvatar>
                <span class="font-medium">{{ storeUser.nickname || storeUser.username }}</span>
                <ElButton size="small" @click="showPurchasedApps">已购应用</ElButton>
                <ElButton size="small" @click="handleLogout">退出</ElButton>
              </template>
              <template v-else>
                <ElButton size="small" @click="handleLogin">登录</ElButton>
                <ElButton size="small" @click="handleRegister">注册</ElButton>
                <span class="text-sm text-gray-400">来管理已购插件</span>
              </template>
            </div>
          </div>

          <!-- 应用网格 -->
          <div class="app-grid">
            <div
              v-for="item in onlineApps"
              :key="item.id"
              class="app-card"
              @click="showDetail(item)"
            >
              <div class="app-card-header">
                <img :src="item.logo" :alt="item.title" class="app-logo" />
                <div class="app-info">
                  <div class="app-title">{{ item.title }}</div>
                  <div class="app-version">v{{ item.version }}</div>
                </div>
                <div class="app-price" :class="{ free: item.price === '0.00' }">
                  {{ item.price === '0.00' ? '免费' : '¥' + item.price }}
                </div>
              </div>
              <div class="app-about">{{ item.about }}</div>
              <div class="app-footer">
                <div class="app-author">
                  <img
                    :src="item.avatar || 'https://via.placeholder.com/24'"
                    class="author-avatar"
                  />
                  <span>{{ item.username }}</span>
                </div>
                <div class="app-sales">
                  <ArtSvgIcon icon="ri:user-line" class="mr-1" />
                  {{ item.sales_num }} 销量
                </div>
              </div>
            </div>
          </div>

          <!-- 分页 -->
          <div class="flex justify-center mt-4">
            <ElPagination
              v-model:current-page="onlinePagination.current"
              v-model:page-size="onlinePagination.size"
              :total="onlinePagination.total"
              :page-sizes="[12, 24, 48]"
              layout="total, prev, pager, next, sizes"
              @size-change="fetchOnlineApps"
              @current-change="fetchOnlineApps"
            />
          </div>
        </ElTabPane>
      </ElTabs>
    </ElCard>

    <!-- 上传插件弹窗 -->
    <InstallForm ref="installFormRef" @success="getList" />

    <!-- 终端弹窗 -->
    <TerminalBox ref="terminalRef" @success="getList" />

    <!-- 详情抽屉 -->
    <ElDrawer v-model="detailVisible" :size="600" :with-header="true">
      <template #header>
        <div class="flex items-center gap-3">
          <img :src="currentApp?.logo" class="w-9 h-9 rounded-lg" />
          <div>
            <div class="text-lg font-semibold">{{ currentApp?.title }}</div>
            <div class="text-xs text-gray-400">
              v{{ currentApp?.version }} · {{ currentApp?.username }}
            </div>
          </div>
        </div>
      </template>
      <div class="detail-content">
        <div class="detail-price" :class="{ free: currentApp?.price === '0.00' }">
          {{ currentApp?.price === '0.00' ? '免费' : '¥' + currentApp?.price }}
        </div>
        <div class="detail-about">{{ currentApp?.about }}</div>

        <!-- 截图预览 -->
        <div v-if="currentApp?.screenshots?.length" class="mb-6">
          <div class="text-base font-semibold mb-3">截图预览</div>
          <ElSpace wrap :size="12">
            <ElImage
              v-for="(img, idx) in currentApp?.screenshots"
              :key="idx"
              :src="img"
              :preview-src-list="currentApp?.screenshots"
              :preview-teleported="true"
              fit="cover"
              class="w-36 h-24 rounded-lg cursor-pointer"
            />
          </ElSpace>
        </div>

        <!-- 详情描述 -->
        <div class="detail-desc">
          <div class="text-base font-semibold mb-3">详细介绍</div>
          <div class="desc-content" v-html="renderMarkdown(currentApp?.content)"></div>
        </div>

        <!-- 购买按钮 -->
        <div class="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700">
          <ElButton type="primary" size="large" class="w-full" @click="handleBuy">
            <template #icon>
              <ArtSvgIcon icon="ri:shopping-cart-line" />
            </template>
            前往购买
          </ElButton>
        </div>
      </div>
    </ElDrawer>

    <!-- 登录弹窗 -->
    <ElDialog v-model="loginVisible" title="登录应用商店" width="400" :close-on-click-modal="false">
      <ElForm :model="loginForm" @submit.prevent="submitLogin" label-position="top">
        <ElFormItem label="用户名/邮箱" required>
          <ElInput v-model="loginForm.username" placeholder="请输入用户名或邮箱" clearable>
            <template #prefix>
              <ArtSvgIcon icon="ri:user-line" />
            </template>
          </ElInput>
        </ElFormItem>
        <ElFormItem label="密码" required>
          <ElInput
            v-model="loginForm.password"
            type="password"
            placeholder="请输入密码"
            show-password
            clearable
          >
            <template #prefix>
              <ArtSvgIcon icon="ri:lock-line" />
            </template>
          </ElInput>
        </ElFormItem>
        <ElFormItem label="验证码" required>
          <div class="flex gap-2 w-full">
            <ElInput v-model="loginForm.code" placeholder="请输入验证码" clearable class="flex-1">
              <template #prefix>
                <ArtSvgIcon icon="ri:shield-check-line" />
              </template>
            </ElInput>
            <img
              :src="captchaImage"
              @click="getCaptcha"
              class="h-8 w-24 cursor-pointer rounded"
              title="点击刷新"
            />
          </div>
        </ElFormItem>
        <ElFormItem>
          <ElButton type="primary" native-type="submit" class="w-full" :loading="loginLoading">
            登录
          </ElButton>
        </ElFormItem>
        <div class="text-center text-sm text-gray-400">
          还没有账号？
          <ElLink type="primary" @click="handleRegister">立即注册</ElLink>
        </div>
      </ElForm>
    </ElDialog>

    <!-- 已购应用抽屉 -->
    <ElDrawer v-model="purchasedVisible" title="已购应用" :size="720">
      <div v-loading="purchasedLoading" class="purchased-list">
        <div v-for="app in purchasedApps" :key="app.id" class="purchased-card">
          <img :src="app.logo" class="purchased-logo" />
          <div class="purchased-info">
            <div class="purchased-title">{{ app.title }}</div>
            <div class="purchased-version">v{{ app.version }} · {{ app.developer }}</div>
            <div class="purchased-about">{{ app.about }}</div>
          </div>
          <div class="gap-2">
            <ElButton size="small" @click="viewDocs(app)">
              <template #icon>
                <ArtSvgIcon icon="ri:book-line" />
              </template>
              文档
            </ElButton>
            <ElButton type="primary" size="small" @click="showVersions(app)">
              <template #icon>
                <ArtSvgIcon icon="ri:download-line" />
              </template>
              下载
            </ElButton>
          </div>
        </div>
        <ElEmpty
          v-if="!purchasedLoading && purchasedApps.length === 0"
          description="暂无已购应用"
        />
      </div>
    </ElDrawer>

    <!-- 版本选择对话框 -->
    <ElDialog
      v-model="versionVisible"
      :title="'选择版本 - ' + (currentPurchasedApp?.title || '')"
      width="500"
    >
      <div v-loading="versionLoading" class="version-list">
        <div v-for="ver in versionList" :key="ver.id" class="version-item">
          <div>
            <div class="version-info-row">
              <span class="version-name">v{{ ver.version }}</span>
              <span class="version-date">{{ ver.create_time }}</span>
            </div>
            <div class="version-remark">{{ ver.remark }}</div>
          </div>
          <ElButton
            type="primary"
            size="small"
            :loading="downloadingId === ver.id"
            @click="downloadVersion(ver)"
          >
            下载安装
          </ElButton>
        </div>
        <ElEmpty v-if="!versionLoading && versionList.length === 0" description="暂无可用版本" />
      </div>
    </ElDialog>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, onMounted, watch } from 'vue'
  import { ElMessage } from 'element-plus'
  import type { ColumnOption } from '@/types'
  import saipackageApi, {
    type AppInfo,
    type VersionInfo,
    type StoreApp,
    type StoreUser,
    type PurchasedApp,
    type AppVersion
  } from '../api/index'
  import InstallForm from './install-box.vue'
  import TerminalBox from './terminal.vue'

  // ========== 基础状态 ==========
  const activeTab = ref('local')
  const version = ref<VersionInfo>({})
  const loading = ref(false)
  const installFormRef = ref()
  const terminalRef = ref()
  const installList = ref<AppInfo[]>([])

  // ========== 本地安装相关 ==========
  const handleUpload = () => {
    installFormRef.value?.open()
  }

  // 检查版本兼容性
  const checkVersionCompatibility = (support: string | undefined): boolean => {
    if (!support || !version.value?.saiadmin_version?.describe) {
      return false // 如果没有兼容性信息，默认不允许安装
    }

    const currentVersion = version.value.saiadmin_version.describe
    const currentMatch = currentVersion.match(/^(\d+)\./)

    if (!currentMatch) {
      return true
    }

    const currentMajor = currentMatch[1]
    // support 格式为 "5.x" 或 "5.x|6.x"，用 | 分隔多个支持的版本
    const supportVersions = support.split('|').map((v) => v.trim())

    // 检查当前版本是否匹配任意一个支持的版本
    return supportVersions.some((ver) => {
      const supportMatch = ver.match(/^(\d+)\.x$/i)
      return supportMatch && supportMatch[1] === currentMajor
    })
  }

  const handleInstall = async (record: AppInfo) => {
    // 检查
    if (version.value?.saipackage_version?.state === 'fail') {
      ElMessage.error('插件市场saipackage版本检测失败')
      return
    }

    // 检查版本兼容性
    if (!checkVersionCompatibility(record.support)) {
      ElMessage.error(
        `此插件仅支持 ${record.support} 版本框架，当前框架版本为 ${version.value?.saiadmin_version?.describe}，不兼容无法安装`
      )
      return
    }

    try {
      await saipackageApi.installApp({ appName: record.app })
      ElMessage.success('安装成功')
      getList()
      saipackageApi.reloadBackend()
    } catch {
      // Error already handled by http utility
    }
  }

  const handleUninstall = async (record: AppInfo) => {
    await saipackageApi.uninstallApp({ appName: record.app })
    ElMessage.success('卸载成功')
    getList()
  }

  const handleExecFront = (record: AppInfo) => {
    const extend = 'module-install:' + record.app
    terminalRef.value?.open()
    setTimeout(() => {
      terminalRef.value?.frontInstall(extend)
    }, 500)
  }

  const handleExecBackend = (record: AppInfo) => {
    const extend = 'module-install:' + record.app
    terminalRef.value?.open()
    setTimeout(() => {
      terminalRef.value?.backendInstall(extend)
    }, 500)
  }

  const handleTerminal = () => {
    terminalRef.value?.open()
  }

  const columns: ColumnOption[] = [
    { prop: 'app', label: '插件标识', width: 120, useSlot: true },
    { prop: 'title', label: '插件名称', width: 150 },
    { prop: 'about', label: '插件描述', showOverflowTooltip: true },
    { prop: 'author', label: '作者', width: 120 },
    { prop: 'version', label: '版本', width: 100 },
    { prop: 'support', label: '框架兼容', width: 120, align: 'center' },
    { prop: 'state', label: '插件状态', width: 100, useSlot: true },
    { prop: 'npm', label: '前端依赖', width: 100, useSlot: true },
    { prop: 'composer', label: '后端依赖', width: 100, useSlot: true },
    { prop: 'operation', label: '操作', width: 140, fixed: 'right', useSlot: true }
  ]

  const getList = async () => {
    loading.value = true
    try {
      const resp = await saipackageApi.getAppList()
      installList.value = resp?.data || []
      version.value = resp?.version || {}
    } catch {
      // Error already handled by http utility
    } finally {
      loading.value = false
    }
  }

  // ========== 在线商店相关 ==========
  const detailVisible = ref(false)
  const currentApp = ref<StoreApp | null>(null)
  const storeUser = ref<StoreUser | null>(null)
  const storeToken = ref(localStorage.getItem('storeToken') || '')
  const onlineApps = ref<StoreApp[]>([])
  const onlineLoading = ref(false)
  const onlinePagination = reactive({
    current: 1,
    size: 12,
    total: 0
  })

  // 登录相关
  const loginVisible = ref(false)
  const loginLoading = ref(false)
  const captchaImage = ref('')
  const captchaUuid = ref('')
  const loginForm = reactive({
    username: '',
    password: '',
    code: ''
  })

  // 搜索表单
  const searchForm = reactive({
    keywords: '',
    type: '' as string | number,
    price: 'all'
  })

  // 已购应用相关
  const purchasedVisible = ref(false)
  const purchasedLoading = ref(false)
  const purchasedApps = ref<PurchasedApp[]>([])
  const versionVisible = ref(false)
  const versionLoading = ref(false)
  const versionList = ref<AppVersion[]>([])
  const currentPurchasedApp = ref<PurchasedApp | null>(null)
  const downloadingId = ref<number | null>(null)

  const handleLogin = () => {
    loginVisible.value = true
    getCaptcha()
  }

  const handleRegister = () => {
    window.open('https://saas.saithink.top/register', '_blank')
  }

  const handleLogout = () => {
    storeUser.value = null
    storeToken.value = ''
    localStorage.removeItem('storeToken')
  }

  const getCaptcha = async () => {
    try {
      const response = await saipackageApi.getStoreCaptcha()
      captchaImage.value = response?.image || ''
      captchaUuid.value = response?.uuid || ''
    } catch {
      // Error already handled by http utility
    }
  }

  const submitLogin = async () => {
    if (!loginForm.username || !loginForm.password || !loginForm.code) {
      ElMessage.warning('请填写完整信息')
      return
    }

    loginLoading.value = true
    try {
      const response = await saipackageApi.storeLogin({
        username: loginForm.username,
        password: loginForm.password,
        code: loginForm.code,
        uuid: captchaUuid.value
      })

      storeToken.value = response?.access_token || ''
      localStorage.setItem('storeToken', response?.access_token || '')
      loginVisible.value = false
      loginForm.username = ''
      loginForm.password = ''
      loginForm.code = ''
      await fetchStoreUser()
      ElMessage.success('登录成功')
    } catch {
      getCaptcha()
      // Error already handled by http utility
    } finally {
      loginLoading.value = false
    }
  }

  const fetchStoreUser = async () => {
    if (!storeToken.value) return

    try {
      const response = await saipackageApi.getStoreUserInfo(storeToken.value)
      storeUser.value = response || null
    } catch {
      handleLogout()
    }
  }

  const fetchOnlineApps = async () => {
    onlineLoading.value = true
    try {
      const response = await saipackageApi.getOnlineAppList({
        page: onlinePagination.current,
        limit: onlinePagination.size,
        price: searchForm.price,
        type: searchForm.type,
        keywords: searchForm.keywords
      })

      onlineApps.value = response?.data || []
      onlinePagination.total = response?.total || 0
    } catch {
      // Error already handled by http utility
    } finally {
      onlineLoading.value = false
    }
  }

  const showDetail = (item: StoreApp) => {
    currentApp.value = item
    detailVisible.value = true
  }

  const renderMarkdown = (content?: string) => {
    if (!content) return ''
    return content
      .replace(/^### (.+)$/gm, '<h3>$1</h3>')
      .replace(/^## (.+)$/gm, '<h2>$1</h2>')
      .replace(/^# (.+)$/gm, '<h1>$1</h1>')
      .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
      .replace(/\*(.+?)\*/g, '<em>$1</em>')
      .replace(/`(.+?)`/g, '<code>$1</code>')
      .replace(/^- (.+)$/gm, '<li>$1</li>')
      .replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>')
      .replace(/\n/g, '<br/>')
      .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>')
  }

  const handleBuy = () => {
    window.open('https://saas.saithink.top/store', '_blank')
  }

  const showPurchasedApps = async () => {
    purchasedVisible.value = true
    purchasedLoading.value = true

    try {
      const response = await saipackageApi.getPurchasedApps(storeToken.value)
      purchasedApps.value = response || []
    } catch {
      // Error already handled by http utility
    }
    purchasedLoading.value = false
  }

  const viewDocs = (app: PurchasedApp) => {
    window.open(`https://saas.saithink.top/store/docs-${app.app_id}`, '_blank')
  }

  const showVersions = async (app: PurchasedApp) => {
    currentPurchasedApp.value = app
    versionVisible.value = true
    versionLoading.value = true

    try {
      const response = await saipackageApi.getAppVersions(storeToken.value, app.app_id)
      versionList.value = response || []
    } catch {
      // Error already handled by http utility
    }
    versionLoading.value = false
  }

  const downloadVersion = async (ver: AppVersion) => {
    downloadingId.value = ver.id

    try {
      await saipackageApi.downloadApp({
        token: storeToken.value,
        id: ver.id
      })

      ElMessage.success('下载成功，即将刷新插件列表...')
      versionVisible.value = false
      purchasedVisible.value = false
      activeTab.value = 'local'
      getList()
    } catch {
      // Error already handled by http utility
    }
    downloadingId.value = null
  }

  // 监听 tab 切换
  watch(activeTab, (val) => {
    if (val === 'online') {
      fetchOnlineApps()
      fetchStoreUser()
    }
  })

  onMounted(() => {
    getList()
  })
</script>

<style lang="scss" scoped>
  .version-title {
    padding: 5px 10px;
    background: var(--el-fill-color-light);
    border: 1px solid var(--el-border-color);
    font-size: 12px;
  }

  .version-value {
    padding: 5px 10px;
    border: 1px solid var(--el-border-color);
    font-size: 12px;
  }

  .app-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 16px;
    max-height: calc(100vh - 380px);
    overflow-y: auto;
  }

  .app-card {
    background: var(--el-bg-color);
    border-radius: 8px;
    padding: 16px;
    cursor: pointer;
    transition: all 0.3s ease;
    border: 1px solid var(--el-border-color);

    &:hover {
      box-shadow: var(--el-box-shadow-light);
      transform: translateY(-2px);
    }
  }

  .app-card-header {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
  }

  .app-logo {
    width: 48px;
    height: 48px;
    border-radius: 8px;
    object-fit: cover;
  }

  .app-info {
    flex: 1;
  }

  .app-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--el-text-color-primary);
  }

  .app-version {
    font-size: 12px;
    color: var(--el-text-color-secondary);
  }

  .app-price {
    font-size: 16px;
    font-weight: 600;
    color: var(--el-color-danger);

    &.free {
      color: var(--el-color-success);
    }
  }

  .app-about {
    font-size: 13px;
    color: var(--el-text-color-regular);
    line-height: 1.5;
    margin-bottom: 12px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .app-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 12px;
    color: var(--el-text-color-secondary);
  }

  .app-author {
    display: flex;
    align-items: center;
    gap: 6px;
  }

  .author-avatar {
    width: 20px;
    height: 20px;
    border-radius: 50%;
  }

  .app-sales {
    display: flex;
    align-items: center;
  }

  .detail-content {
    padding: 16px 0;
  }

  .detail-price {
    font-size: 24px;
    font-weight: 600;
    color: var(--el-color-danger);
    margin-bottom: 16px;

    &.free {
      color: var(--el-color-success);
    }
  }

  .detail-about {
    font-size: 14px;
    color: var(--el-text-color-regular);
    line-height: 1.6;
    margin-bottom: 24px;
  }

  .desc-content {
    font-size: 14px;
    color: var(--el-text-color-regular);
    line-height: 1.8;

    :deep(code) {
      background: var(--el-fill-color);
      padding: 2px 6px;
      border-radius: 4px;
      font-size: 13px;
    }

    :deep(a) {
      color: var(--el-color-primary);
    }
  }

  .purchased-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  .purchased-card {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px;
    background: var(--el-bg-color);
    border-radius: 8px;
    border: 1px solid var(--el-border-color);
  }

  .purchased-logo {
    width: 56px;
    height: 56px;
    border-radius: 8px;
    object-fit: cover;
  }

  .purchased-info {
    flex: 1;
    min-width: 0;
  }

  .purchased-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--el-text-color-primary);
    margin-bottom: 4px;
  }

  .purchased-version {
    font-size: 12px;
    color: var(--el-text-color-secondary);
    margin-bottom: 6px;
  }

  .purchased-about {
    font-size: 13px;
    color: var(--el-text-color-regular);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .version-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  .version-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px;
    background: var(--el-fill-color-light);
    border-radius: 6px;
  }

  .version-info-row {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .version-name {
    font-weight: 600;
    color: var(--el-text-color-primary);
  }

  .version-date {
    font-size: 12px;
    color: var(--el-text-color-secondary);
  }

  .version-remark {
    flex: 1;
    font-size: 13px;
    color: var(--el-text-color-regular);
  }
</style>
