#!/usr/bin/env python3
"""弹窗策略数据分析 V2：仅端内购课用户 + 注册→购课天数分布"""
import os
import psycopg2
import psycopg2.extras

def get_conn():
    return psycopg2.connect(
        host="bj-postgres-16pob4sg.sql.tencentcdb.com",
        port=28591,
        user="ai_member",
        password=os.environ["PG_ONLINE_PASSWORD"],
        dbname="vala_bi"
    )

def run_sql(sql):
    conn = get_conn()
    cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
    cur.execute(sql)
    rows = cur.fetchall()
    cur.close()
    conn.close()
    return rows

# ── 端内过滤条件 ──
ENDPOINT_INNER = "o.key_from IN ('app-active-h5-0-0', 'app-sales-bj-qhm-0')"
GOODS_FILTER = "o.goods_id IN (57, 60, 63, 31, 32, 33, 54, 61)"
ORDER_STATUS_FILTER = "o.order_status IN (3, 4)"

# ======================================================================
print("=" * 70)
print("分析零：注册→购课天数分布（端内付费用户）")
print("=" * 70)

sql0 = f"""
SELECT
    o.pay_success_date::date - a.created_at::date AS days_to_purchase,
    COUNT(DISTINCT o.account_id) AS user_count
FROM bi_vala_order o
JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
WHERE o.pay_success_date IS NOT NULL
  AND o.order_status IN (3, 4)
  AND o.goods_id IN (57, 60, 63, 31, 32, 33, 54, 61)
  AND o.key_from IN ('app-active-h5-0-0', 'app-sales-bj-qhm-0')
GROUP BY days_to_purchase
ORDER BY days_to_purchase;
"""
rows0 = run_sql(sql0)

total_users0 = sum(r['user_count'] for r in rows0)
cum = 0
print(f"\n{'天数':>6} {'人数':>8} {'占比':>8} {'累计占比':>10}")
print("-" * 38)
for r in rows0:
    cum += r['user_count']
    pct = 100.0 * r['user_count'] / total_users0
    cum_pct = 100.0 * cum / total_users0
    print(f"{r['days_to_purchase']:>6} {r['user_count']:>8} {pct:>7.1f}% {cum_pct:>9.1f}%")
print(f"\n端内付费用户总数: {total_users0}")

# ── 分段统计 ──
sql0b = f"""
SELECT
    CASE
        WHEN days_to_purchase = 0 THEN '当天购买'
        WHEN days_to_purchase BETWEEN 1 AND 3 THEN '1-3天'
        WHEN days_to_purchase BETWEEN 4 AND 7 THEN '4-7天'
        WHEN days_to_purchase BETWEEN 8 AND 14 THEN '8-14天'
        WHEN days_to_purchase BETWEEN 15 AND 30 THEN '15-30天'
        ELSE '30天以上'
    END AS day_bucket,
    COUNT(DISTINCT account_id) AS user_count,
    ROUND(100.0 * COUNT(DISTINCT account_id) / SUM(COUNT(DISTINCT account_id)) OVER(), 1) AS pct
FROM (
    SELECT
        o.pay_success_date::date - a.created_at::date AS days_to_purchase,
        o.account_id
    FROM bi_vala_order o
    JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
    WHERE o.pay_success_date IS NOT NULL
      AND o.order_status IN (3, 4)
      AND o.goods_id IN (57, 60, 63, 31, 32, 33, 54, 61)
      AND o.key_from IN ('app-active-h5-0-0', 'app-sales-bj-qhm-0')
) gap
GROUP BY day_bucket
ORDER BY MIN(gap.days_to_purchase);
"""
rows0b = run_sql(sql0b)
print(f"\n{'时间段':<12} {'人数':>8} {'占比':>8}")
print("-" * 32)
cum2 = 0
for r in rows0b:
    cum2 += r['user_count']
    print(f"{r['day_bucket']:<12} {r['user_count']:>8} {r['pct']:>7}%")

