import { Injectable } from '@nestjs/common';
import { PersonaFeatureKey, FactType } from '@pac/types';
import type {
  ActiveFact,
  FeatureExtractor,
  FeatureExtractorContext,
  PersonaFeatureDraft,
} from './feature.interface';

/**
 * discount_anchor 折扣锚点(D.1.3)— 规则层,snapshot
 *
 * 标签:历史最大折扣力度(最低折扣率)+ 对应结算日期/项目。销售推优惠的价格底线参考。
 *
 * 数据源:payment_record.content(摄入自结算):receivable_cents=应收(原价,2026-07 起;
 *   旧事实 fallback amount_cents)、discount_cents=折扣额(分,4渠道和)。
 *   ⚠️ 折扣率 = (应收−折扣)/应收;amount_cents 已切实付,不能再当分母
 *      (discount_*_rate 实为折扣金额,非比率;储值卡实付=0 但 discount=0,口径稳)。
 *
 * 算法:遍历"真实治疗的部分折扣"结算,取最小折扣率(力度最大)+ 保留日期/项目。
 *   无折扣记录 → 不打标签(业务:无锚点则换推增值权益而非直接降价)。
 *   ⚠️ 修正 spec naive 点:原"遍历全部结算"会被免费洁牙/检查促销(100%off=0折)霸占,
 *      锚点失去"价格底线"意义。故只看 原价≥¥500(真实治疗,排基础/促销小项)且 ratio>0
 *      (排全免 comp)——锚点 = 真实治疗上谈到的最深【部分】折扣。¥500 阈值可调(口径)。
 */
@Injectable()
export class DiscountAnchorFeatureExtractor implements FeatureExtractor {
  readonly key = PersonaFeatureKey.DISCOUNT_ANCHOR;

  private static readonly MIN_ORIGINAL_CENTS = 50000; // ¥500:真实治疗,排基础/促销小项

  extract(ctx: FeatureExtractorContext): PersonaFeatureDraft | null {
    const pays = (ctx.factsByType.get(FactType.PAYMENT_RECORD) ?? []) as ActiveFact[];
    let minRatio = Infinity;
    let anchorAt: Date | null = null;
    let project: string | null = null;
    let anchorAmount = 0;
    let anchorDiscount = 0;
    let anchorFactId: string | null = null;

    for (const f of pays) {
      const c = (f.content ?? {}) as Record<string, unknown>;
      // 应收(原价)= 折扣率分母。2026-07 起 amount_cents 切实付,应收在 receivable_cents;
      // 旧事实(reparse 前)无 receivable_cents → fallback amount_cents(彼时 amount 即应收)。
      const amount = Number(c.receivable_cents ?? c.amount_cents ?? 0);
      const disc = Number(c.discount_cents ?? 0);
      if (amount < DiscountAnchorFeatureExtractor.MIN_ORIGINAL_CENTS || disc <= 0) continue; // ≥¥500 真实治疗 + 有折扣
      const ratio = Math.max(0, Math.min(1, (amount - disc) / amount));
      if (ratio <= 0) continue; // 排全免 comp(0折不是可参考的销售折扣)
      if (ratio < minRatio) {
        minRatio = ratio;
        anchorAt = f.occurredAt ?? null;
        project = String(c.settlement_project ?? '').trim() || null;
        anchorAmount = amount;
        anchorDiscount = disc;
        anchorFactId = f.id;
      }
    }
    if (!Number.isFinite(minRatio)) return null; // 从无折扣 → 无锚点

    const zhe = (minRatio * 10).toFixed(1); // 0.85 → 8.5折
    const dateStr = anchorAt ? anchorAt.toISOString().slice(0, 10) : null;
    const projStr = project ? ` · ${project}` : '';
    return {
      key: this.key,
      description: `最大折扣力度 ${zhe}折${dateStr ? ` · ${dateStr}` : ''}${projStr}`,
      score: null,
      data: {
        minDiscount: Math.round(minRatio * 100) / 100, // 折扣率 0-1
        anchorDate: dateStr,
        project,
        anchorAmountCents: anchorAmount,
        anchorDiscountCents: anchorDiscount,
      },
      evidence: { factIds: anchorFactId ? [anchorFactId] : [] },
    };
  }
}
