﻿<template>
  <main class="max-w-7xl mx-auto px-4 py-8">
    <BaseCard v-if="!isLoggedIn" class="max-w-md mx-auto mt-20" padding="lg">
      <h1 class="text-3xl font-bold gradient-text mb-4 text-center">DreamWeaver 控制台</h1>
      <p class="text-sm text-gray-500 mb-8 text-center">请登录以管理 AI 计算引擎与策略</p>
      <form @submit.prevent="login" class="space-y-6">
        <BaseInput v-model="loginForm.username" label="管理员账号" required placeholder="admin" />
        <BaseInput v-model="loginForm.password" label="密钥密码" type="password" required />
        <div class="flex items-center justify-between mt-6">
          <span v-if="loginError" class="text-sm text-red-500 font-medium">{{ loginError }}</span>
          <BaseButton type="submit" class="w-full">进入控制台</BaseButton>
        </div>
      </form>
    </BaseCard>

    <div v-else class="space-y-8">
      <!-- Header -->
      <header class="flex flex-col md:flex-row md:items-center justify-between gap-4 bg-white p-6 rounded-2xl shadow-sm border border-gray-100">
        <div>
          <h1 class="text-3xl font-bold gradient-text">引擎调度中心</h1>
          <p class="text-sm text-gray-500 mt-1">Provider Orchestration & Strategy</p>
        </div>
        <div class="flex items-center gap-3">
          <div class="bg-blue-50 text-blue-700 px-3 py-1 rounded-full text-xs font-medium flex items-center gap-1">
            <span class="w-2 h-2 rounded-full bg-blue-500 animate-pulse"></span>
            系统运行中
          </div>
          <BaseButton variant="ghost" @click="logout" size="sm">退出</BaseButton>
        </div>
      </header>

      <BaseCard padding="lg">
        <div class="flex flex-col gap-5 xl:flex-row xl:items-start xl:justify-between">
          <div class="max-w-2xl">
            <div class="flex flex-wrap items-center gap-3">
              <h2 class="text-xl font-bold text-gray-900">当前环境 Provider 运营摘要</h2>
              <span class="rounded-full bg-emerald-50 px-3 py-1 text-xs font-medium text-emerald-700">
                跨用户 / 当前环境
              </span>
            </div>
            <p class="mt-2 text-sm leading-6 text-gray-500">
              这里展示的是当前部署环境内所有生成任务留下的 Provider 调用轨迹，便于运营和排障。
              跨环境对比仍需要后续独立汇聚层。
            </p>
            <div class="mt-4 flex flex-wrap gap-2">
              <button
                type="button"
                class="rounded-lg border px-3 py-1.5 text-sm transition-colors"
                :class="analyticsWindow === '7' ? 'border-gray-900 bg-gray-900 text-white' : 'border-gray-200 bg-white text-gray-600 hover:border-gray-400'"
                @click="analyticsWindow = '7'"
              >
                最近 7 天
              </button>
              <button
                type="button"
                class="rounded-lg border px-3 py-1.5 text-sm transition-colors"
                :class="analyticsWindow === '30' ? 'border-gray-900 bg-gray-900 text-white' : 'border-gray-200 bg-white text-gray-600 hover:border-gray-400'"
                @click="analyticsWindow = '30'"
              >
                最近 30 天
              </button>
              <button
                type="button"
                class="rounded-lg border px-3 py-1.5 text-sm transition-colors"
                :class="analyticsWindow === 'all' ? 'border-gray-900 bg-gray-900 text-white' : 'border-gray-200 bg-white text-gray-600 hover:border-gray-400'"
                @click="analyticsWindow = 'all'"
              >
                全部
              </button>
            </div>
            <div class="mt-3 flex flex-wrap gap-2">
              <button
                type="button"
                class="rounded-lg border px-3 py-1.5 text-sm transition-colors"
                :class="analyticsCapability === 'all' ? 'border-indigo-600 bg-indigo-600 text-white' : 'border-gray-200 bg-white text-gray-600 hover:border-gray-400'"
                @click="analyticsCapability = 'all'"
              >
                全部能力
              </button>
              <button
                type="button"
                class="rounded-lg border px-3 py-1.5 text-sm transition-colors"
                :class="analyticsCapability === 'text' ? 'border-indigo-600 bg-indigo-600 text-white' : 'border-gray-200 bg-white text-gray-600 hover:border-gray-400'"
                @click="analyticsCapability = 'text'"
              >
                文本
              </button>
              <button
                type="button"
                class="rounded-lg border px-3 py-1.5 text-sm transition-colors"
                :class="analyticsCapability === 'image' ? 'border-indigo-600 bg-indigo-600 text-white' : 'border-gray-200 bg-white text-gray-600 hover:border-gray-400'"
                @click="analyticsCapability = 'image'"
              >
                图片
              </button>
              <button
                type="button"
                class="rounded-lg border px-3 py-1.5 text-sm transition-colors"
                :class="analyticsCapability === 'tts' ? 'border-indigo-600 bg-indigo-600 text-white' : 'border-gray-200 bg-white text-gray-600 hover:border-gray-400'"
                @click="analyticsCapability = 'tts'"
              >
                语音
              </button>
              <button
                type="button"
                class="rounded-lg border px-3 py-1.5 text-sm transition-colors"
                :class="analyticsCapability === 'storybook' ? 'border-indigo-600 bg-indigo-600 text-white' : 'border-gray-200 bg-white text-gray-600 hover:border-gray-400'"
                @click="analyticsCapability = 'storybook'"
              >
                绘本
              </button>
            </div>
          </div>

          <div class="grid grid-cols-2 gap-3 sm:grid-cols-4 xl:min-w-[420px]">
            <div class="rounded-xl border border-gray-100 bg-gray-50 px-4 py-3">
              <div class="text-xs text-gray-500">活跃用户</div>
              <div class="mt-1 text-2xl font-semibold text-gray-900">
                {{ analytics?.user_count ?? 0 }}
              </div>
            </div>
            <div class="rounded-xl border border-gray-100 bg-gray-50 px-4 py-3">
              <div class="text-xs text-gray-500">总调用</div>
              <div class="mt-1 text-2xl font-semibold text-gray-900">
                {{ analytics?.total_calls ?? 0 }}
              </div>
            </div>
            <div class="rounded-xl border border-gray-100 bg-gray-50 px-4 py-3">
              <div class="text-xs text-gray-500">成功率</div>
              <div class="mt-1 text-2xl font-semibold text-gray-900">
                {{ providerSuccessRate ?? '--' }}<span v-if="providerSuccessRate !== null">%</span>
              </div>
            </div>
            <div class="rounded-xl border border-gray-100 bg-gray-50 px-4 py-3">
              <div class="text-xs text-gray-500">预估成本</div>
              <div class="mt-1 text-2xl font-semibold text-gray-900">
                {{ formatCost(analytics?.estimated_cost_usd) }}
              </div>
            </div>
          </div>
        </div>

        <div v-if="analyticsLoading" class="mt-5 rounded-xl border border-dashed border-gray-200 px-4 py-6 text-sm text-gray-500">
          正在更新运营摘要...
        </div>
        <div v-else-if="analyticsError" class="mt-5 rounded-xl border border-rose-100 bg-rose-50 px-4 py-4 text-sm text-rose-600">
          {{ analyticsError }}
        </div>
        <template v-else-if="analytics">
          <div class="mt-6 grid grid-cols-2 gap-3 lg:grid-cols-4">
            <div class="rounded-xl border border-gray-100 bg-white px-4 py-3">
              <div class="text-xs text-gray-500">覆盖故事</div>
              <div class="mt-1 text-lg font-semibold text-gray-900">{{ analytics.story_count }}</div>
            </div>
            <div class="rounded-xl border border-gray-100 bg-white px-4 py-3">
              <div class="text-xs text-gray-500">覆盖任务</div>
              <div class="mt-1 text-lg font-semibold text-gray-900">{{ analytics.job_count }}</div>
            </div>
            <div class="rounded-xl border border-gray-100 bg-white px-4 py-3">
              <div class="text-xs text-gray-500">平均耗时</div>
              <div class="mt-1 text-lg font-semibold text-gray-900">{{ formatLatency(analytics.avg_latency_ms) }}</div>
            </div>
            <div class="rounded-xl border border-gray-100 bg-white px-4 py-3">
              <div class="text-xs text-gray-500">配置中 Provider</div>
              <div class="mt-1 text-lg font-semibold text-gray-900">{{ enabledProviderCount }}/{{ providers.length }}</div>
            </div>
          </div>

          <div class="mt-6 grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]">
            <div class="rounded-2xl border border-gray-100 bg-white">
              <div class="flex items-center justify-between border-b border-gray-100 px-5 py-4">
                <div>
                  <h3 class="font-semibold text-gray-900">Provider 调用明细</h3>
                  <p class="mt-1 text-xs text-gray-500">按能力和 adapter 聚合的当前环境视图</p>
                </div>
                <span class="text-xs text-gray-400">{{ analyticsProviderRows.length }} 个组合</span>
              </div>
              <div class="divide-y divide-gray-100">
                <div
                  v-for="row in analyticsProviderRows"
                  :key="`${row.capability}:${row.adapter}`"
                  class="grid grid-cols-1 gap-3 px-5 py-4 md:grid-cols-[minmax(0,1.2fr)_repeat(4,minmax(0,0.8fr))]"
                >
                  <div>
                    <div class="flex items-center gap-2">
                      <span class="rounded-full bg-gray-100 px-2 py-0.5 text-[11px] font-medium text-gray-600">
                        {{ formatCapability(row.capability) }}
                      </span>
                      <span class="font-medium text-gray-900">{{ row.adapter }}</span>
                    </div>
                  </div>
                  <div>
                    <div class="text-[11px] text-gray-400">调用</div>
                    <div class="mt-1 text-sm font-medium text-gray-900">{{ row.call_count }}</div>
                  </div>
                  <div>
                    <div class="text-[11px] text-gray-400">成功率</div>
                    <div class="mt-1 text-sm font-medium text-gray-900">
                      {{ getSuccessRate(row.success_count, row.call_count) ?? '--' }}<span v-if="getSuccessRate(row.success_count, row.call_count) !== null">%</span>
                    </div>
                  </div>
                  <div>
                    <div class="text-[11px] text-gray-400">耗时</div>
                    <div class="mt-1 text-sm font-medium text-gray-900">{{ formatLatency(row.avg_latency_ms) }}</div>
                  </div>
                  <div>
                    <div class="text-[11px] text-gray-400">成本</div>
                    <div class="mt-1 text-sm font-medium text-gray-900">{{ formatCost(row.estimated_cost_usd) }}</div>
                  </div>
                </div>
                <div v-if="analyticsProviderRows.length === 0" class="px-5 py-8 text-sm text-gray-500">
                  当前筛选条件下还没有 Provider 调用样本。
                </div>
              </div>
            </div>

            <div class="space-y-6">
              <div class="rounded-2xl border border-gray-100 bg-white">
                <div class="border-b border-gray-100 px-5 py-4">
                  <h3 class="font-semibold text-gray-900">跨用户分布</h3>
                  <p class="mt-1 text-xs text-gray-500">按调用量排序，帮助快速识别主要使用者</p>
                </div>
                <div class="divide-y divide-gray-100">
                  <div
                    v-for="row in analyticsUserRows.slice(0, 5)"
                    :key="row.user_id"
                    class="px-5 py-4"
                  >
                    <div class="flex items-start justify-between gap-3">
                      <div>
                        <div class="text-sm font-medium text-gray-900">{{ row.user_id }}</div>
                        <div class="mt-1 text-xs text-gray-500">
                          {{ row.story_count }} 个故事 · {{ row.job_count }} 个任务
                        </div>
                      </div>
                      <div class="text-right">
                        <div class="text-sm font-semibold text-gray-900">{{ row.call_count }} 次</div>
                        <div class="mt-1 text-xs text-gray-500">{{ formatCost(row.estimated_cost_usd) }}</div>
                      </div>
                    </div>
                  </div>
                  <div v-if="analyticsUserRows.length === 0" class="px-5 py-8 text-sm text-gray-500">
                    当前还没有跨用户样本。
                  </div>
                </div>
              </div>

              <div class="rounded-2xl border border-gray-100 bg-white">
                <div class="border-b border-gray-100 px-5 py-4">
                  <h3 class="font-semibold text-gray-900">最近失败原因</h3>
                  <p class="mt-1 text-xs text-gray-500">先看最常见原因，再决定是否调整路由或优先级</p>
                </div>
                <div class="divide-y divide-gray-100">
                  <div
                    v-for="reason in analytics.failure_reasons.slice(0, 5)"
                    :key="reason.reason"
                    class="flex items-center justify-between gap-3 px-5 py-4"
                  >
                    <span class="text-sm text-gray-700">{{ reason.reason }}</span>
                    <span class="rounded-full bg-rose-50 px-2.5 py-1 text-xs font-medium text-rose-600">
                      {{ reason.count }} 次
                    </span>
                  </div>
                  <div v-if="analytics.failure_reasons.length === 0" class="px-5 py-8 text-sm text-gray-500">
                    当前窗口内还没有失败调用。
                  </div>
                </div>
              </div>
            </div>
          </div>
        </template>
      </BaseCard>

      <!-- Main Content Grid -->
      <div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
        
        <!-- Left: Status & Defaults -->
        <div class="lg:col-span-1 space-y-6">
          <BaseCard padding="md" title="出厂默认策略 (.env)">
             <div class="space-y-4">
               <div v-for="(providers, type) in defaults" :key="type" class="p-3 bg-gray-50 rounded-lg border border-gray-100">
                 <div class="flex items-center gap-2 mb-2">
                   <span class="text-xs font-bold uppercase tracking-wider text-gray-400">{{ type }}</span>
                 </div>
                 <div class="flex flex-wrap gap-2">
                   <button 
                     v-for="p in providers" 
                     :key="p" 
                     @click="cloneDefault(type, p)"
                     class="px-2 py-1 text-xs bg-white border border-gray-200 rounded text-gray-600 font-mono hover:border-indigo-300 hover:text-indigo-600 hover:shadow-sm transition-all cursor-pointer"
                     title="点击基于此默认配置创建"
                   >
                     {{ p }}
                   </button>
                 </div>
               </div>
               <p class="text-xs text-gray-400 mt-2 px-1">
                 * 当数据库中未配置或全部禁用时，系统将回退到上述出厂设置。
               </p>
             </div>
          </BaseCard>

          <BaseCard padding="md" title="可用驱动 (Adapters)">
            <div class="flex flex-wrap gap-2">
              <span v-for="adapter in availableAdapters" :key="adapter" 
                class="px-2 py-1 text-xs bg-indigo-50 text-indigo-700 rounded-full border border-indigo-100">
                {{ adapter.split(':')[1] }} <span class="opacity-50 text-[10px]">({{ adapter.split(':')[0] }})</span>
              </span>
            </div>
          </BaseCard>
        </div>

        <!-- Right: Active Manager -->
        <div class="lg:col-span-3 space-y-6">
          
          <!-- Tabs -->
          <div class="flex space-x-1 bg-gray-100 p-1 rounded-xl w-fit">
            <button
              v-for="tab in ['text', 'image', 'tts', 'storybook']"
              :key="tab"
              @click="activeTab = tab"
              class="px-6 py-2 rounded-lg text-sm font-medium transition-all duration-200"
              :class="activeTab === tab ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-500 hover:text-gray-700'"
            >
              {{ tab.toUpperCase() }}
            </button>
          </div>

          <!-- Provider Cards -->
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
             <!-- Add New Card -->
             <button @click="openCreateModal" class="flex flex-col items-center justify-center p-8 border-2 border-dashed border-gray-200 rounded-2xl hover:border-indigo-300 hover:bg-indigo-50 transition-all group min-h-[200px]">
               <div class="w-12 h-12 rounded-full bg-white shadow-sm flex items-center justify-center mb-3 group-hover:scale-110 transition-transform">
                 <svg class="w-6 h-6 text-indigo-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg>
               </div>
               <span class="text-sm font-medium text-gray-600 group-hover:text-indigo-600">添加新的 {{ activeTab }} 引擎</span>
             </button>

             <!-- Existing Cards -->
             <div v-for="p in filteredProviders" :key="p.id" 
               class="relative p-6 bg-white rounded-2xl border transition-all duration-200 group hover:shadow-lg"
               :class="p.enabled ? 'border-gray-200' : 'border-gray-100 opacity-75 bg-gray-50'"
             >
                <!-- Enabled Toggle -->
                <div class="absolute top-4 right-4 z-10">
                   <label class="relative inline-flex items-center cursor-pointer">
                    <input type="checkbox" :checked="p.enabled" @change="toggleEnabled(p)" class="sr-only peer">
                    <div class="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-indigo-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-indigo-600"></div>
                  </label>
                </div>

                <div class="flex items-start justify-between mb-4">
                  <div>
                    <h3 class="font-bold text-lg text-gray-900">{{ p.name }}</h3>
                    <div class="flex items-center gap-2 mt-1">
                      <span class="px-2 py-0.5 rounded text-xs font-mono bg-gray-100 text-gray-600 border border-gray-200">
                        {{ p.adapter }}
                      </span>
                      <span v-if="p.model" class="px-2 py-0.5 rounded text-xs bg-blue-50 text-blue-600 border border-blue-100 truncate max-w-[120px]">
                        {{ p.model }}
                      </span>
                    </div>
                  </div>
                </div>
                
                <div class="space-y-2 text-sm text-gray-500 mb-6">
                  <div class="flex justify-between">
                    <span>Priority:</span>
                    <span class="font-medium text-gray-700">{{ p.priority }}</span>
                  </div>
                  <div class="flex justify-between">
                    <span>API Key:</span>
                    <span :class="p.has_api_key ? 'text-green-600' : 'text-yellow-600'">
                      {{ p.has_api_key ? '● Configured' : '○ Not Set (Env?)' }}
                    </span>
                  </div>
                </div>

                <div class="flex items-center gap-2 pt-4 border-t border-gray-100 opacity-0 group-hover:opacity-100 transition-opacity">
                  <BaseButton size="sm" variant="secondary" class="flex-1" @click="edit(p)">配置</BaseButton>
                  <BaseButton size="sm" variant="ghost" class="text-red-500 hover:bg-red-50" @click="remove(p)">删除</BaseButton>
                </div>
             </div>
          </div>
        </div>
      </div>
    
    </div>

    <!-- Edit/Create Modal -->
    <div v-if="editing" class="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm" @click.self="reset">
      <BaseCard class="w-full max-w-2xl max-h-[90vh] overflow-y-auto" padding="lg" @click.stop>
        <div class="flex justify-between items-center mb-6">
          <h2 class="text-xl font-bold gradient-text">{{ form.id ? '编辑引擎配置' : '添加新引擎' }}</h2>
          <button @click="reset" class="text-gray-400 hover:text-gray-600">
            <svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>
          </button>
        </div>
        
        <form @submit.prevent="submit" class="grid grid-cols-1 md:grid-cols-2 gap-6">
          <BaseInput v-model="form.name" label="名称 (显示名)" placeholder="如: Pro GPT-4" required />
          
          <BaseSelect
            v-model="form.adapter"
            label="驱动程序 (Adapter)"
            :options="adapterOptions"
            required
            description="选择底层的 API 驱动协议"
          />

          <BaseInput v-model="form.model" label="模型名称 (Model)" placeholder="如: gpt-4o, minimax-v2" description="具体调用的模型ID" />
          
          <BaseInput v-model.number="form.priority" label="优先级 (0-100)" type="number" description="数字越大越优先" />
          
          <div class="md:col-span-2 p-4 bg-gray-50 rounded-xl border border-gray-100 space-y-4">
             <h3 class="text-sm font-bold text-gray-700">密钥与连接</h3>
             <BaseInput v-model="form.api_key" label="API Key" type="password" placeholder="留空则使用 .env 配置" :required="!form.id && !form.config_ref" />
             <BaseInput v-model="form.api_base" label="API Endpoint / Group ID" placeholder="https://... 或 Group ID" />
             <BaseInput v-model="form.config_ref" label="Fallback Env Var" placeholder="如: OPENAI_API_KEY (高级)" />
          </div>

          <!-- MiniMax Specific Config -->
          <div v-if="form.adapter === 'minimax'" class="md:col-span-2 p-4 bg-indigo-50 rounded-xl border border-indigo-100 space-y-4">
             <h3 class="text-sm font-bold text-indigo-700">MiniMax 语音参数</h3>
             <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <BaseInput v-model="form.config_json.voice_id" label="音色 ID (Voice ID)" placeholder="male-qn-qingse" />
                <BaseInput v-model="form.config_json.emotion" label="情感 (Emotion)" placeholder="happy / sad / angry" />
                
                <div class="space-y-2">
                   <div class="flex justify-between">
                     <label class="text-xs font-semibold text-gray-600">语速 (Speed)</label>
                     <span class="text-xs text-indigo-600 font-mono">{{ form.config_json.speed || 1.0 }}x</span>
                   </div>
                   <input type="range" v-model.number="form.config_json.speed" min="0.5" max="2.0" step="0.1" class="w-full accent-indigo-600" />
                </div>

                <div class="space-y-2">
                   <div class="flex justify-between">
                     <label class="text-xs font-semibold text-gray-600">音量 (Volume)</label>
                     <span class="text-xs text-indigo-600 font-mono">{{ form.config_json.vol || 1.0 }}</span>
                   </div>
                   <input type="range" v-model.number="form.config_json.vol" min="0.1" max="5.0" step="0.1" class="w-full accent-indigo-600" />
                </div>
                
                 <div class="space-y-2">
                   <div class="flex justify-between">
                     <label class="text-xs font-semibold text-gray-600">音高 (Pitch)</label>
                     <span class="text-xs text-indigo-600 font-mono">{{ form.config_json.pitch || 0 }}</span>
                   </div>
                   <input type="range" v-model.number="form.config_json.pitch" min="-12" max="12" step="1" class="w-full accent-indigo-600" />
                </div>
             </div>
          </div>

          <!-- CQTAI Specific Config -->
          <div v-if="form.adapter === 'cqtai'" class="md:col-span-2 p-4 bg-purple-50 rounded-xl border border-purple-100 space-y-4">
             <h3 class="text-sm font-bold text-purple-700">CQTAI 画图参数</h3>
             <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <BaseSelect
                  v-model="form.config_json.aspect_ratio"
                  label="画面比例 (Aspect Ratio)"
                  :options="[
                    { value: '1:1', label: '1:1 (正方形)' },
                    { value: '16:9', label: '16:9 (横屏)' },
                    { value: '9:16', label: '9:16 (竖屏)' },
                    { value: '4:3', label: '4:3 (传统)' },
                    { value: '3:4', label: '3:4 (海报)' }
                  ]"
                  placeholder="默认 1:1"
                />
                
                <BaseSelect
                  v-model="form.config_json.resolution"
                  label="分辨率 (Resolution)"
                  :options="[
                    { value: '1K', label: '1K (标准)' },
                    { value: '2K', label: '2K (高清)' },
                    { value: '4K', label: '4K (超清)' }
                  ]"
                  placeholder="默认 1K"
                />
             </div>
          </div>

          <!-- Antigravity Specific Config -->
          <div v-if="form.adapter === 'antigravity'" class="md:col-span-2 p-4 bg-emerald-50 rounded-xl border border-emerald-100 space-y-4">
             <h3 class="text-sm font-bold text-emerald-700">Antigravity 画图参数 (OpenAI Compatible)</h3>
             <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <BaseSelect
                  v-model="form.config_json.size"
                  label="图像尺寸 (Size)"
                  :options="[
                    { value: '1024x1024', label: '1024x1024 (1:1 正方形)' },
                    { value: '1280x720', label: '1280x720 (16:9 横屏)' },
                    { value: '720x1280', label: '720x1280 (9:16 竖屏)' },
                    { value: '1216x896', label: '1216x896 (4:3 传统)' }
                  ]"
                  placeholder="默认 1024x1024"
                />
                
                <div class="flex items-center">
                  <p class="text-xs text-emerald-600">
                    💡 使用 Gemini 3 Pro Image 模型，通过 OpenAI 兼容接口生成图像
                  </p>
                </div>
             </div>
          </div>

          <div class="md:col-span-2 flex justify-end gap-3 pt-4 border-t border-gray-100">
            <BaseButton variant="secondary" type="button" @click="reset">取消</BaseButton>
            <BaseButton type="submit">{{ form.id ? '保存变更' : '立即创建' }}</BaseButton>
          </div>
        </form>
      </BaseCard>
    </div>
  </main>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import BaseButton from '../components/ui/BaseButton.vue'
