<template>
  <AdminLayout currentPage="subscription-plan">
    <view class="page">
    <!-- 顶部操作栏 -->
    <view class="toolbar">
      <text class="title">订阅方案管理</text>
      <button class="add-btn" @click="openCreate">新增方案</button>
    </view>

    <!-- 列表 -->
    <view v-if="!loading && plans.length > 0" class="list">
      <view class="row header">
        <text class="cell code">编码</text>
        <text class="cell name">名称</text>
        <text class="cell price">价格</text>
        <text class="cell period">周期</text>
        <text class="cell active">启用</text>
        <text class="cell sort">排序</text>
        <text class="cell actions">操作</text>
      </view>
      <list-view>
        <list-item v-for="item in plans" :key="item['id']">
          <view class="row">
            <text class="cell code">{{ item['plan_code'] }}</text>
            <text class="cell name">{{ item['name'] }}</text>
            <text class="cell price">{{ formatPrice(item['price']) }} {{ item['currency'] || 'CNY' }}</text>
            <text class="cell period">{{ item['billing_period'] === 'yearly' ? '年付' : '月付' }}</text>
            <view class="cell active">
              <switch :checked="!!item['is_active']" @change="onActiveChange(item, $event)" />
            </view>
            <view class="cell sort">
              <text>{{ item['sort_order'] ?? '-' }}</text>
            </view>
            <view class="cell actions">
              <button size="mini" @click="openEdit(item)">编辑</button>
              <button size="mini" type="warn" class="ml8" @click="confirmDelete(item)">删除</button>
            </view>
          </view>
        </list-item>
      </list-view>
    </view>

    <view v-if="!loading && plans.length === 0" class="empty">
      <text>暂无订阅方案</text>
    </view>

    <view v-if="loading" class="loading"><text>加载中...</text></view>

    <!-- 编辑弹层（纯样式实现，兼容 uni-app-x） -->
    <view v-if="editVisible" class="overlay" @click="closeEdit">
      <view class="sheet" @click.stop>
        <text class="sheet-title">{{ editMode === 'create' ? '新增方案' : '编辑方案' }}</text>

        <scroll-view scroll-y="true" class="form">
          <view class="form-item">
            <text class="label">编码</text>
            <input class="input" type="text" placeholder="例如: PRO_M"
                   :value="editForm.plan_code || ''"
                   @input="(e:any)=>editForm.plan_code=e.detail.value" />
          </view>
          <view class="form-item">
            <text class="label">名称</text>
            <input class="input" type="text" placeholder="例如: 专业版（月付）"
                   :value="editForm.name || ''"
                   @input="(e:any)=>editForm.name=e.detail.value" />
          </view>
          <view class="form-item">
            <text class="label">描述</text>
            <textarea class="textarea" placeholder="简要说明"
                      :value="editForm.description || ''"
                      @input="(e:any)=>editForm.description=e.detail.value"></textarea>
          </view>
          <view class="form-row">
            <view class="form-item half">
              <text class="label">价格</text>
              <input class="input" type="number" placeholder="例如: 99"
                     :value="String(editForm.price ?? '')"
                     @input="(e:any)=>editForm.price=toNumber(e.detail.value)" />
            </view>
            <view class="form-item half">
              <text class="label">币种</text>
              <input class="input" type="text" placeholder="CNY / USD"
                     :value="editForm.currency || 'CNY'"
                     @input="(e:any)=>editForm.currency=e.detail.value" />
            </view>
          </view>
          <view class="form-row">
            <view class="form-item half">
              <text class="label">周期</text>
              <picker mode="selector" :range="periodOptions" :value="periodIndex"
                      @change="onPeriodPick">
                <view class="picker-value">{{ editForm.billing_period === 'yearly' ? '年付' : '月付' }}</view>
              </picker>
            </view>
            <view class="form-item half">
              <text class="label">试用天数</text>
              <input class="input" type="number" placeholder="例如: 14（可留空）"
                     :value="editForm.trial_days != null ? String(editForm.trial_days) : ''"
                     @input="(e:any)=>editForm.trial_days=toOptionalNumber(e.detail.value)" />
            </view>
          </view>
          <view class="form-row">
            <view class="form-item half">
              <text class="label">排序</text>
              <input class="input" type="number" placeholder="越小越靠前"
                     :value="String(editForm.sort_order ?? '')"
                     @input="(e:any)=>editForm.sort_order=toOptionalNumber(e.detail.value)" />
            </view>
            <view class="form-item half switch-item">
              <text class="label">启用</text>
              <switch :checked="!!editForm.is_active" @change="(e:any)=>editForm.is_active=e.detail.value===true" />
            </view>
          </view>

          <view class="form-item">
            <text class="label">功能点（每行一个）</text>
            <textarea class="textarea" placeholder="示例：\n- 支持X\n- 提供Y"
                      :value="featuresText"
                      @input="(e:any)=>featuresText=e.detail.value"></textarea>
          </view>
        </scroll-view>

        <view class="sheet-actions">
          <button class="cancel" @click="closeEdit">取消</button>
          <button class="save" @click="savePlan">保存</button>
        </view>
      </view>
    </view>
  </view>