# ======================================================================
print("\n" + "=" * 70)
print("分析一：购买节点分布（仅端内付费用户）")
print("=" * 70)

sql1 = f"""
WITH u00_lessons AS (
    SELECT id AS chapter_id, course_level,
           CASE course_lesson
               WHEN 'L01' THEN 1 WHEN 'L02' THEN 2 WHEN 'L03' THEN 3
               WHEN 'L04' THEN 4 WHEN 'L05' THEN 5
           END AS lesson_order
    FROM bi_level_unit_lesson WHERE course_unit = 'U00'
),
paid_orders AS (
    SELECT DISTINCT o.account_id, o.pay_success_date::date AS pay_date, o.goods_id
    FROM bi_vala_order o
    JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
    WHERE o.pay_success_date IS NOT NULL
      AND {ORDER_STATUS_FILTER}
      AND {GOODS_FILTER}
      AND {ENDPOINT_INNER}
),
paid_characters AS (
    SELECT c.id AS character_id, po.account_id, po.pay_date, po.goods_id
    FROM paid_orders po
    JOIN bi_vala_app_character c ON po.account_id = c.account_id
),
u00_done AS (
    SELECT pc.account_id, pc.pay_date, pc.goods_id, l.lesson_order, l.course_level
    FROM paid_characters pc
    JOIN (
        SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_0 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_1 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_2 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_3 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_4 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_5 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_6 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_7 WHERE play_status = 1
    ) p ON pc.character_id = p.user_id
    JOIN u00_lessons l ON p.chapter_id = l.chapter_id
    WHERE p.created_at::date <= pc.pay_date
    GROUP BY pc.account_id, pc.pay_date, pc.goods_id, l.lesson_order, l.course_level
),
best_progress AS (
    SELECT DISTINCT ON (account_id, pay_date, goods_id)
        account_id, pay_date, goods_id, lesson_order
    FROM u00_done
    ORDER BY account_id, pay_date, goods_id, lesson_order DESC
)
SELECT
    CASE
        WHEN lesson_order IS NULL THEN '学习前购买'
        WHEN lesson_order = 1 THEN 'L01之后'
        WHEN lesson_order = 2 THEN 'L02之后'
        WHEN lesson_order = 3 THEN 'L03之后'
        WHEN lesson_order = 4 THEN 'L04之后'
        WHEN lesson_order = 5 THEN 'L05之后'
    END AS purchase_node,
    CASE
        WHEN goods_id IN (57, 60, 63) THEN 'L1'
        WHEN goods_id IN (31, 32, 33, 54) THEN 'L2'
        WHEN goods_id = 61 THEN 'L1+L2'
    END AS product_level,
    COUNT(*) AS order_count,
    COUNT(DISTINCT account_id) AS user_count
FROM best_progress
GROUP BY purchase_node, product_level
UNION ALL
SELECT
    '学习前购买' AS purchase_node,
    CASE
        WHEN po.goods_id IN (57, 60, 63) THEN 'L1'
        WHEN po.goods_id IN (31, 32, 33, 54) THEN 'L2'
        WHEN po.goods_id = 61 THEN 'L1+L2'
    END AS product_level,
    COUNT(*) AS order_count,
    COUNT(DISTINCT po.account_id) AS user_count
FROM (
    SELECT DISTINCT o.account_id, o.pay_success_date::date AS pay_date, o.goods_id
    FROM bi_vala_order o
    JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
    WHERE o.pay_success_date IS NOT NULL
      AND {ORDER_STATUS_FILTER}
      AND {GOODS_FILTER}
      AND {ENDPOINT_INNER}
) po
LEFT JOIN best_progress bp ON po.account_id = bp.account_id AND po.pay_date = bp.pay_date AND po.goods_id = bp.goods_id
WHERE bp.account_id IS NULL
GROUP BY CASE
        WHEN po.goods_id IN (57, 60, 63) THEN 'L1'
        WHEN po.goods_id IN (31, 32, 33, 54) THEN 'L2'
        WHEN po.goods_id = 61 THEN 'L1+L2'
    END
ORDER BY product_level, purchase_node;
"""
rows1 = run_sql(sql1)
print(f"\n{'购买节点':<14} {'产品':<8} {'订单数':>8} {'用户数':>8}")
print("-" * 44)
for r in rows1:
    print(f"{r['purchase_node']:<14} {r['product_level']:<8} {r['order_count']:>8} {r['user_count']:>8}")