import BaseCard from '../components/ui/BaseCard.vue'
import BaseInput from '../components/ui/BaseInput.vue'
import BaseSelect from '../components/ui/BaseSelect.vue'

// Types
type Provider = {
  id: string
  name: string
  type: string
  adapter: string
  model?: string
  api_base?: string
  has_api_key?: boolean
  priority: number
  enabled: boolean
  config_ref?: string
  weight?: number
  timeout_ms?: number
  max_retries?: number
  config_json: Record<string, any>
}

type ProviderAnalyticsBucket = {
  capability: string
  adapter: string
  call_count: number
  success_count: number
  failure_count: number
  avg_latency_ms: number | null
  estimated_cost_usd: number
}

type ProviderAnalyticsUserBucket = {
  user_id: string
  call_count: number
  success_count: number
  failure_count: number
  job_count: number
  story_count: number
  estimated_cost_usd: number
}

type ProviderAnalyticsResponse = {
  scope: string
  window_days: number | null
  capability: string | null
  total_calls: number
  successful_calls: number
  failed_calls: number
  avg_latency_ms: number | null
  estimated_cost_usd: number
  user_count: number
  job_count: number
  story_count: number
  by_provider: ProviderAnalyticsBucket[]
  by_user: ProviderAnalyticsUserBucket[]
  failure_reasons: Array<{
    reason: string
    count: number
  }>
}

