/* 资产编辑模态框 */
const AssetModal = {
  template: `
  <div v-if="store.assetModal.show" class="fixed inset-0 bg-black/40 z-50 flex items-end md:items-center justify-center p-0 md:p-4">
    <div class="bg-white dark:bg-slate-900 w-full md:max-w-lg md:rounded-xl rounded-t-xl max-h-[92vh] overflow-y-auto">
      <div class="px-5 py-3 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center sticky top-0 bg-white dark:bg-slate-900">
        <h3 class="font-semibold text-sm">{{ store.assetModal.editing ? '编辑资产' : '新增资产' }}</h3>
        <button @click="store.assetModal.show=false" class="text-slate-400 hover:text-slate-600">✕</button>
      </div>
      <form @submit.prevent="save" class="px-5 py-4 space-y-3" v-if="f">
        <div class="grid grid-cols-2 gap-3">
          <label class="col-span-2 block"><span class="text-xs text-slate-500">名称 *</span>
            <input v-model="f.name" required class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <label class="block"><span class="text-xs text-slate-500">类型 *</span>
            <select v-model="f.asset_type" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm">
              <option v-for="(l,k) in Fmt.TYPE_LABELS" :key="k" :value="k">{{ l }}</option>
            </select></label>
          <label class="block"><span class="text-xs text-slate-500">所属平台</span>
            <select v-model="f.provider_id" @change="onProviderChange" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm">
              <option :value="null">未指定</option>
              <option v-for="p in providersForType" :key="p.id" :value="p.id">{{ p.name }}</option>
            </select></label>
          <label class="block"><span class="text-xs text-slate-500">到期时间</span>
            <input type="date" v-model="f.expiry_date" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <label class="block"><span class="text-xs text-slate-500">续费周期</span>
            <select v-model="f.renewal_cycle" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm">
              <option value="">未设定</option><option v-for="(l,k) in Fmt.CYCLE_LABELS" :key="k" :value="k">{{ l }}</option>
            </select></label>
          <label class="block"><span class="text-xs text-slate-500">费用</span>
            <input type="number" step="0.01" v-model.number="f.cost" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <label class="block"><span class="text-xs text-slate-500">币种</span>
            <select v-model="f.currency" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm">
              <option>USD</option><option>CNY</option><option>JPY</option><option>EUR</option>
            </select></label>
          <label class="col-span-2 block"><span class="text-xs text-slate-500">续费网址</span>
            <input v-model="f.renew_url" placeholder="https://…（去哪续费）" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <label class="col-span-2 block"><span class="text-xs text-slate-500">取消订阅网址</span>
            <input v-model="f.cancel_url" placeholder="https://…（去哪取消）" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <label class="block"><span class="text-xs text-slate-500">状态</span>
            <select v-model="f.status" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm">
              <option v-for="(l,k) in Fmt.STATUS_LABELS" :key="k" :value="k">{{ l }}</option>
            </select></label>
          <label class="block"><span class="text-xs text-slate-500">所属账号</span>
            <input v-model="f.account" list="account-options" placeholder="在「平台」页管理账号" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm">
            <datalist id="account-options">
              <option v-for="a in store.accounts" :key="a.id" :value="a.name">{{ accountLabel(a) }}</option>
            </datalist></label>
          <div class="col-span-2 flex gap-5 text-sm text-slate-600 dark:text-slate-300">
            <label class="flex items-center gap-2"><input type="checkbox" v-model="f.auto_renew"> 自动续费</label>
            <label class="flex items-center gap-2"><input type="checkbox" v-model="f.is_archived"> 已归档</label>
          </div>
        </div>

        <fieldset v-if="f.asset_type==='vps'" class="border border-slate-200 dark:border-slate-700 rounded-lg p-3">
          <legend class="text-xs font-medium text-slate-600 dark:text-slate-300 px-1">VPS 详情</legend>
          <div class="grid grid-cols-2 gap-2">
            <label class="block"><span class="text-xs text-slate-400">公网 IP *</span><input v-model="f.vps_detail.ip_address" required class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">Tailscale IP</span><input v-model="f.vps_detail.tailscale_ip" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">区域</span><input v-model="f.vps_detail.region" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">系统</span><input v-model="f.vps_detail.os" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">CPU核</span><input type="number" v-model.number="f.vps_detail.cpu_cores" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">内存GB</span><input type="number" step="0.5" v-model.number="f.vps_detail.memory_gb" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">磁盘GB</span><input type="number" v-model.number="f.vps_detail.disk_gb" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">SSH端口</span><input type="number" v-model.number="f.vps_detail.ssh_port" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">SSH用户</span><input v-model="f.vps_detail.ssh_user" placeholder="root" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">登录方式</span><select v-model="f.vps_detail.login_method" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"><option value="key">密钥</option><option value="password">密码</option><option value="other">其他</option></select></label>
            <label class="block"><span class="text-xs text-slate-400">SSH密钥</span><input v-model="f.vps_detail.ssh_key" type="password" :placeholder="store.assetModal.editing ? '留空不修改' : ''" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">密码</span><input v-model="f.vps_detail.password" type="password" :placeholder="store.assetModal.editing ? '留空不修改' : ''" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="col-span-2 block"><span class="text-xs text-slate-400">用途/项目</span><input v-model="f.vps_detail.purpose" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          </div>
        </fieldset>

        <fieldset v-if="f.asset_type==='domain'" class="border border-slate-200 dark:border-slate-700 rounded-lg p-3">
          <legend class="text-xs font-medium text-slate-600 dark:text-slate-300 px-1">域名详情</legend>
          <div class="grid grid-cols-2 gap-2">
            <label class="col-span-2 block"><span class="text-xs text-slate-400">域名 *</span><input v-model="f.domain_detail.domain_name" required class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">注册商</span><input v-model="f.domain_detail.registrar" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">DNS托管</span><input v-model="f.domain_detail.dns_provider" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">CF账号</span><input v-model="f.domain_detail.cloudflare_account" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">绑定资产ID</span><input type="number" v-model.number="f.domain_detail.bind_asset_id" placeholder="关联VPS的ID" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="col-span-2 flex items-center gap-2 text-sm text-slate-600 dark:text-slate-300"><input type="checkbox" v-model="f.domain_detail.is_using"> 仍在实际使用</label>
          </div>
        </fieldset>

        <fieldset v-if="f.asset_type==='ai_agent'" class="border border-slate-200 dark:border-slate-700 rounded-lg p-3">
          <legend class="text-xs font-medium text-slate-600 dark:text-slate-300 px-1">AI 账号详情</legend>
          <div class="grid grid-cols-2 gap-2">
            <label class="block"><span class="text-xs text-slate-400">服务商 *</span><input v-model="f.ai_detail.provider" required class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">计划</span><input v-model="f.ai_detail.plan" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="col-span-2 block"><span class="text-xs text-slate-400">API Key</span><input v-model="f.ai_detail.api_key" type="password" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">余额</span><input type="number" step="0.01" v-model.number="f.ai_detail.balance" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">月限额</span><input type="number" step="0.01" v-model.number="f.ai_detail.monthly_limit" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          </div>
        </fieldset>

        <fieldset v-if="f.asset_type==='cloudflare'" class="border border-slate-200 dark:border-slate-700 rounded-lg p-3">
          <legend class="text-xs font-medium text-slate-600 dark:text-slate-300 px-1">Cloudflare 子资产详情</legend>
          <div class="grid grid-cols-2 gap-2">
            <label class="block"><span class="text-xs text-slate-400">账号邮箱</span><input v-model="f.cloudflare_detail.account_email" placeholder="账号邮箱（区分多账号）" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">子资产类型</span><select v-model="f.cloudflare_detail.sub_type" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"><option value="zone">zone(解析)</option><option value="worker">Worker</option><option value="r2">R2</option><option value="tunnel">Tunnel</option><option value="mail">Mail</option><option value="dns_record">DNS记录</option><option value="other">其他</option></select></label>
            <label class="block"><span class="text-xs text-slate-400">子资产名称</span><input v-model="f.cloudflare_detail.sub_name" placeholder="如 worker 名 / bucket 名" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="block"><span class="text-xs text-slate-400">关联 zone/域名</span><input v-model="f.cloudflare_detail.zone_name" placeholder="example.com" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
            <label class="col-span-2 block"><span class="text-xs text-slate-400">状态</span><input v-model="f.cloudflare_detail.status" placeholder="active / paused 等" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          </div>
        </fieldset>

        <label class="block"><span class="text-xs text-slate-500">备注</span>
          <textarea v-model="f.remark" rows="2" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></textarea></label>

        <div class="flex justify-end gap-2 pt-1">
          <button type="button" @click="store.assetModal.show=false" class="px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-700 text-sm text-slate-600 dark:text-slate-300">取消</button>
          <button type="submit" class="px-4 py-2 rounded-lg bg-blue-600 text-white text-sm hover:bg-blue-700">{{ store.assetModal.editing ? '保存' : '创建' }}</button>
        </div>
      </form>
    </div>
  </div>`,
  setup() {
    const f = Vue.computed(() => store.assetModal.form);
    const providersForType = Vue.computed(() => {
      const t = f.value ? f.value.asset_type : null;
      const map = { vps: 'vps', domain: 'domain', ai_agent: 'ai_agent', cloudflare: 'cloudflare' };
      const cat = map[t];
      if (!cat) return store.providers;
      // 综合平台按 services 过滤（如阿里云可同时选 vps/domain）；services 为空时回退分类匹配
      return store.providers.filter(p => {
        if (p.services) return p.services.split(',').map(s => s.trim()).includes(cat);
        return p.category === cat || p.category === 'other';
      });
    });
    function onProviderChange() {
      const p = store.providers.find(x => x.id === f.value.provider_id);
      if (p) f.value.provider = p.slug;
    }
    // 账号候选显示：说明优先，其次平台名（platform 存的是 slug，回退原值）
    function accountLabel(a) {
      if (a.remark) return a.remark + ' · ' + a.name;
      const p = store.providers.find(x => x.slug === a.platform);
      return p ? a.name + '（' + p.name + '）' : a.name;
    }
    return { store, Fmt, f, providersForType, onProviderChange, accountLabel, save: saveAsset };
  },
};