# ── 汇总 ──
sql1b = f"""
WITH u00_lessons AS (
    SELECT id AS chapter_id,
           CASE course_lesson
               WHEN 'L01' THEN 1 WHEN 'L02' THEN 2 WHEN 'L03' THEN 3
               WHEN 'L04' THEN 4 WHEN 'L05' THEN 5 END AS lesson_order
    FROM bi_level_unit_lesson WHERE course_unit = 'U00'
),
paid_orders AS (
    SELECT DISTINCT o.account_id, o.pay_success_date::date AS pay_date
    FROM bi_vala_order o JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
    WHERE o.pay_success_date IS NOT NULL AND {ORDER_STATUS_FILTER} AND {GOODS_FILTER} AND {ENDPOINT_INNER}
),
paid_characters AS (
    SELECT c.id AS character_id, po.account_id, po.pay_date
    FROM paid_orders po JOIN bi_vala_app_character c ON po.account_id = c.account_id
),
u00_done AS (
    SELECT pc.account_id, pc.pay_date, l.lesson_order
    FROM paid_characters pc
    JOIN (
        SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_0 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_1 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_2 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_3 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_4 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_5 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_6 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_7 WHERE play_status = 1
    ) p ON pc.character_id = p.user_id
    JOIN u00_lessons l ON p.chapter_id = l.chapter_id
    WHERE p.created_at::date <= pc.pay_date
    GROUP BY pc.account_id, pc.pay_date, l.lesson_order
),
best_progress AS (
    SELECT DISTINCT ON (account_id, pay_date) account_id, pay_date, lesson_order
    FROM u00_done ORDER BY account_id, pay_date, lesson_order DESC
)
SELECT
    CASE
        WHEN lesson_order IS NULL THEN '学习前购买'
        WHEN lesson_order = 1 THEN 'L01之后'
        WHEN lesson_order = 2 THEN 'L02之后'
        WHEN lesson_order = 3 THEN 'L03之后'
        WHEN lesson_order = 4 THEN 'L04之后'
        WHEN lesson_order = 5 THEN 'L05之后'
    END AS purchase_node,
    COUNT(*) AS order_count,
    COUNT(DISTINCT account_id) AS user_count
FROM best_progress
GROUP BY purchase_node
UNION ALL
SELECT '学习前购买', COUNT(*), COUNT(DISTINCT po.account_id)
FROM (
    SELECT DISTINCT o.account_id, o.pay_success_date::date AS pay_date
    FROM bi_vala_order o JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
    WHERE o.pay_success_date IS NOT NULL AND {ORDER_STATUS_FILTER} AND {GOODS_FILTER} AND {ENDPOINT_INNER}
) po
LEFT JOIN best_progress bp ON po.account_id = bp.account_id AND po.pay_date = bp.pay_date
WHERE bp.account_id IS NULL
ORDER BY purchase_node;
"""
rows1b = run_sql(sql1b)
print(f"\n{'购买节点':<14} {'订单数':>8} {'用户数':>8} {'占比':>8}")
print("-" * 44)
total_orders = sum(r['order_count'] for r in rows1b)
for r in rows1b:
    pct = 100.0 * r['user_count'] / sum(x['user_count'] for x in rows1b)
    print(f"{r['purchase_node']:<14} {r['order_count']:>8} {r['user_count']:>8} {pct:>7.1f}%")
print(f"\n端内付费总订单: {total_orders}")

# ======================================================================
print("\n" + "=" * 70)
print("分析二：峰值后用户 —— 学完U00但未购（端内购买为判断标准）")
print("=" * 70)

