#!/usr/bin/env python3
"""
付费+周活用户的设备类型分布分析
设备分类：手机 / 学习机 / 平板电脑 / 无设备记录
"""
import os
import psycopg2

# Load secrets
secrets = {}
with open(os.path.join(os.path.dirname(__file__), '..', 'secrets.env')) as f:
    for line in f:
        line = line.strip()
        if line and not line.startswith('#') and '=' in line:
            key, val = line.split('=', 1)
            val = val.strip("'").strip('"')
            secrets[key] = val

conn = psycopg2.connect(
    host="bj-postgres-16pob4sg.sql.tencentcdb.com",
    port=28591,
    user="ai_member",
    password=secrets['PG_ONLINE_PASSWORD'],
    database="vala_bi"
)
cur = conn.cursor()

end_date = '2026-05-26'
start_date = '2026-05-19'
print(f"周活窗口: {start_date} ~ {end_date}")

# Step 1: 付费用户
print("\n=== Step 1: 付费用户 ===")
cur.execute("""
    SELECT DISTINCT o.account_id
    FROM bi_vala_order o
    INNER JOIN bi_vala_app_account a ON o.account_id = a.id
    WHERE a.status = 1 AND a.deleted_at IS NULL
      AND o.order_status IN (3, 4)
      AND o.pay_success_date IS NOT NULL AND o.deleted_at IS NULL
""")
paid_users = {row[0] for row in cur.fetchall()}
print(f"付费用户数: {len(paid_users)}")

# Step 2: 周活用户
print("\n=== Step 2: 周活用户 ===")
weekly_active_users = set()
for i in range(8):
    cur.execute(f"""
        SELECT DISTINCT cpr.user_id
        FROM bi_user_chapter_play_record_{i} cpr
        WHERE cpr.play_status = 1
          AND cpr.created_at >= %s AND cpr.created_at < %s::date + interval '1 day'
          AND cpr.deleted_at IS NULL
    """, (start_date, end_date))
    for row in cur.fetchall():
        weekly_active_users.add(row[0])

print("  获取角色->账号映射...")
weekly_active_accounts = set()
user_ids = list(weekly_active_users)
batch_size = 1000
for i in range(0, len(user_ids), batch_size):
    batch = user_ids[i:i+batch_size]
    placeholders = ','.join(['%s'] * len(batch))
    cur.execute(f"""
        SELECT DISTINCT c.account_id FROM bi_vala_app_character c
        WHERE c.id IN ({placeholders}) AND c.deleted_at IS NULL
    """, batch)
    for row in cur.fetchall():
        if row[0]:
            weekly_active_accounts.add(row[0])
print(f"周活角色数: {len(weekly_active_users)}, account数: {len(weekly_active_accounts)}")

# Step 3: 交集
target_accounts = paid_users & weekly_active_accounts
print(f"\n=== 付费+周活交集: {len(target_accounts)} ===")

# Step 4: 设备信息
print("\n=== Step 4: 设备信息 ===")
target_ids = list(target_accounts)
device_data = {}
batch_size = 500
for i in range(0, len(target_ids), batch_size):
    batch = target_ids[i:i+batch_size]
    placeholders = ','.join(['%s'] * len(batch))
    cur.execute(f"""
        SELECT DISTINCT ON (account_id) account_id, device, device_os
        FROM account_detail_info
        WHERE account_id IN ({placeholders}) AND device_os IS NOT NULL AND device_os != ''
        ORDER BY account_id, created_time DESC
    """, batch)
    for row in cur.fetchall():
        device_data[row[0]] = {'device': row[1], 'device_os': row[2]}

print(f"有设备记录: {len(device_data)}, 无设备记录: {len(target_accounts) - len(device_data)}")

# Step 5: 分类
print("\n=== Step 5: 分类 ===")

