/**
 * VIP 权限判断（全局方法）
 * - 默认读登录态 userInfo.vip
 * - 接诊/复诊等场景务必传入「履约诊所」vip，避免用错门店权益
 * - 模板显隐优先用 <VipGate code="xxx" :vip="storeVip" />
 */
import { computed, type ComputedRef, type Ref } from 'vue';

import { useUserStore } from '@vben/stores';

/** 与 xk_vip_feature.code / 等级 permissions 对齐的常用功能码 */
export const VIP_FEATURE = {
  MEDICAL_RECORD: 'medical_record',
  AI_MEDICAL_RECORD: 'ai_medical_record',
  AI_PRESCRIPTION: 'ai_prescription',
  GOLDEN_FORMULA: 'golden_formula',
} as const;

export type VipFeatureCode = (typeof VIP_FEATURE)[keyof typeof VIP_FEATURE] | string;

export interface StoreVipInfo {
  level_code?: string;
  level_name?: string;
  level_weight?: number;
  badge_url?: string;
  duration_type?: string;
  duration_label?: string;
  duration_badge_url?: string;
  permissions?: string[];
  expire_at?: number;
  is_lifetime?: boolean;
}

/** 读取当前登录用户 VIP 信息 */
export function getCurrentVip(): StoreVipInfo | null {
  const userStore = useUserStore();
  return ((userStore.userInfo as any)?.vip as StoreVipInfo) || null;
}

/**
 * 从 get-current-store-type / 同类接口响应中取出 vip 对象
 * 兼容 result / data / 已解包
 */
export function pickVipFromApiPayload(payload: unknown): StoreVipInfo | null {
  if (!payload || typeof payload !== 'object') return null;
  const raw = payload as Record<string, any>;
  const data = raw.result ?? raw.data ?? raw;
  if (!data || typeof data !== 'object') return null;
  const vip = (data as any).vip;
  return vip && typeof vip === 'object' ? (vip as StoreVipInfo) : null;
}

/** 规范化 permissions 列表 */
export function normalizeVipPermissions(
  vipOrPermissions?: StoreVipInfo | string[] | null,
): string[] {
  if (Array.isArray(vipOrPermissions)) {
    return vipOrPermissions.filter((x) => typeof x === 'string' && x);
  }
  if (vipOrPermissions && typeof vipOrPermissions === 'object') {
    const list = vipOrPermissions.permissions;
    return Array.isArray(list) ? list.filter((x) => typeof x === 'string' && x) : [];
  }
  const cur = getCurrentVip()?.permissions;
  return Array.isArray(cur) ? cur.filter((x) => typeof x === 'string' && x) : [];
}

/**
 * 是否拥有指定权限码（全局判断方法）
 * @param code 权限码，如 VIP_FEATURE.MEDICAL_RECORD
 * @param vipOrPermissions 挂号侧 vip / permissions；
 *   - 不传：用登录态 userInfo.vip
 *   - 显式传 null：视为无履约诊所权益（不回落登录态，避免接诊未就绪时误放行）
 */
export function hasVipPermission(
  code: string,
  vipOrPermissions?: StoreVipInfo | string[] | null,
): boolean {
  if (!code) return false;
  if (arguments.length < 2) {
    return normalizeVipPermissions().includes(code);
  }
  if (vipOrPermissions == null) {
    return false;
  }
  return normalizeVipPermissions(vipOrPermissions).includes(code);
}

/**
 * 等级是否不低于目标（按 level_weight；若无 weight 则仅精确匹配编码时返回 true）
 */
export function levelAtLeast(minCode: string, vip?: StoreVipInfo | null): boolean {
  const current = vip ?? getCurrentVip();
  if (!current?.level_code) return false;
  if (current.level_code === minCode) return true;
  const weight = Number(current.level_weight ?? 0);
  const minWeight = parseLevelWeight(minCode);
  if (minWeight >= 0) {
    return weight >= minWeight;
  }
  return false;
}