// State
const loginForm = ref({ username: '', password: '' })
const loginError = ref('')
const isLoggedIn = ref(!!sessionStorage.getItem('admin_auth'))
const activeTab = ref('text')
const providers = ref<Provider[]>([])
const defaults = ref<Record<string, string[]>>({})
const availableAdapters = ref<string[]>([])
const analytics = ref<ProviderAnalyticsResponse | null>(null)
const analyticsLoading = ref(false)
const analyticsError = ref('')
const analyticsWindow = ref<'7' | '30' | 'all'>('30')
const analyticsCapability = ref<'all' | 'text' | 'image' | 'tts' | 'storybook'>('all')
const editing = ref(false)
const form = ref<Partial<Provider> & { api_key?: string; config_json: Record<string, any> }>({
  type: 'text',
  priority: 10,
  enabled: true,
  config_json: {}
})

const apiBase = import.meta.env.VITE_API_BASE || ''

function getAuthHeader(): string {
  return sessionStorage.getItem('admin_auth') || ''
}

function buildAnalyticsPath() {
  const params = new URLSearchParams()
  if (analyticsWindow.value !== 'all') {
    params.set('days', analyticsWindow.value)
  }
  if (analyticsCapability.value !== 'all') {
    params.set('capability', analyticsCapability.value)
  }
  const query = params.toString()
  return `${apiBase}/admin/providers/analytics${query ? `?${query}` : ''}`
}