sql2 = f"""
WITH u00_lessons AS (
    SELECT id AS chapter_id,
           CASE course_lesson
               WHEN 'L01' THEN 1 WHEN 'L02' THEN 2 WHEN 'L03' THEN 3
               WHEN 'L04' THEN 4 WHEN 'L05' THEN 5 END AS lesson_order
    FROM bi_level_unit_lesson WHERE course_unit = 'U00'
),
user_u00_progress AS (
    SELECT DISTINCT a.id AS account_id, l.lesson_order
    FROM bi_vala_app_account a
    JOIN bi_vala_app_character c ON a.id = c.account_id
    JOIN (
        SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_0 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_1 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_2 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_3 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_4 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_5 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_6 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_7 WHERE play_status = 1
    ) p ON c.id = p.user_id
    JOIN u00_lessons l ON p.chapter_id = l.chapter_id
    WHERE a.status = 1 AND a.deleted_at IS NULL
),
user_max_progress AS (
    SELECT account_id, MAX(lesson_order) AS max_lesson
    FROM user_u00_progress GROUP BY account_id
),
u00_completers AS (
    SELECT account_id FROM user_max_progress WHERE max_lesson = 5
),
-- 端内付费用户
paid_inner AS (
    SELECT DISTINCT o.account_id
    FROM bi_vala_order o
    JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
    WHERE o.pay_success_date IS NOT NULL
      AND o.order_status IN (3, 4)
      AND o.goods_id IN (57, 60, 63, 31, 32, 33, 54, 61)
      AND o.key_from IN ('app-active-h5-0-0', 'app-sales-bj-qhm-0')
)
SELECT
    '学完U00全部5课' AS user_group,
    COUNT(*) AS total_users,
    COUNT(*) FILTER (WHERE pu.account_id IS NOT NULL) AS paid_users,
    COUNT(*) FILTER (WHERE pu.account_id IS NULL) AS unpaid_users,
    ROUND(100.0 * COUNT(*) FILTER (WHERE pu.account_id IS NOT NULL) / COUNT(*), 1) AS paid_rate
FROM u00_completers uc
LEFT JOIN paid_inner pu ON uc.account_id = pu.account_id;
"""
rows2 = run_sql(sql2)
for r in rows2:
    print(f"\n总用户数: {r['total_users']}, 已端内付费: {r['paid_users']}, 未端内付费: {r['unpaid_users']}, 端内付费率: {r['paid_rate']}%")

# ======================================================================
print("\n" + "=" * 70)
print("分析三：各断点用户规模 + 端内付费率")
print("=" * 70)

sql3 = f"""
WITH u00_lessons AS (
    SELECT id AS chapter_id, course_level,
           CASE course_lesson
               WHEN 'L01' THEN 1 WHEN 'L02' THEN 2 WHEN 'L03' THEN 3
               WHEN 'L04' THEN 4 WHEN 'L05' THEN 5 END AS lesson_order
    FROM bi_level_unit_lesson WHERE course_unit = 'U00'
),
user_u00_progress AS (
    SELECT a.id AS account_id, l.course_level, l.lesson_order
    FROM bi_vala_app_account a
    JOIN bi_vala_app_character c ON a.id = c.account_id
    JOIN (
        SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_0 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_1 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_2 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_3 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_4 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_5 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_6 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_7 WHERE play_status = 1
    ) p ON c.id = p.user_id
    JOIN u00_lessons l ON p.chapter_id = l.chapter_id
    WHERE a.status = 1 AND a.deleted_at IS NULL
    GROUP BY a.id, l.course_level, l.lesson_order
),
user_max_per_level AS (
    SELECT account_id, course_level, MAX(lesson_order) AS max_lesson
    FROM user_u00_progress GROUP BY account_id, course_level
),
paid_inner AS (
    SELECT DISTINCT o.account_id
    FROM bi_vala_order o
    JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
    WHERE o.pay_success_date IS NOT NULL
      AND o.order_status IN (3, 4)
      AND o.goods_id IN (57, 60, 63, 31, 32, 33, 54, 61)
      AND o.key_from IN ('app-active-h5-0-0', 'app-sales-bj-qhm-0')
)
SELECT
    course_level, max_lesson,
    COUNT(*) AS user_count,
    COUNT(*) FILTER (WHERE pu.account_id IS NOT NULL) AS paid_count,
    ROUND(100.0 * COUNT(*) FILTER (WHERE pu.account_id IS NOT NULL) / COUNT(*), 1) AS paid_rate
FROM user_max_per_level um
LEFT JOIN paid_inner pu ON um.account_id = pu.account_id
GROUP BY course_level, max_lesson
ORDER BY course_level, max_lesson;
"""
rows3 = run_sql(sql3)
print(f"\n{'Level':<6} {'最大完成':<10} {'用户数':>8} {'端内付费':>10} {'端内付费率':>10}")
print("-" * 48)
for r in rows3:
    pct = 100.0 * r['paid_count'] / r['user_count']
    print(f"{r['course_level']:<6} L{r['max_lesson']:02d}      {r['user_count']:>8} {r['paid_count']:>10} {pct:>9.1f}%")