/* 平台编辑模态框 */
const ProviderModal = {
  template: `
  <div v-if="store.providerModal.show" class="fixed inset-0 bg-black/40 z-50 flex items-end md:items-center justify-center p-0 md:p-4">
    <div class="bg-white dark:bg-slate-900 w-full md:max-w-md md:rounded-xl rounded-t-xl max-h-[92vh] overflow-y-auto">
      <div class="px-5 py-3 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center">
        <h3 class="font-semibold text-sm">{{ store.providerModal.editing ? '编辑平台' : '新增平台' }}</h3>
        <button @click="store.providerModal.show=false" class="text-slate-400 hover:text-slate-600">✕</button>
      </div>
      <form @submit.prevent="save" class="px-5 py-4 space-y-3" v-if="f">
        <div class="grid grid-cols-2 gap-3">
          <label class="block"><span class="text-xs text-slate-500">标识 slug *</span><input v-model="f.slug" required placeholder="aliyun" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <label class="block"><span class="text-xs text-slate-500">名称 *</span><input v-model="f.name" required class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <label class="col-span-2 block"><span class="text-xs text-slate-500">分类</span><select v-model="f.category" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"><option v-for="(l,k) in Fmt.CATEGORY_LABELS" :key="k" :value="k">{{ l }}</option></select></label>
          <div class="col-span-2 block"><span class="text-xs text-slate-500">提供服务（可多选，综合平台全选）</span>
            <div class="flex flex-wrap gap-x-3 gap-y-1 mt-1">
              <label v-for="(l,k) in Fmt.SERVICES_LABELS" :key="k" class="flex items-center gap-1 text-xs text-slate-600 dark:text-slate-300"><input type="checkbox" :checked="servicesSet.has(k)" @change="toggleService(k)"> {{ l }}</label>
            </div>
          </div>
          <label class="block"><span class="text-xs text-slate-500">SDK类型</span><select v-model="f.sdk_type" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"><option value="">未指定</option><option v-for="o in sdkOptions" :key="o.type" :value="o.type">{{ o.type }}</option></select></label>
          <label class="col-span-2 block"><span class="text-xs text-slate-500">官网</span><input v-model="f.website" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <label class="col-span-2 block"><span class="text-xs text-slate-500">管理面板URL</span><input v-model="f.console_url" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          <div v-if="currentFields.length" class="col-span-2 border border-slate-200 dark:border-slate-700 rounded-lg p-3 space-y-2">
            <div class="text-xs font-medium text-slate-600 dark:text-slate-300">API 凭证（加密存储）</div>
            <label v-for="field in currentFields" :key="field" class="block"><span class="text-xs text-slate-400">{{ field }}</span><input v-model="apiFields[field]" type="password" :placeholder="store.providerModal.editing ? '留空不修改' : '填写 ' + field" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
          </div>
          <div v-else-if="f.sdk_type" class="col-span-2 text-xs text-amber-600 dark:text-amber-400">该 SDK 类型暂无预设凭证字段（可后续扩展）</div>
          <label class="col-span-2 flex items-center gap-2 text-sm text-slate-600 dark:text-slate-300"><input type="checkbox" v-model="f.enabled"> 启用</label>
        </div>
        <div class="flex justify-end gap-2">
          <button type="button" @click="store.providerModal.show=false" class="px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-700 text-sm text-slate-600 dark:text-slate-300">取消</button>
          <button type="submit" class="px-4 py-2 rounded-lg bg-blue-600 text-white text-sm hover:bg-blue-700">保存</button>
        </div>
      </form>
    </div>
  </div>`,
  setup() {
    const f = Vue.computed(() => store.providerModal.form);
    const adapterMeta = Vue.ref([]);
    const apiFields = Vue.reactive({});
    Vue.onMounted(async () => {
      try { const r = await Api.get('/providers/adapters'); adapterMeta.value = r.adapters || []; } catch (e) { /* ignore */ }
    });
    const sdkOptions = Vue.computed(() => {
      const opts = [];
      for (const m of adapterMeta.value) for (const t of (m.sdk_types || [])) opts.push({ type: t, fields: m.required_config || [] });
      return opts;
    });
    const currentFields = Vue.computed(() => {
      const opt = sdkOptions.value.find(o => o.type === (f.value && f.value.sdk_type));
      return opt ? opt.fields : [];
    });
    // 提供服务多选：services 逗号分隔字符串 <-> checkbox 集合
    const servicesSet = Vue.computed(() => new Set((f.value && f.value.services || '').split(',').map(s => s.trim()).filter(Boolean)));
    function toggleService(k) {
      const arr = (f.value.services || '').split(',').map(s => s.trim()).filter(Boolean);
      const idx = arr.indexOf(k);
      if (idx >= 0) arr.splice(idx, 1); else arr.push(k);
      f.value.services = arr.join(',');
    }
    // 模态框每次打开时清空上次残留的凭证输入，避免串号
    Vue.watch(() => store.providerModal.show, (show) => {
      if (show) { for (const k of Object.keys(apiFields)) delete apiFields[k]; }
    });
    function save() {
      const cfg = {};
      for (const field of currentFields.value) if (apiFields[field]) cfg[field] = apiFields[field];
      if (Object.keys(cfg).length) f.value.api_config = JSON.stringify(cfg);
      saveProvider();
    }
    return { store, Fmt, f, sdkOptions, currentFields, servicesSet, toggleService, apiFields, save };
  },
};