function formatLatency(value?: number | null) {
  return typeof value === 'number' ? `${Math.round(value)}ms` : '暂无'
}

function formatCost(value?: number | null) {
  return typeof value === 'number' ? `$${value.toFixed(4)}` : '$0.0000'
}

function formatCapability(value: string) {
  switch (value) {
    case 'text':
      return '文本'
    case 'image':
      return '图片'
    case 'tts':
      return '语音'
    case 'storybook':
      return '绘本'
    default:
      return value
  }
}

function getSuccessRate(successCount: number, totalCount: number) {
  if (!totalCount) return null
  return Math.round((successCount / totalCount) * 100)
}

// Actions
async function login() {
  loginError.value = ''
  const auth = 'Basic ' + btoa(loginForm.value.username + ':' + loginForm.value.password)
  try {
    const res = await fetch(`${apiBase}/admin/providers`, {
      headers: { Authorization: auth },
    })
    if (res.ok) {
      sessionStorage.setItem('admin_auth', auth)
      isLoggedIn.value = true
      // 触发 NavBar 更新（如果在同一页面）- 实际上我们需要强制刷新或使用事件总线，但最简单的是 reload
      // 不过 AdminProviders 是视图组件，NavBar 是布局组件，它们状态不共享是个问题
      // 鉴于 NavBar 也依赖 sessionStorage 但不响应，这里的页面刷新是必要的
      window.location.reload() 
    } else {
      loginError.value = '鉴权失败'
    }
  } catch {
    loginError.value = '网络不可达'
  }
}

