#!/usr/bin/env python3
"""
分析「是否添加班主任微信」与「退款率」的相关性
数据源：
- 加微判断：vala_class.public.student_info（vala_account_id 存在即已加微）
- 订单数据：vala_bi.bi_vala_order + bi_vala_app_account + bi_refund_order
"""
import psycopg2
import os
from collections import defaultdict

PG_HOST = "bj-postgres-16pob4sg.sql.tencentcdb.com"
PG_PORT = 28591
PG_USER = "ai_member"
PG_PASS = os.environ.get("PG_ONLINE_PASSWORD", "")

def get_conn(db):
    return psycopg2.connect(host=PG_HOST, port=PG_PORT, user=PG_USER, password=PG_PASS, dbname=db)

print("=" * 70)
print("📊 是否添加班主任微信 vs 退款率 相关性分析")
print("=" * 70)

# ============================================================
# Step 1: 从 vala_class 获取所有已加微的 account_id
# ============================================================
print("\n[1/5] 获取已加班主任微信的用户列表...")
conn_class = get_conn("vala_class")
cur = conn_class.cursor()
cur.execute("""
    SELECT DISTINCT vala_account_id
    FROM student_info
    WHERE vala_account_id IS NOT NULL
""")
wechat_accounts = {row[0] for row in cur.fetchall()}
cur.close()
conn_class.close()
print(f"  已加微用户数: {len(wechat_accounts):,}")

# ============================================================
# Step 2: 获取所有购课用户（非测试账号）
# ============================================================
print("\n[2/5] 获取购课用户及订单数据...")
conn_bi = get_conn("vala_bi")
cur = conn_bi.cursor()

# 获取所有非测试账号的购课订单
cur.execute("""
    SELECT 
        o.account_id,
        o.id AS order_id,
        o.trade_no,
        o.out_trade_no,
        o.order_status,
        o.pay_amount_int,
        o.pay_success_date,
        o.key_from
    FROM bi_vala_order o
    INNER JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1 AND a.deleted_at IS NULL
    WHERE o.pay_success_date IS NOT NULL
      AND o.order_status IN (3, 4)
""")
orders = cur.fetchall()
print(f"  购课订单数: {len(orders):,}")

# 按 account_id 分组
user_orders = defaultdict(list)
for row in orders:
    user_orders[row[0]].append({
        'order_id': row[1],
        'trade_no': row[2],
        'out_trade_no': row[3],
        'order_status': row[4],
        'pay_amount_int': row[5],
        'pay_success_date': row[6],
        'key_from': row[7]
    })

buying_users = set(user_orders.keys())
print(f"  购课用户数（去重）: {len(buying_users):,}")

# ============================================================
# Step 3: 获取所有退费记录
# ============================================================
print("\n[3/5] 获取退费记录...")
cur.execute("""
    SELECT trade_no, out_trade_no, refund_amount, status
    FROM bi_refund_order
    WHERE status = 3
""")
refund_rows = cur.fetchall()
print(f"  退费记录数: {len(refund_rows):,}")

# 构建退费记录列表：每条记录 (trade_no, out_trade_no, amount_fen)
refund_records = []
for row in refund_rows:
    trade_no, out_trade_no, amount, status = row
    amount_fen = int(float(amount) * 100) if amount else 0
    refund_records.append((trade_no, out_trade_no, amount_fen))

cur.close()
conn_bi.close()

# ============================================================
# Step 4: 判断每笔订单是否退费
# ============================================================
print("\n[4/5] 计算退费情况...")

def get_refund_info(order):
    """判断订单是否退费，返回 (is_refunded, total_refund_amount_fen)"""
    # order_status=4 → 直接判定退费
    if order['order_status'] == 4:
        # 计算退费金额：匹配所有退费记录
        total = 0
        tn = order['trade_no']
        otn = order['out_trade_no']
        seen = set()  # 避免同一笔退费记录重复计算
        for i, (r_tn, r_otn, r_amt) in enumerate(refund_records):
            if (r_tn and r_tn == tn) or (r_otn and r_otn == otn):
                if i not in seen:
                    seen.add(i)
                    total += r_amt
        return True, total
    # order_status=3 → 需在退费表中存在 status=3 的记录
    if order['order_status'] == 3:
        total = 0
        tn = order['trade_no']
        otn = order['out_trade_no']
        seen = set()
        for i, (r_tn, r_otn, r_amt) in enumerate(refund_records):
            if (r_tn and r_tn == tn) or (r_otn and r_otn == otn):
                if i not in seen:
                    seen.add(i)
                    total += r_amt
        if total > 0:
            return True, total
    return False, 0

