"""
2.3 产品测试效率对比执行脚本
功能:按子产品维度分析测试周期、转化率、流失率等效能指标,并输出Excel、Markdown和图片
"""

import os
from datetime import datetime

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# 设置中文显示
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

# 配置
INPUT_FILE = "脱敏数据_特征增强.xlsx"
OUTPUT_DIR = "执行分析结果/2.3_产品测试效率对比"
OUTPUT_EXCEL = "2.3_产品测试效率对比.xlsx"
OUTPUT_MD = "2.3_产品测试效率对比摘要.md"
OUTPUT_PNG_RANK = "2.3_产品效能排名.png"
OUTPUT_PNG_COMPARE = "2.3_产品效能对比.png"


def main():
    # 1. 读取数据
    base_dir = os.path.dirname(os.path.dirname(__file__))
    input_path = os.path.join(base_dir, INPUT_FILE)

    if not os.path.exists(input_path):
        raise FileNotFoundError(f"未找到输入文件:{input_path}")

    df = pd.read_excel(input_path)
    print(f"数据读取成功: {len(df)} 行, {len(df.columns)} 列")

    # 创建输出目录
    output_dir_abs = os.path.join(base_dir, OUTPUT_DIR)
    os.makedirs(output_dir_abs, exist_ok=True)
    excel_path = os.path.join(output_dir_abs, OUTPUT_EXCEL)
    md_path = os.path.join(output_dir_abs, OUTPUT_MD)
    png_rank_path = os.path.join(output_dir_abs, OUTPUT_PNG_RANK)
    png_compare_path = os.path.join(output_dir_abs, OUTPUT_PNG_COMPARE)

    # 必要字段检查
    required_cols = [
        "子产品名称",
        "测试周期(天)",
        "是否已接入",
        "是否调用(数值)",
        "是否不接入",
        "不接入原因",
    ]
    missing = [c for c in required_cols if c not in df.columns]
    if missing:
        raise ValueError(f"输入数据缺少必要字段: {missing}")

    # =========================
    # 1. 产品基础效能排名
    # =========================
    print("\n计算产品基础效能排名...")

    # 记录总数
    product_total = df.groupby("子产品名称").size().rename("记录总数")

    # 测试周期统计
    cycle_stats = df.groupby("子产品名称")["测试周期(天)"].agg(
        平均测试周期="mean",
        中位数测试周期="median",
        标准差测试周期="std",
    )

    # 数量统计
    agg_counts = df.groupby("子产品名称").agg(
        已接入数量=("是否已接入", "sum"),
        已调用数量=("是否调用(数值)", "sum"),
        不接入数量=("是否不接入", "sum"),
    )

    product_stats = pd.concat([product_total, cycle_stats, agg_counts], axis=1)

    # 计算转化率和流失率
    product_stats["申请→已接入转化率(%)"] = (
        np.where(
            product_stats["记录总数"] > 0,
            product_stats["已接入数量"] / product_stats["记录总数"] * 100,
            np.nan,
        )
    ).round(2)
    product_stats["申请→已调用转化率(%)"] = (
        np.where(
            product_stats["记录总数"] > 0,
            product_stats["已调用数量"] / product_stats["记录总数"] * 100,
            np.nan,
        )
    ).round(2)
    product_stats["不接入流失率(%)"] = (
        np.where(
            product_stats["记录总数"] > 0,
            product_stats["不接入数量"] / product_stats["记录总数"] * 100,
            np.nan,
        )
    ).round(2)

    # 综合效能得分(按转化率排名)
    valid_conv = product_stats["申请→已接入转化率(%)"].fillna(0)
    product_stats["转化率得分"] = valid_conv.rank(pct=True) * 100
    product_stats["综合效能得分"] = product_stats["转化率得分"].round(2)
    product_stats["综合效能排名"] = (
        product_stats["综合效能得分"].rank(ascending=False, method="min").astype(int)
    )

    product_stats = product_stats.sort_values("综合效能排名")

    # =========================
    # 2. 产品不接入原因分布
    # =========================
    print("计算产品不接入原因分布...")

    if df["不接入原因"].notna().any():
        tmp = df[df["不接入原因"].notna()]
        product_reason = (
            tmp.groupby("子产品名称")["不接入原因"]
            .value_counts()
            .unstack(fill_value=0)
        )
        reason_size = tmp.groupby("子产品名称").size()
        product_reason_pct = (
            product_reason.div(reason_size, axis=0).fillna(0) * 100
        ).round(2)
    else:
        product_reason = pd.DataFrame()
        product_reason_pct = pd.DataFrame()

    # =========================
    # 3. 高效产品与低效产品
    # =========================
    print("识别高效产品与低效产品...")

    stats_for_rank = product_stats.dropna(subset=["申请→已接入转化率(%)"]).copy()
    if len(stats_for_rank) >= 2:
        top_products = (
            stats_for_rank.sort_values("申请→已接入转化率(%)", ascending=False)
            .head(2)
            .index.tolist()
        )
        bottom_products = (
            stats_for_rank.sort_values("申请→已接入转化率(%)", ascending=True)
            .head(2)
            .index.tolist()
        )
    else:
        top_products = stats_for_rank.index.tolist()
        bottom_products = stats_for_rank.index.tolist()

    def build_product_feature_dict(name: str) -> dict:
        sub = df[df["子产品名称"] == name]
        if name not in product_stats.index:
            return {}
        row = product_stats.loc[name]
        return {
            "记录总数": int(row["记录总数"]),
            "转化率": float(row["申请→已接入转化率(%)"])
            if pd.notna(row["申请→已接入转化率(%)"])
            else np.nan,
            "平均测试周期": float(row["平均测试周期"])
            if pd.notna(row["平均测试周期"])
            else np.nan,
            "流失率": float(row["不接入流失率(%)"])
            if pd.notna(row["不接入流失率(%)"])
            else np.nan,
        }

    top_product_features = {
        p: build_product_feature_dict(p) for p in top_products
    }
    bottom_product_features = {
        p: build_product_feature_dict(p) for p in bottom_products
    }

    # =========================
    # 4. 保存 Excel
    # =========================
    print(f"\n保存Excel文件: {excel_path}")
    with pd.ExcelWriter(excel_path, engine="openpyxl") as writer:
        product_stats.to_excel(writer, sheet_name="产品基础效能排名")
        if not product_reason.empty:
            product_reason.to_excel(writer, sheet_name="产品不接入原因分布")
            product_reason_pct.to_excel(writer, sheet_name="产品不接入原因占比")

    print("Excel文件保存成功")

    # =========================
    # 5. 生成图片
    # =========================
    print(f"\n生成图片...")

    # 5.1 产品效能排名图
    if not product_stats.empty:
        products_for_plot = (
            product_stats.sort_values("申请→已接入转化率(%)", ascending=False).head(
                20
            )
        )
        plt.figure(figsize=(12, 6))
        plt.bar(
            range(len(products_for_plot)),
            products_for_plot["申请→已接入转化率(%)"],
            color="steelblue",
        )
        plt.xticks(
            range(len(products_for_plot)),
            products_for_plot.index,
            rotation=45,
            ha="right",
        )
        plt.ylabel("申请→已接入转化率(%)")
        plt.title("2.3 产品效能排名(按申请→已接入转化率)")
        plt.tight_layout()
        plt.savefig(png_rank_path, dpi=300, bbox_inches="tight")
        plt.close()
        print(f"产品效能排名图已保存: {png_rank_path}")

    # 5.2 高效vs低效产品对比图
    names_for_compare = list(dict.fromkeys(top_products + bottom_products))
    if names_for_compare and len(names_for_compare) > 0:
        metrics = [
            "申请→已接入转化率(%)",
            "平均测试周期",
            "不接入流失率(%)",
        ]
        comp_df = product_stats.loc[names_for_compare, metrics].copy()

        x = np.arange(len(names_for_compare))
        width = 0.25

        plt.figure(figsize=(12, 6))
        for i, m in enumerate(metrics):
            plt.bar(
                x + (i - 1) * width,
                comp_df[m],
                width=width,
                label=m,
            )

        plt.xticks(x, [str(n) for n in names_for_compare], rotation=45, ha="right")
        plt.ylabel("数值")
        plt.title("2.3 高效 vs 低效产品对比(转化率 / 周期 / 流失率)")
        plt.legend()
        plt.tight_layout()
        plt.savefig(png_compare_path, dpi=300, bbox_inches="tight")
        plt.close()
        print(f"产品效能对比图已保存: {png_compare_path}")

    # =========================
    # 6. 生成 Markdown 摘要
    # =========================
    print(f"\n生成Markdown摘要: {md_path}")

    now_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    md_lines = []
    md_lines.append("# 产品测试效率对比摘要")
    md_lines.append("")
    md_lines.append(f"> **生成时间**: {now_str}  ")
    md_lines.append(f"> **数据文件**: {INPUT_FILE}  ")
    md_lines.append(f"> **数据量**: {len(df)} 条记录")
    md_lines.append("")
    md_lines.append("---")
    md_lines.append("")
    md_lines.append("## 📊 产品基础效能排名(按综合效能得分)")
    md_lines.append("")
    md_lines.append(
        "| 排名 | 子产品名称 | 记录总数 | 平均测试周期(天) | 申请→已接入转化率(%) | "
        "申请→已调用转化率(%) | 不接入流失率(%) | 综合效能得分 |"
    )
    md_lines.append(
        "|------|------------|----------|------------------|---------------------|"
        "---------------------|-----------------|--------------|"
    )

    for name, row in product_stats.iterrows():
        md_lines.append(
            f"| {int(row['综合效能排名'])} | {name} | "
            f"{int(row['记录总数'])} | "
            f"{row['平均测试周期']:.1f} | "
            f"{row['申请→已接入转化率(%)']:.2f} | "
            f"{row['申请→已调用转化率(%)']:.2f} | "
            f"{row['不接入流失率(%)']:.2f} | "
            f"{row['综合效能得分']:.2f} |"
        )

    # 高效产品
    md_lines.append("")
    md_lines.append("---")
    md_lines.append("")
    md_lines.append("## 🏆 高效产品特征(转化率 Top 2)")
    md_lines.append("")

    for p in top_products:
        feat = top_product_features.get(p, {})
        if not feat:
            continue
        md_lines.append(f"### {p}")
        md_lines.append("")
        md_lines.append(f"- **记录总数**: {feat['记录总数']}")
        if not np.isnan(feat["转化率"]):
            md_lines.append(f"- **申请→已接入转化率**: {feat['转化率']:.2f}%")
        if not np.isnan(feat["平均测试周期"]):
            md_lines.append(f"- **平均测试周期**: {feat['平均测试周期']:.1f} 天")
        if not np.isnan(feat["流失率"]):
            md_lines.append(f"- **不接入流失率**: {feat['流失率']:.2f}%")
        md_lines.append("")

    # 低效产品
    md_lines.append("")
    md_lines.append("---")
    md_lines.append("")
    md_lines.append("## ⚠️ 低效产品特征(转化率 Bottom 2)")
    md_lines.append("")

    for p in bottom_products:
        feat = bottom_product_features.get(p, {})
        if not feat:
            continue
        md_lines.append(f"### {p}")
        md_lines.append("")
        md_lines.append(f"- **记录总数**: {feat['记录总数']}")
        if not np.isnan(feat["转化率"]):
            md_lines.append(f"- **申请→已接入转化率**: {feat['转化率']:.2f}%")
        if not np.isnan(feat["平均测试周期"]):
            md_lines.append(f"- **平均测试周期**: {feat['平均测试周期']:.1f} 天")
        if not np.isnan(feat["流失率"]):
            md_lines.append(f"- **不接入流失率**: {feat['流失率']:.2f}%")
        md_lines.append("")

    # 关键发现
    md_lines.append("")
    md_lines.append("---")
    md_lines.append("")
    md_lines.append("## 📈 关键发现")
    md_lines.append("")

    if not product_stats.empty:
        best = product_stats["申请→已接入转化率(%)"].idxmax()
        worst = product_stats["申请→已接入转化率(%)"].idxmin()
        md_lines.append(
            f"1. **转化率最高产品**:{best} "
            f"({product_stats.loc[best, '申请→已接入转化率(%)']:.2f}%)"
        )
        md_lines.append(
            f"2. **转化率最低产品**:{worst} "
            f"({product_stats.loc[worst, '申请→已接入转化率(%)']:.2f}%)"
        )
        md_lines.append(
            f"3. **平均测试周期最短产品**:"
            f"{product_stats['平均测试周期'].idxmin()} "
            f"({product_stats['平均测试周期'].min():.1f} 天)"
        )
        md_lines.append(
            f"4. **平均测试周期最长产品**:"
            f"{product_stats['平均测试周期'].idxmax()} "
            f"({product_stats['平均测试周期'].max():.1f} 天)"
        )
        md_lines.append(
            f"5. **流失率最低产品**:"
            f"{product_stats['不接入流失率(%)'].idxmin()} "
            f"({product_stats['不接入流失率(%)'].min():.2f}%)"
        )
        md_lines.append(
            f"6. **流失率最高产品**:"
            f"{product_stats['不接入流失率(%)'].idxmax()} "
            f"({product_stats['不接入流失率(%)'].max():.2f}%)"
        )

    md_lines.append("")
    md_lines.append("---")
    md_lines.append("")
    md_lines.append("*本报告由 2.3_产品测试效率对比.md 方案自动生成*")

    with open(md_path, "w", encoding="utf-8") as f:
        f.write("\n".join(md_lines))

    print("Markdown摘要生成成功")
    print(f"\n✅ 产品测试效率对比分析完成!")
    print(f"   Excel文件: {excel_path}")
    print(f"   Markdown摘要: {md_path}")
    print(f"   产品效能排名图: {png_rank_path}")
    print(f"   产品效能对比图: {png_compare_path}")


if __name__ == "__main__":
    main()