function logout() {
  sessionStorage.removeItem('admin_auth')
  isLoggedIn.value = false
  providers.value = []
  analytics.value = null
  window.location.reload()
}

async function loadAnalytics() {
  if (!isLoggedIn.value) return

  analyticsLoading.value = true
  analyticsError.value = ''
  try {
    const response = await fetch(buildAnalyticsPath(), {
      headers: { Authorization: getAuthHeader() },
    })
    if (!response.ok) {
      throw new Error('运营数据加载失败')
    }
    analytics.value = await response.json()
  } catch (error) {
    analyticsError.value = error instanceof Error ? error.message : '运营数据加载失败'
    analytics.value = null
  } finally {
    analyticsLoading.value = false
  }
}

async function loadData() {
  if (!isLoggedIn.value) return

  const headers = { Authorization: getAuthHeader() }
  analyticsLoading.value = true

  try {
    const [pRes, dRes, aRes, analyticsRes] = await Promise.all([
      fetch(`${apiBase}/admin/providers`, { headers }),
      fetch(`${apiBase}/admin/providers/defaults`, { headers }),
      fetch(`${apiBase}/admin/providers/adapters`, { headers }),
      fetch(buildAnalyticsPath(), { headers }),
    ])

    if (pRes.ok) providers.value = await pRes.json()
    if (dRes.ok) defaults.value = await dRes.json()
    if (aRes.ok) availableAdapters.value = await aRes.json()
    if (analyticsRes.ok) {
      analytics.value = await analyticsRes.json()
      analyticsError.value = ''
    } else {
      analytics.value = null
      analyticsError.value = '运营数据加载失败'
    }
  } finally {
    analyticsLoading.value = false
  }
}