/* 账号编辑模态框 */
const AccountModal = {
  template: `
  <div v-if="store.accountModal.show" class="fixed inset-0 bg-black/40 z-50 flex items-end md:items-center justify-center p-0 md:p-4">
    <div class="bg-white dark:bg-slate-900 w-full md:max-w-md md:rounded-xl rounded-t-xl max-h-[92vh] overflow-y-auto">
      <div class="px-5 py-3 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center">
        <h3 class="font-semibold text-sm">{{ store.accountModal.editing ? '编辑账号' : '新增账号' }}</h3>
        <button @click="store.accountModal.show=false" class="text-slate-400 hover:text-slate-600">✕</button>
      </div>
      <form @submit.prevent="save" class="px-5 py-4 space-y-3" v-if="f">
        <label class="block"><span class="text-xs text-slate-500">账号说明（这个账号是干嘛的）</span>
          <input v-model="f.remark" placeholder="如：XX公司代管账号" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
        <label class="block"><span class="text-xs text-slate-500">账号标识 *（邮箱/用户名）</span>
          <input v-model="f.name" required placeholder="如 you@example.com" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
        <label class="block"><span class="text-xs text-slate-500">所属平台</span>
          <select v-model="f.platform" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm">
            <option value="">未指定</option>
            <option v-for="p in store.providers" :key="p.id" :value="p.slug">{{ p.name }}</option>
          </select></label>
        <p v-if="store.accountModal.editing" class="text-xs text-slate-400">修改账号标识后，引用该账号的资产会自动同步更新。</p>
        <div class="flex justify-end gap-2">
          <button type="button" @click="store.accountModal.show=false" class="px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-700 text-sm text-slate-600 dark:text-slate-300">取消</button>
          <button type="submit" class="px-4 py-2 rounded-lg bg-blue-600 text-white text-sm hover:bg-blue-700">保存</button>
        </div>
      </form>
    </div>
  </div>`,
  setup() {
    const f = Vue.computed(() => store.accountModal.form);
    return { store, f, save: saveAccount };
  },
};