</AdminLayout>
</template>

<script lang="uts">
import supa from '@/components/supadb/aksupainstance.uts'
import AdminLayout from '@/layouts/admin/AdminLayout.uvue'


type UJ = UTSJSONObject

export default {
  data() {
    return {
      loading: false as boolean,
      plans: [] as Array<UJ>,
      // 编辑弹层
      editVisible: false as boolean,
      editMode: 'create' as 'create' | 'edit',
      editId: '' as string,
      editForm: {
        plan_code: '',
        name: '',
        description: '',
        price: 0,
        currency: 'CNY',
        billing_period: 'monthly',
        trial_days: null,
        is_active: true,
        sort_order: 0,
        features: null
      } as UJ,
      featuresText: '' as string,
      periodOptions: ['monthly','yearly'] as Array<string>,
      periodIndex: 0 as number
    }
  },

  onShow() {
    this.loadPlans()
  },

  methods: {
    async loadPlans() {
      try {
        this.loading = true
        const res = await supa
          .from('ml_subscription_plans')
          .select('*', {})
          .order('sort_order', { ascending: true })
          .execute()
        this.plans = Array.isArray(res.data) ? (res.data as Array<UJ>) : []
      } catch (e) {
        uni.showToast({ title: '加载失败', icon: 'none' })
      } finally {
        this.loading = false
      }
    },

    formatPrice(v: any): string {
      const n = Number(v)
      if (isNaN(n)) return String(v ?? '')
      return n.toFixed(2)
    },

    toNumber(v: any): number {
      const n = Number(v)
      return isNaN(n) ? 0 : n
    },

    toOptionalNumber(v: any): number | null {
      if (v == null || String(v).trim() === '') return null
      const n = Number(v)
      return isNaN(n) ? null : n
    },

    openCreate() {
      this.editMode = 'create'
      this.editId = ''
      this.editForm = {
        plan_code: '',
        name: '',
        description: '',
        price: 0,
        currency: 'CNY',
        billing_period: 'monthly',
        trial_days: null,
        is_active: true,
        sort_order: 0,
        features: null
      } as UJ
      this.featuresText = ''
      this.periodIndex = 0
      this.editVisible = true
    },

    openEdit(item: UJ) {
      this.editMode = 'edit'
      this.editId = (item['id'] ?? '') as string
      // 拷贝主要字段
      this.editForm = {
        plan_code: item['plan_code'] ?? '',
        name: item['name'] ?? '',
        description: item['description'] ?? '',
        price: item['price'] ?? 0,
        currency: item['currency'] ?? 'CNY',
        billing_period: item['billing_period'] ?? 'monthly',
        trial_days: item['trial_days'] ?? null,
        is_active: !!item['is_active'],
        sort_order: item['sort_order'] ?? 0,
        features: item['features'] ?? null
      } as UJ
      this.featuresText = this.featuresJsonToText(this.editForm['features'])
      this.periodIndex = this.editForm['billing_period'] === 'yearly' ? 1 : 0
      this.editVisible = true
    },

    closeEdit() {
      this.editVisible = false
    },

    onPeriodPick(e: any) {
      const idx = Number(e.detail.value)
      this.periodIndex = isNaN(idx) ? 0 : idx
      this.editForm['billing_period'] = this.periodOptions[this.periodIndex]
    },

    featuresTextToJson(text: string): UJ | null {
      // 将每行转换为 { f1: '...', f2: '...' }
      if (text == null || text.trim() === '') return null
      const lines = text.split(/\r?\n/).map(s => s.trim()).filter(s => s.length > 0)
      const obj: UJ = {} as any
      for (let i = 0; i < lines.length; i++) {
        const key = 'f' + (i + 1)
        ;(obj as any)[key] = lines[i]
      }
      return obj
    },

    featuresJsonToText(j: any): string {
      if (j == null) return ''
      const out: Array<string> = []
      try {
        const keys = Object.keys(j as any)
        for (let i = 0; i < keys.length; i++) {
          const k = keys[i]
          const v = (j as any)[k]
          out.push(typeof v === 'string' ? v : JSON.stringify(v))
        }
      } catch (e) {
        // ignore
      }
      return out.join('\n')
    },

    async savePlan() {
      // 校验
      if (!this.editForm['plan_code'] || !this.editForm['name']) {
        uni.showToast({ title: '编码和名称必填', icon: 'none' })
        return
      }
      if (this.editForm['price'] == null || Number(this.editForm['price']) < 0) {
        uni.showToast({ title: '价格需为非负数', icon: 'none' })
        return
      }

      // features 处理
      this.editForm['features'] = this.featuresTextToJson(this.featuresText)

      try {
        if (this.editMode === 'create') {
          const res = await supa
            .from('ml_subscription_plans')
            .insert([this.editForm])
            .execute()
          if (res.status >= 200 && res.status < 300) {
            uni.showToast({ title: '创建成功', icon: 'success' })
            this.closeEdit()
            this.loadPlans()
          } else {
            uni.showToast({ title: '创建失败', icon: 'none' })
          }
        } else {
          const res = await supa
            .from('ml_subscription_plans')
            .update(this.editForm)
            .eq('id', this.editId)
            .execute()
          if (res.status >= 200 && res.status < 300) {
            uni.showToast({ title: '保存成功', icon: 'success' })
            this.closeEdit()
            this.loadPlans()
          } else {
            uni.showToast({ title: '保存失败', icon: 'none' })
          }
        }
      } catch (e) {
        uni.showToast({ title: '请求失败', icon: 'none' })
      }
    },

    confirmDelete(item: UJ) {
      const id = (item['id'] ?? '') as string
      if (!id) return
      uni.showModal({
        title: '删除确认',
        content: `确定删除方案「${item['name'] ?? ''}」吗？`,
        success: (r:any) => {
          if (r.confirm) this.deletePlan(id)
        }
      })
    },

    async deletePlan(id: string) {
      try {
        const res = await supa
          .from('ml_subscription_plans')
          .delete()
          .eq('id', id)
          .execute()
        if (res.status >= 200 && res.status < 300) {
          uni.showToast({ title: '已删除', icon: 'success' })
          this.loadPlans()
        } else {
          uni.showToast({ title: '删除失败', icon: 'none' })
        }
      } catch (e) {
        uni.showToast({ title: '请求失败', icon: 'none' })
      }
    },

    async onActiveChange(item: UJ, evt: any) {
      const id = (item['id'] ?? '') as string
      const newVal = evt?.detail?.value === true
      try {
        const res = await supa
          .from('ml_subscription_plans')
          .update({ is_active: newVal })
          .eq('id', id)
          .execute()
        if (!(res.status >= 200 && res.status < 300)) {
          uni.showToast({ title: '更新失败', icon: 'none' })
          // 回滚 UI
          item['is_active'] = !newVal
        }
      } catch (e) {
        uni.showToast({ title: '请求失败', icon: 'none' })
        item['is_active'] = !newVal
      }
    }
  }
}
</script>