def classify_device(device, device_os):
    d = (device or '').strip()
    dl = d.lower()
    os = (device_os or '').strip()

    if os.startswith('iPad'):
        return '平板电脑'
    if os.startswith('iOS'):
        return '手机'

    if os.startswith('Android'):
        # === 学习机品牌 ===
        lm_patterns = [
            'iflytek', 'xiaodu', 'seewo', 'eebbk',
        ]
        for p in lm_patterns:
            if p in dl:
                return '学习机'
        # boe 京东方
        if dl.startswith('boe'):
            return '学习机'
        # ZYB
        if dl.startswith('zyb'):
            return '学习机'
        # 优学派
        if 'youxuepai' in dl:
            return '学习机'
        # 读书郎
        if 'readboy' in dl:
            return '学习机'
        # 乐乐课堂
        if 'leleketang' in dl:
            return '学习机'
        # alps / rockchip 平台学习机
        if dl.startswith('alps') or dl.startswith('rockchip'):
            return '学习机'
        # 其他已知学习机品牌
        other_lm = ['cvte', 'jzx', 'cmdc', 'incar', 'tdtech', 'thtf', 'shuowang',
                     'ptac', 'emdoor', 'hra', 'inspur', 'ktc', 'miaowang',
                     'wancheng', 'ployer', 'robint', 'skyth',
                     'a127cs', 'a127ch', 'a140', 'b127cs', 'b127ch',
                     'elink', 'hht', 'huaruian', 'jhkj', 'knc', 'mfyd',
                     'm66_pro', 'svision', 'xh-258', 'yfd', 'zyl',
                     'conquest', 'ereneben', 'tianyi',
                     'tablepc', 'aigo']
        for p in other_lm:
            if dl.startswith(p):
                return '学习机'
        # UNISOC learning devices
        if dl.startswith('unisoc') and ('k-c22' in dl or 'p600' in dl or 't600' in dl or 'kimi' in dl):
            return '学习机'
        # TCL learning devices
        if dl.startswith('tcl') and ('ycxy' in dl or 'zc30' in dl):
            return '学习机'
        # Generic Android device names
        if dl.startswith('android ') or dl.startswith('5g ') or dl.startswith('- ') or dl.startswith('unknown') or dl.startswith('v10') or dl.startswith('yt '):
            return '学习机'
        if dl.startswith('e3 ') or dl.startswith('e3_'):
            return '学习机'
        if dl.startswith('mid ') or dl.startswith('mid_'):
            return '学习机'
        if dl.startswith('tal ') or dl.startswith('tal_'):
            return '学习机'
        if dl.startswith('zte ') and ('w' in d.split()[-1].lower() if ' ' in d else True):
            return '学习机'

        # === 平板电脑 ===
        # Huawei/Honor tablets (W model = WiFi)
        if (dl.startswith('huawei') or dl.startswith('honor')) and ('-w' in dl):
            return '平板电脑'
        # Lenovo tablets
        if dl.startswith('lenovo') and 'tb' in dl:
            return '平板电脑'
        # Samsung tablets
        if dl.startswith('samsung') and ('sm-t' in dl or 'sm-x' in dl):
            return '平板电脑'
        # Xiaomi Pad
        if dl.startswith('xiaomi') and ('pad' in dl or 'mi pad' in dl):
            return '平板电脑'
        if 'mi pad' in dl:
            return '平板电脑'
        # Alldocube tablets
        if 'iplay' in dl or 'alldocube' in dl:
            return '平板电脑'
        # Teclast tablets
        if dl.startswith('teclast'):
            return '平板电脑'
        # Hisense tablets
        if 'familymobilepad' in dl:
            return '平板电脑'
        if dl.startswith('hisense') and '32x8n' in dl:
            return '平板电脑'
        # CUBE / Lecoo tablets
        if dl.startswith('cube') or dl.startswith('lecoo'):
            return '平板电脑'

        # === 其余Android默认为手机 ===
        return '手机'

    # 无OS信息，尝试从device名推断
    if dl.startswith('ipad'):
        return '平板电脑'
    return '手机'