# ======================================================================
print("\n" + "=" * 70)
print("分析四：到达各lesson的端内付费转化率")
print("=" * 70)

sql4 = f"""
WITH u00_lessons AS (
    SELECT id AS chapter_id, course_level,
           CASE course_lesson
               WHEN 'L01' THEN 1 WHEN 'L02' THEN 2 WHEN 'L03' THEN 3
               WHEN 'L04' THEN 4 WHEN 'L05' THEN 5 END AS lesson_order
    FROM bi_level_unit_lesson WHERE course_unit = 'U00'
),
user_u00_progress AS (
    SELECT a.id AS account_id, l.course_level, l.lesson_order
    FROM bi_vala_app_account a
    JOIN bi_vala_app_character c ON a.id = c.account_id
    JOIN (
        SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_0 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_1 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_2 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_3 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_4 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_5 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_6 WHERE play_status = 1
        UNION ALL SELECT user_id, chapter_id, created_at FROM bi_user_chapter_play_record_7 WHERE play_status = 1
    ) p ON c.id = p.user_id
    JOIN u00_lessons l ON p.chapter_id = l.chapter_id
    WHERE a.status = 1 AND a.deleted_at IS NULL
    GROUP BY a.id, l.course_level, l.lesson_order
),
paid_inner AS (
    SELECT DISTINCT o.account_id
    FROM bi_vala_order o
    JOIN bi_vala_app_account a ON o.account_id = a.id AND a.status = 1
    WHERE o.pay_success_date IS NOT NULL
      AND o.order_status IN (3, 4)
      AND o.goods_id IN (57, 60, 63, 31, 32, 33, 54, 61)
      AND o.key_from IN ('app-active-h5-0-0', 'app-sales-bj-qhm-0')
)
SELECT
    up.course_level,
    up.lesson_order AS reached_lesson,
    COUNT(DISTINCT up.account_id) AS reached_users,
    COUNT(DISTINCT pu.account_id) AS paid_users,
    ROUND(100.0 * COUNT(DISTINCT pu.account_id) / COUNT(DISTINCT up.account_id), 1) AS conversion_rate
FROM user_u00_progress up
LEFT JOIN paid_inner pu ON up.account_id = pu.account_id
GROUP BY up.course_level, up.lesson_order
ORDER BY up.course_level, up.lesson_order;
"""
rows4 = run_sql(sql4)
print(f"\n{'Level':<6} {'到达':<10} {'到达人数':>8} {'端内付费':>10} {'端内转化率':>10}")
print("-" * 48)
for r in rows4:
    print(f"{r['course_level']:<6} L{r['reached_lesson']:02d}      {r['reached_users']:>8} {r['paid_users']:>10} {r['conversion_rate']:>9}%")

print("\n✅ 全部分析完成")
