#!/usr/bin/env python3
"""Build the reproducible lifetime aggregate-analysis notebook with nbformat."""

from pathlib import Path

import nbformat as nbf


OUTPUT_DIR = Path(__file__).resolve().parent
NOTEBOOK = OUTPUT_DIR / "saidi-airport-feature-usage-analysis.ipynb"


def main() -> None:
    notebook = nbf.v4.new_notebook()
    notebook["metadata"]["kernelspec"] = {"display_name": "Python 3", "language": "python", "name": "python3"}
    notebook["metadata"]["language_info"] = {"name": "python", "version": "3"}
    notebook["cells"] = [
        nbf.v4.new_markdown_cell(
            """# 赛迪与首都机场上线以来功能使用分析

## tl;dr

- 主口径从首个有效订单日统计至 2026-08-03：首都机场 2026-01-20 起累计 895,908 单；赛迪 2026-01-18 起累计 145,955 单。
- 机场消费机占 89.43%、外部订单接入占 10.57%；赛迪消费机占 81.09%、闸机占 18.55%、线上订餐仅占 0.36%。
- 机场累计报表导出 1,379 次但集中于 1 位操作者；赛迪累计限额拦截 210 次，257 条取餐记录全部停留在“备餐中”。
- 近30天只用于观察变化，不能替代项目全生命周期结构。数据库业务表也不能替代页面点击流。"""
        ),
        nbf.v4.new_markdown_cell(
            """## Context & Methods

- 可观察上线起点：首个满足 `pay_status=20 AND order_status=30 AND is_delete=0 AND user_id>0` 的订单 `meal_date`。
- 起点代表数据库开始出现有效业务，不等于合同上线、部署或验收日期。
- 有效订单按 `meal_date` 归属；订单流水为 `total_price` 合计，不等于收入或回款。
- 近30天（2026-07-05 至 2026-08-03）与前30天（2026-06-05 至 2026-07-04）只作趋势补充。
- 本目录只保存项目级聚合，不保存数据库凭据、人员、订单或日志明细。"""
        ),
        nbf.v4.new_code_cell(
            """from pathlib import Path
import pandas as pd
import matplotlib.pyplot as plt

ROOT = Path.cwd()
project_meta = pd.read_csv(ROOT / 'project_meta.csv')
order_summary = pd.read_csv(ROOT / 'order_summary.csv')
channel_mix = pd.read_csv(ROOT / 'channel_mix.csv')
payment_mix = pd.read_csv(ROOT / 'payment_mix.csv')
meal_mix = pd.read_csv(ROOT / 'meal_mix.csv')
monthly_usage = pd.read_csv(ROOT / 'monthly_usage.csv')
feature_activity = pd.read_csv(ROOT / 'feature_activity.csv')
management_activity = pd.read_csv(ROOT / 'management_activity.csv')
restaurant_rank = pd.read_csv(ROOT / 'restaurant_rank.csv')
user_frequency = pd.read_csv(ROOT / 'user_frequency.csv')
data_quality = pd.read_csv(ROOT / 'data_quality.csv')
PROJECT_LABELS = {'airport': '首都机场', 'saidi': '赛迪物业'}
project_meta[['project_key','observable_launch_date','observable_launch_definition']]"""
        ),
        nbf.v4.new_markdown_cell("## Results\n\n### 1. 上线以来规模与近期趋势"),
        nbf.v4.new_code_cell(
            """rows = []
for key in ['airport', 'saidi']:
    life = order_summary[(order_summary.project_key == key) & (order_summary.period == '上线以来')].iloc[0]
    current = order_summary[(order_summary.project_key == key) & (order_summary.period == '近30天')].iloc[0]
    previous = order_summary[(order_summary.project_key == key) & (order_summary.period == '前30天')].iloc[0]
    rows.append({
        '项目': PROJECT_LABELS[key], '可观察上线起点': life.start_date,
        '累计订单': int(life.orders), '累计活跃用户': int(life.active_users),
        '累计人均订单': life.orders_per_user, '累计流水': life.amount,
        '近30天订单': int(current.orders), '近30天订单环比': current.orders / previous.orders - 1,
        '近30天用户环比': current.active_users / previous.active_users - 1,
    })
summary_view = pd.DataFrame(rows)
display_view = summary_view.copy()
display_view['累计流水'] = display_view['累计流水'].map('¥{:,.2f}'.format)
display_view['累计人均订单'] = display_view['累计人均订单'].map('{:.2f}'.format)
display_view['近30天订单环比'] = display_view['近30天订单环比'].map('{:+.2%}'.format)
display_view['近30天用户环比'] = display_view['近30天用户环比'].map('{:+.2%}'.format)
display_view"""
        ),
        nbf.v4.new_markdown_cell("### 2. 上线以来功能渠道结构"),
        nbf.v4.new_code_cell(
            """lifetime_channels = channel_mix[channel_mix.period == '上线以来'].copy()
lifetime_channels['项目'] = lifetime_channels.project_key.map(PROJECT_LABELS)
lifetime_channels['功能渠道'] = lifetime_channels['项目'] + '｜' + lifetime_channels.label
chart_data = lifetime_channels.sort_values('orders')
ax = chart_data.plot.barh(x='功能渠道', y='orders', legend=False, figsize=(9, 4.8), color='#2474b5')
ax.set_title('上线以来功能渠道累计订单量')
ax.set_xlabel('有效订单数'); ax.set_ylabel(''); ax.grid(axis='x', alpha=.2)
plt.tight_layout(); plt.show()
lifetime_channels[['项目','label','orders','active_users','amount','order_share']].sort_values(['项目','orders'], ascending=[True,False])"""
        ),
        nbf.v4.new_markdown_cell("### 3. 上线以来月度趋势（首月与8月是不完整月）"),
        nbf.v4.new_code_cell(
            """monthly_usage['month_date'] = pd.to_datetime(monthly_usage.month + '-01')
fig, axes = plt.subplots(2, 1, figsize=(10, 6.5), sharex=True)
for ax, key, color in zip(axes, ['airport','saidi'], ['#0b6e99','#c56a2d']):
    frame = monthly_usage[monthly_usage.project_key == key]
    ax.plot(frame.month_date, frame.orders, marker='o', color=color, linewidth=1.8)
    ax.set_title(f"{PROJECT_LABELS[key]}｜月度有效订单")
    ax.set_ylabel('订单数'); ax.grid(alpha=.2)
plt.tight_layout(); plt.show()"""
        ),
        nbf.v4.new_markdown_cell("### 4. 累计高频用户与场景集中度"),
        nbf.v4.new_code_cell(
            """concentration = []
for key in ['airport', 'saidi']:
    f = user_frequency[(user_frequency.project_key == key) & (user_frequency.period == '上线以来')]
    high = f[f.frequency_bucket == '21次以上'].iloc[0]
    r = restaurant_rank[restaurant_rank.project_key == key].sort_values('rank')
    concentration.append({
        '项目': PROJECT_LABELS[key],
        '21次以上用户占比': high.users / f.users.sum(),
        '21次以上用户订单贡献': high.orders / f.orders.sum(),
        'Top3餐厅订单占比': r.head(3).orders.sum() / r.orders.sum(),
    })
concentration_display = pd.DataFrame(concentration)
for column in ['21次以上用户占比','21次以上用户订单贡献','Top3餐厅订单占比']:
    concentration_display[column] = concentration_display[column].map('{:.2%}'.format)
concentration_display"""
        ),
        nbf.v4.new_markdown_cell("### 5. 上线以来功能证据与后台管理"),
        nbf.v4.new_code_cell(
            """feature_activity.sort_values(['project_key','lifetime_records'], ascending=[True,False])[
    ['project_name','feature','evidence_type','lifetime_records','lifetime_distinct_actors','current_30d_records','previous_30d_records']
].head(40)"""
        ),
        nbf.v4.new_code_cell(
            """management_activity[management_activity.period == '上线以来'].sort_values(
    ['project_key','events'], ascending=[True,False]
)"""
        ),
        nbf.v4.new_markdown_cell("### 6. 数据质量"),
        nbf.v4.new_code_cell("data_quality"),
        nbf.v4.new_markdown_cell(
            """## Takeaways

1. **机场长期优先级：** 消费机稳定性、外部订单一致性、多支付保障、退款和报表自动化。
2. **赛迪长期优先级：** 消费机＋闸机双链路、工作日午餐高峰、消费码和核心点位闭环；线上订餐仍是补充能力。
3. **累计风险：** 赛迪 257 条取餐记录全部为“备餐中”；累计 210 次限额拦截，且近30天从 21 次升至 95 次。
4. **证据边界：** 业务表为 0 不代表页面从未打开。要回答页面访问和转化，仍需补统一事件埋点。
5. **报告原则：** 主看上线以来累计使用，近30天只用于趋势、活跃度与异常诊断。"""
        ),
    ]
    nbf.write(notebook, NOTEBOOK)
    print(NOTEBOOK)


if __name__ == "__main__":
    main()