# 分类统计
categories = {'手机': 0, '学习机': 0, '平板电脑': 0, '无设备记录': 0}
cat_users = {'手机': set(), '学习机': set(), '平板电脑': set(), '无设备记录': set()}

for aid in target_accounts:
    if aid in device_data:
        cat = classify_device(device_data[aid]['device'], device_data[aid]['device_os'])
    else:
        cat = '无设备记录'
    categories[cat] += 1
    cat_users[cat].add(aid)

print(f"\n{'='*60}")
print(f"📱 付费+周活用户设备分布（近7天: {start_date}~{end_date}）")
print(f"{'='*60}")
print(f"总用户数: {len(target_accounts)}")
print()
for cat in ['手机', '学习机', '平板电脑', '无设备记录']:
    pct = categories[cat] / len(target_accounts) * 100
    print(f"  {cat}: {categories[cat]} 人 ({pct:.1f}%)")

has_device = categories['手机'] + categories['学习机'] + categories['平板电脑']
print(f"\n--- 仅看有设备记录的 {has_device} 人 ---")
for cat in ['手机', '学习机', '平板电脑']:
    pct = categories[cat] / has_device * 100
    print(f"  {cat}: {categories[cat]} 人 ({pct:.1f}%)")

# === 详细拆分 ===
print(f"\n{'='*60}")
print(f"📱 设备子分类详细分布")
print(f"{'='*60}")

brand_stats = {}
for aid in target_accounts:
    if aid in device_data:
        d = device_data[aid]
        os_name = (d['device_os'] or '').strip()
        dev_name = (d['device'] or 'unknown').strip()
        dl = dev_name.lower()

        if os_name.startswith('iOS'):
            brand = 'iPhone'
        elif os_name.startswith('iPad'):
            brand = 'iPad'
        elif 'iflytek' in dl:
            brand = '讯飞(iFLYTEK)'
        elif 'xiaodu' in dl:
            brand = '小度'
        elif 'seewo' in dl:
            brand = '希沃'
        elif 'eebbk' in dl:
            brand = '步步高'
        elif dl.startswith('boe'):
            brand = '京东方'
        elif dl.startswith('zyb'):
            brand = 'ZYB'
        elif 'youxuepai' in dl:
            brand = '优学派'
        elif 'readboy' in dl:
            brand = '读书郎'
        elif dl.startswith('alps'):
            brand = 'alps(MTK)'
        elif dl.startswith('rockchip'):
            brand = 'rockchip(RK)'
        elif dl.startswith('huawei'):
            brand = '华为'
        elif dl.startswith('honor'):
            brand = '荣耀'
        elif dl.startswith('xiaomi'):
            brand = '小米'
        elif dl.startswith('vivo'):
            brand = 'vivo'
        elif dl.startswith('oppo'):
            brand = 'OPPO'
        elif dl.startswith('oneplus'):
            brand = '一加'
        elif dl.startswith('samsung'):
            brand = '三星'
        elif dl.startswith('realme'):
            brand = 'realme'
        elif dl.startswith('lenovo'):
            brand = '联想'
        elif dl.startswith('meizu'):
            brand = '魅族'
        elif dl.startswith('motorola'):
            brand = 'motorola'
        elif dl.startswith('nubia'):
            brand = 'nubia'
        else:
            brand = dev_name.split()[0]
        key = brand
    else:
        key = '无设备记录'

    brand_stats[key] = brand_stats.get(key, 0) + 1

sorted_brands = sorted(brand_stats.items(), key=lambda x: -x[1])
for brand, count in sorted_brands[:50]:
    pct = count / len(target_accounts) * 100
    print(f"  {brand}: {count} ({pct:.1f}%)")