// Computed
const filteredProviders = computed(() => {
  return providers.value
    .filter(p => p.type === activeTab.value)
    .sort((a, b) => b.priority - a.priority)
})

const adapterOptions = computed(() => {
  return availableAdapters.value
    .filter(a => a.startsWith(activeTab.value + ':'))
    .map(a => {
       const name = a.split(':')[1]
       return { value: name, label: name } // e.g. 'gemini', 'openai'
    })
})

const enabledProviderCount = computed(() => providers.value.filter((provider) => provider.enabled).length)

const providerSuccessRate = computed(() => {
  if (!analytics.value?.total_calls) return null
  return getSuccessRate(analytics.value.successful_calls, analytics.value.total_calls)
})

const analyticsProviderRows = computed(() => {
  return [...(analytics.value?.by_provider || [])].sort((left, right) => {
    if (right.call_count !== left.call_count) {
      return right.call_count - left.call_count
    }
    if (right.estimated_cost_usd !== left.estimated_cost_usd) {
      return right.estimated_cost_usd - left.estimated_cost_usd
    }
    return left.adapter.localeCompare(right.adapter)
  })
})

const analyticsUserRows = computed(() => {
  return [...(analytics.value?.by_user || [])].sort((left, right) => {
    if (right.call_count !== left.call_count) {
      return right.call_count - left.call_count
    }
    if (right.estimated_cost_usd !== left.estimated_cost_usd) {
      return right.estimated_cost_usd - left.estimated_cost_usd
    }
    return left.user_id.localeCompare(right.user_id)
  })
})