/* 账号查看弹窗：平台 → 账号 → 资产 三层结构，展开账号看名下资产 */
const AccountsViewModal = {
  template: `
  <div v-if="store.accountsModal.show" class="fixed inset-0 bg-black/40 z-50 flex items-end md:items-center justify-center p-0 md:p-4">
    <div class="bg-white dark:bg-slate-900 w-full md:max-w-lg md:rounded-xl rounded-t-xl max-h-[92vh] overflow-y-auto">
      <div class="px-5 py-3 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center sticky top-0 bg-white dark:bg-slate-900">
        <h3 class="font-semibold text-sm">👤 {{ title }}（{{ accountList.length }}）</h3>
        <div class="flex items-center gap-3">
          <button @click="add" class="text-xs text-blue-600 dark:text-blue-400">+ 新增账号</button>
          <button @click="store.accountsModal.show=false" class="text-slate-400 hover:text-slate-600">✕</button>
        </div>
      </div>
      <div class="px-5 py-4">
        <p v-if="!accountList.length" class="text-xs text-slate-400">暂无账号。一个平台可有多个账号（如代管/公司账号），添加后可在资产表单「所属账号」中选择。</p>
        <div v-else class="space-y-4">
          <div v-for="g in groups" :key="g.platform">
            <div v-if="!singleProvider" class="text-xs font-medium text-slate-400 mb-1">{{ g.platform ? platformName(g.platform) : '未指定平台' }}</div>
            <div class="divide-y divide-slate-100 dark:divide-slate-800 border border-slate-100 dark:border-slate-800 rounded-lg">
              <div v-for="a in g.accounts" :key="a.id">
                <div class="px-3 py-2 flex items-center gap-2">
                  <button @click="toggle(a.id)" class="text-slate-400 text-xs w-4">{{ expanded[a.id] ? '▾' : '▸' }}</button>
                  <div class="flex-1 min-w-0">
                    <div class="text-sm truncate">{{ a.remark || a.name }}</div>
                    <div class="text-xs text-slate-400 truncate"><span v-if="a.remark">{{ a.name }} · </span>关联 {{ assetsOf(a).length }} 个资产</div>
                  </div>
                  <button @click="edit(a)" class="text-xs text-blue-600 dark:text-blue-400">编辑</button>
                  <button @click="del(a)" class="text-xs text-red-600 dark:text-red-400">删除</button>
                </div>
                <div v-if="expanded[a.id]" class="px-3 pb-2 pl-9 space-y-1">
                  <p v-if="!assetsOf(a).length" class="text-xs text-slate-400">该账号下暂无资产（编辑资产时在「所属账号」选择 {{ a.name }} 即可关联）</p>
                  <div v-for="asset in assetsOf(a)" :key="asset.id" class="text-xs flex items-center gap-2">
                    <span class="px-1.5 py-0.5 rounded-full shrink-0" :class="Fmt.typeBadge(asset.asset_type)">{{ Fmt.TYPE_LABELS[asset.asset_type] }}</span>
                    <span class="truncate">{{ asset.name }}</span>
                    <span v-if="asset.expiry_date" class="text-slate-400 shrink-0">{{ asset.expiry_date }} 到期</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>`,
  setup() {
    const expanded = Vue.reactive({});
    const singleProvider = Vue.computed(() => !!store.accountsModal.providerSlug);
    const title = Vue.computed(() => {
      const slug = store.accountsModal.providerSlug;
      if (!slug) return '全部账号';
      const p = store.providers.find(x => x.slug === slug);
      return (p ? p.name : slug) + ' 的账号';
    });
    const accountList = Vue.computed(() => {
      const slug = store.accountsModal.providerSlug;
      return slug ? store.accounts.filter(a => a.platform === slug) : store.accounts;
    });
    // 全部模式下按平台分组，保持 平台→账号→资产 层级
    const groups = Vue.computed(() => {
      const m = new Map();
      for (const a of accountList.value) {
        const key = a.platform || '';
        if (!m.has(key)) m.set(key, []);
        m.get(key).push(a);
      }
      return [...m.entries()].map(([platform, accounts]) => ({ platform, accounts }));
    });
    function platformName(slug) {
      const p = store.providers.find(x => x.slug === slug);
      return p ? p.name : slug;
    }
    function assetsOf(a) {
      return store.assets.filter(x => x.account === a.name);
    }
    function toggle(id) { expanded[id] = !expanded[id]; }
    // 每次打开重置展开状态
    Vue.watch(() => store.accountsModal.show, (show) => {
      if (show) for (const k of Object.keys(expanded)) delete expanded[k];
    });
    return {
      store, Fmt, expanded, singleProvider, title, accountList, groups,
      platformName, assetsOf, toggle,
      add: () => openAccountCreate(store.accountsModal.providerSlug || ''),
      edit: openAccountEdit, del: deleteAccount,
    };
  },
};