# 平板电脑品牌拆分
print(f"\n--- 📱 平板电脑内部拆分 ({categories['平板电脑']}人) ---")
tb = {}
for aid in cat_users['平板电脑']:
    if aid in device_data:
        os_name = (device_data[aid]['device_os'] or '').strip()
        if os_name.startswith('iPad'):
            brand = 'iPad'
        else:
            dl = (device_data[aid]['device'] or '').strip().lower()
            if dl.startswith('huawei'):
                brand = '华为平板'
            elif dl.startswith('honor'):
                brand = '荣耀平板'
            elif dl.startswith('lenovo'):
                brand = '联想平板'
            elif dl.startswith('samsung'):
                brand = '三星平板'
            elif dl.startswith('xiaomi') or 'mi pad' in dl:
                brand = '小米平板'
            elif 'iplay' in dl:
                brand = 'ALLDOCUBE'
            elif dl.startswith('teclast'):
                brand = 'Teclast'
            elif 'familymobilepad' in dl or (dl.startswith('hisense') and '32x8n' in dl):
                brand = '海信平板'
            elif dl.startswith('cube') or dl.startswith('lecoo'):
                brand = '其他平板'
            else:
                brand = '其他平板'
        tb[brand] = tb.get(brand, 0) + 1
for b, c in sorted(tb.items(), key=lambda x: -x[1]):
    print(f"  {b}: {c}")

# 学习机品牌拆分
print(f"\n--- 📚 学习机内部拆分 ({categories['学习机']}人) ---")
lm = {}
for aid in cat_users['学习机']:
    if aid in device_data:
        dl = (device_data[aid]['device'] or '').strip().lower()
        if 'iflytek' in dl:
            brand = '讯飞'
        elif 'xiaodu' in dl:
            brand = '小度'
        elif 'seewo' in dl:
            brand = '希沃'
        elif 'eebbk' in dl:
            brand = '步步高'
        elif dl.startswith('boe'):
            brand = '京东方'
        elif dl.startswith('zyb'):
            brand = 'ZYB'
        elif 'youxuepai' in dl:
            brand = '优学派'
        elif 'readboy' in dl:
            brand = '读书郎'
        elif dl.startswith('alps'):
            brand = 'alps平台'
        elif dl.startswith('rockchip'):
            brand = 'rockchip平台'
        elif 'leleketang' in dl:
            brand = '乐乐课堂'
        else:
            # 取第一个词
            brand = dl.split()[0] if dl else 'unknown'
        lm[brand] = lm.get(brand, 0) + 1
for b, c in sorted(lm.items(), key=lambda x: -x[1]):
    print(f"  {b}: {c}")

# 手机品牌拆分
print(f"\n--- 📞 手机内部拆分 ({categories['手机']}人) ---")
ph = {}
for aid in cat_users['手机']:
    if aid in device_data:
        d = device_data[aid]
        os_name = (d['device_os'] or '').strip()
        dev_name = (d['device'] or '').strip()
        dl = dev_name.lower()
        if os_name.startswith('iOS'):
            brand = 'iPhone'
        elif dl.startswith('huawei'):
            brand = '华为手机'
        elif dl.startswith('honor'):
            brand = '荣耀手机'
        elif dl.startswith('xiaomi'):
            brand = '小米'
        elif dl.startswith('vivo'):
            brand = 'vivo'
        elif dl.startswith('oppo'):
            brand = 'OPPO'
        elif dl.startswith('oneplus'):
            brand = '一加'
        elif dl.startswith('samsung'):
            brand = '三星'
        elif dl.startswith('realme'):
            brand = 'realme'
        elif dl.startswith('meizu'):
            brand = '魅族'
        elif dl.startswith('motorola'):
            brand = 'motorola'
        elif dl.startswith('nubia'):
            brand = 'nubia'
        elif dl.startswith('lenovo'):
            brand = '联想手机'
        elif dl.startswith('zte'):
            brand = '中兴'
        else:
            brand = dl.split()[0] if dl else 'other'
        ph[brand] = ph.get(brand, 0) + 1
for b, c in sorted(ph.items(), key=lambda x: -x[1]):
    print(f"  {b}: {c}")

cur.close()
conn.close()