// UI Actions
function cloneDefault(type: string, name: string) {
  // 根据默认名称推断配置
  // 大多数默认 provider 的 name 就是 adapter name (如 gemini, openai, cqtai)
  // 如果未来有别名，这里可以做映射
  activeTab.value = type // 切换到对应 tab
  form.value = {
    type: type,
    name: name,
    adapter: name, // Default assumption
    priority: 10,
    enabled: true,
    weight: 1,
    timeout_ms: 60000,
    max_retries: 1,
    config_json: {}
  }
  editing.value = true
}

function openCreateModal() {
  form.value = {
    type: activeTab.value,
    priority: 10,
    enabled: true,
    weight: 1,
    timeout_ms: 60000,
    max_retries: 1,
    config_json: {}
  }
  editing.value = true
}

function edit(p: Provider) {
  const { has_api_key, ...rest } = p
  form.value = { ...rest, api_key: '', config_json: rest.config_json || {} } // Clear key for security, user re-enters if needed
  editing.value = true
}

function reset() {
  editing.value = false
  form.value = { config_json: {} }
}

async function submit() {
  const method = form.value.id ? 'PUT' : 'POST'
  const url = form.value.id
    ? `${apiBase}/admin/providers/${form.value.id}`
    : `${apiBase}/admin/providers`

  await fetch(url, {
    method,
    headers: {
      'Content-Type': 'application/json',
      Authorization: getAuthHeader(),
    },
    body: JSON.stringify(form.value),
  })

  await loadData()
  reset()
}

async function remove(p: Provider) {
  if (!confirm(`确认删除 ${p.name}?`)) return
  await fetch(`${apiBase}/admin/providers/${p.id}`, {
    method: 'DELETE',
    headers: { Authorization: getAuthHeader() },
  })
  await loadData()
}

async function toggleEnabled(p: Provider) {
  await fetch(`${apiBase}/admin/providers/${p.id}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
      Authorization: getAuthHeader(),
    },
    body: JSON.stringify({ enabled: !p.enabled }),
  })
  await loadData()
}

onMounted(() => {
  if (isLoggedIn.value) loadData()
})

watch([analyticsWindow, analyticsCapability], () => {
  if (isLoggedIn.value) {
    void loadAnalytics()
  }
})
</script>