# 按用户统计
wechat_stats = {
    'users': set(),
    'total_orders': 0,
    'refunded_orders': 0,
    'total_gmv': 0,
    'total_refund_amount': 0,
}
no_wechat_stats = {
    'users': set(),
    'total_orders': 0,
    'refunded_orders': 0,
    'total_gmv': 0,
    'total_refund_amount': 0,
}

for account_id, order_list in user_orders.items():
    has_wechat = account_id in wechat_accounts
    target = wechat_stats if has_wechat else no_wechat_stats
    target['users'].add(account_id)
    
    for order in order_list:
        target['total_orders'] += 1
        target['total_gmv'] += order['pay_amount_int']
        
        is_ref, refund_amt = get_refund_info(order)
        if is_ref:
            target['refunded_orders'] += 1
            target['total_refund_amount'] += refund_amt

# ============================================================
# Step 5: 输出结果
# ============================================================
print("\n[5/5] 输出分析结果...")
print("\n" + "=" * 70)
print("📊 分析结果")
print("=" * 70)

def print_stats(label, stats):
    users = len(stats['users'])
    orders = stats['total_orders']
    refunded = stats['refunded_orders']
    gmv = stats['total_gmv'] / 100
    refund_amt = stats['total_refund_amount'] / 100
    gsv = gmv - refund_amt
    
    refund_rate = (refunded / orders * 100) if orders > 0 else 0
    refund_amount_rate = (refund_amt / gmv * 100) if gmv > 0 else 0
    avg_orders_per_user = orders / users if users > 0 else 0
    
    print(f"\n{'─' * 50}")
    print(f"  {label}")
    print(f"{'─' * 50}")
    print(f"  购课用户数:        {users:>8,} 人")
    print(f"  订单总数:          {orders:>8,} 单")
    print(f"  人均订单数:        {avg_orders_per_user:>8.1f} 单/人")
    print(f"  退费订单数:        {refunded:>8,} 单")
    print(f"  退费率(按订单):    {refund_rate:>8.1f}%")
    print(f"  GMV:               {gmv:>10,.0f} 元")
    print(f"  退费金额:          {refund_amt:>10,.0f} 元")
    print(f"  GSV:               {gsv:>10,.0f} 元")
    print(f"  退费金额占比:      {refund_amount_rate:>8.1f}%")
    return {
        'users': users, 'orders': orders, 'refunded': refunded,
        'refund_rate': refund_rate, 'gmv': gmv, 'refund_amt': refund_amt,
        'gsv': gsv, 'refund_amount_rate': refund_amount_rate
    }

w = print_stats("✅ 已加班主任微信", wechat_stats)
n = print_stats("❌ 未加班主任微信", no_wechat_stats)

# 对比
print(f"\n{'=' * 70}")
print("📊 对比分析")
print(f"{'=' * 70}")
print(f"  退费率差异:        已加微 {w['refund_rate']:.1f}%  vs  未加微 {n['refund_rate']:.1f}%")
diff = w['refund_rate'] - n['refund_rate']
print(f"  退费率差值:        {diff:+.1f} 个百分点")
if n['refund_rate'] > 0:
    ratio = w['refund_rate'] / n['refund_rate']
    print(f"  退费率比值:        已加微是未加微的 {ratio:.2f} 倍")

print(f"\n  退费金额占比差异:  已加微 {w['refund_amount_rate']:.1f}%  vs  未加微 {n['refund_amount_rate']:.1f}%")

# 用户维度退费率（有退费的用户 / 总用户）
wechat_refund_users = sum(1 for uid in wechat_stats['users'] 
    if any(get_refund_info(o)[0] for o in user_orders[uid]))
no_wechat_refund_users = sum(1 for uid in no_wechat_stats['users'] 
    if any(get_refund_info(o)[0] for o in user_orders[uid]))

print(f"\n  用户维度退费率:")
print(f"    已加微: {wechat_refund_users}/{len(wechat_stats['users'])} = {wechat_refund_users/len(wechat_stats['users'])*100:.1f}%")
if len(no_wechat_stats['users']) > 0:
    print(f"    未加微: {no_wechat_refund_users}/{len(no_wechat_stats['users'])} = {no_wechat_refund_users/len(no_wechat_stats['users'])*100:.1f}%")

print(f"\n{'=' * 70}")
print("分析完成 ✅")