/** 粗略解析 V0-V11 / BLACK_GOLD / CUSTOM 权重 */
function parseLevelWeight(code: string): number {
  if (/^V\d+$/i.test(code)) {
    return Number(code.slice(1));
  }
  if (code === 'BLACK_GOLD') return 12;
  if (code === 'CUSTOM') return 13;
  return -1;
}

/**
 * 组合式：基于可选的门店 vip ref 做权限判断（接诊台推荐）
 * @example
 * const { has, canUseMedicalRecord } = useVipPermission(receptionVip)
 * const ok = has(VIP_FEATURE.MEDICAL_RECORD)
 */
export function useVipPermission(
  vipSource?: Ref<StoreVipInfo | null | undefined> | ComputedRef<StoreVipInfo | null | undefined>,
) {
  /** 传入了 vipSource 时始终走履约诊所分支（含 null=无权益） */
  const has = (code: string) => {
    if (vipSource) {
      return hasVipPermission(code, vipSource.value ?? null);
    }
    return hasVipPermission(code);
  };
  return {
    vip: computed(() => (vipSource ? vipSource.value : getCurrentVip())),
    has,
    hasVipPermission: has,
    levelAtLeast: (minCode: string) =>
      levelAtLeast(minCode, vipSource ? vipSource.value ?? null : getCurrentVip()),
    canUseMedicalRecord: computed(() => has(VIP_FEATURE.MEDICAL_RECORD)),
    canUseAiMedicalRecord: computed(() => has(VIP_FEATURE.AI_MEDICAL_RECORD)),
    canUseAiPrescription: computed(() => has(VIP_FEATURE.AI_PRESCRIPTION)),
    canUseGoldenFormula: computed(() => has(VIP_FEATURE.GOLDEN_FORMULA)),
  };
}

/** @deprecated 请用 useVipPermission；保留兼容旧调用 */
export function useVipGate() {
  return useVipPermission();
}

/**
 * 格式化 VIP 到期时间文案（列表/弹窗共用）
 * @param vip 门店 VIP 信息
 * @param options.emptyText 普通会员/无数据时的文案，默认空串
 * @param options.lifetimeText 终身文案，默认「终身」
 * @param options.withPrefix 是否加「至」前缀（非终身时）
 */
export function formatVipExpireAt(
  vip?: StoreVipInfo | Record<string, any> | null,
  options?: {
    emptyText?: string;
    lifetimeText?: string;
    withPrefix?: boolean;
  },
): string {
  const emptyText = options?.emptyText ?? '';
  const lifetimeText = options?.lifetimeText ?? '终身';
  const withPrefix = options?.withPrefix ?? false;
  if (!vip) return emptyText;
  const code = String(vip.level_code || 'V0').trim() || 'V0';
  if (code === 'V0') return emptyText;
  if (vip.is_lifetime) return lifetimeText;
  const raw = vip.expire_at as unknown;
  if (raw == null || raw === '' || raw === 0) {
    // 无到期日且非 V0：按终身展示（与列表列逻辑一致）
    return lifetimeText;
  }
  // 后端偶发已格式化成 Y-m-d H:i:s
  if (typeof raw === 'string' && Number.isNaN(Number(raw))) {
    return withPrefix ? `至 ${raw}` : raw;
  }
  const n = Number(raw);
  if (!(n > 0)) return lifetimeText;
  const d = new Date(n * 1000);
  if (Number.isNaN(d.getTime())) return emptyText;
  const pad = (x: number) => String(x).padStart(2, '0');
  const text = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
  return withPrefix ? `至 ${text}` : text;
}

/**
 * 列表副文案：时长类型 + 到期（如「月卡 · 至 2026-08-10 …」）
 */
export function formatVipDurationExpireLine(
  vip?: StoreVipInfo | Record<string, any> | null,
): string {
  if (!vip) return '点击管理';
  const code = String(vip.level_code || 'V0').trim() || 'V0';
  if (code === 'V0') return '点击管理';
  const duration = String(vip.duration_label || '').trim();
  const expire = formatVipExpireAt(vip, { withPrefix: true, lifetimeText: '终身' });
  if (duration && expire) return `${duration} · ${expire}`;
  return duration || expire || '点击管理';
}