<style scoped>
.page { padding: 12px; }
.toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.title { font-size: 18px; font-weight: 600; }
.add-btn { background: #3cc51f; color: #fff; border-radius: 6px; padding: 8px 12px; }

.list { background: #fff; border-radius: 10px; overflow: hidden; }
.row { display: flex; align-items: center; padding: 10px; }
.row.header { background: #fafafa; font-weight: 600; color: #555; }
.cell { padding: 0 6px; }
.code { width: 18%; }
.name { width: 22%; }
.price { width: 18%; }
.period { width: 12%; }
.active { width: 12%; display: flex; align-items: center; }
.sort { width: 8%; }
.actions { width: 20%; display: flex; justify-content: flex-end; }
.ml8 { margin-left: 8px; }

.empty, .loading { padding: 24px; text-align: center; color: #888; }

/* 弹层 */
.overlay { position: fixed; left: 0; right: 0; top: 0; bottom: 0; background: rgba(0,0,0,0.45); display: flex; align-items: flex-end; }
.sheet { background: #fff; width: 100%; max-height: 80%; border-top-left-radius: 12px; border-top-right-radius: 12px; padding: 12px; }
.sheet-title { font-size: 16px; font-weight: 600; margin-bottom: 8px; }
.form { max-height: 60vh; }
.form-item { margin-bottom: 12px; }
.form-row { display: flex; gap: 10px; }
.half { flex: 1; }
.label { font-size: 13px; color: #666; margin-bottom: 6px; display: block; }
.input { background: #f6f6f6; border-radius: 6px; padding: 8px; }
.textarea { background: #f6f6f6; border-radius: 6px; padding: 8px; min-height: 80px; }
.picker-value { background: #f6f6f6; border-radius: 6px; padding: 8px; color: #333; }
.switch-item { display: flex; align-items: center; justify-content: space-between; }
.sheet-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 10px; }
.cancel { background: #f0f0f0; color: #333; border-radius: 6px; padding: 8px 12px; }
.save { background: #3cc51f; color: #fff; border-radius: 6px; padding: 8px 12px; }
</style>