import json
from datetime import datetime
from pathlib import Path


def generate_screen_report(results, market_ctx=None, llm_report=None, output_dir=None, mode="confirm"):
    if output_dir is None:
        output_dir = Path(__file__).parent / "reports"
    output_dir.mkdir(exist_ok=True)
    timestamp = datetime.now().strftime("%Y%m%d_%H%M")
    filename = f"screen_{timestamp}.html"
    filepath = Path(output_dir) / filename

    rows_html = ""
    for _, row in results.iterrows():
        prob = row.get("buy_prob", 0.5)
        ml_raw = row.get("ml_score", 0)
        prob_pct = f"{prob*100:.1f}%"
        ml_raw_pct = f"{ml_raw*100:.1f}%"
        if prob >= 0.65:
            badge_class = "badge-danger"
            advice = "强烈推荐"
            stars = "★★★"
        elif prob >= 0.55:
            badge_class = "badge-warning"
            advice = "可以买入"
            stars = "★★☆"
        elif prob >= 0.45:
            badge_class = "badge-info"
            advice = "观望"
            stars = "★☆☆"
        else:
            badge_class = "badge-secondary"
            advice = "不建议"
            stars = "☆☆☆"

        chg = row.get("change_pct", 0)
        chg_class = "text-success" if chg >= 0 else "text-danger"
        chg_icon = "▲" if chg >= 0 else "▼"

        rows_html += f"""
        <tr>
            <td class="rank">{int(row.get('rank', 0))}</td>
            <td class="code">{row.get('code', '')}</td>
            <td class="name">{row.get('name', '')}</td>
            <td class="prob">
                <div class="prob-bar">
                    <div class="prob-fill" style="width:{prob*100}%"></div>
                </div>
                <span class="prob-text">{prob_pct}</span>
                <span class="prob-raw">ML原始 {ml_raw_pct}</span>
            </td>
            <td class="{chg_class}">{chg_icon} {abs(chg):.2f}%</td>
            <td><span class="badge {badge_class}">{stars} {advice}</span></td>
        </tr>"""

    market_html = ""
    if market_ctx:
        advance = market_ctx.get("market_advance_count", 0)
        decline = market_ctx.get("market_decline_count", 0)
        total = advance + decline
        ratio = advance / total * 100 if total > 0 else 50
        market_html = f"""
        <div class="market-info">
            <div class="market-item">
                <span class="label">上涨</span>
                <span class="value text-success">{advance}</span>
            </div>
            <div class="market-item">
                <span class="label">下跌</span>
                <span class="value text-danger">{decline}</span>
            </div>
            <div class="market-item">
                <span class="label">上涨比例</span>
                <span class="value">{ratio:.1f}%</span>
            </div>
            <div class="market-item">
                <span class="label">市场均涨幅</span>
                <span class="value">{market_ctx.get('market_mean_return', 0):.2f}%</span>
            </div>
        </div>"""

    llm_html = ""
    if llm_report:
        llm_html = f"""
        <div class="section">
            <h2>LLM分析报告</h2>
            <div class="llm-report">{_md_to_html(llm_report)}</div>
        </div>"""

    now = datetime.now().strftime("%Y-%m-%d %H:%M")
    if mode == "pre":
        mode_label = "盘前规划版"
        title_note = "基于昨日数据，预测今日走向 | 结合9:25竞价观察，10:00确认买入"
        tips = """<li>本版为盘前规划名单，预测的是<b>今日</b>走向，尚不可直接买入</li>
                <li>9:15-9:25 观察名单股票的竞价强弱（高开/低开/竞价量）</li>
                <li>10:00 运行确认版（实时数据）决定最终买入，次日卖出</li>"""
    else:
        mode_label = "盘中确认版"
        title_note = "实时数据，预测次日走向 | 从前5名选2-3只买入，次日卖出"
        tips = """<li>从前5名中选择2-3只买入（概率>55%优先）</li>
                <li>止损：亏损 > 5% 立即卖出 | 止盈：盈利 > 5% 考虑卖出</li>
                <li>每只股票仓位不超过总资金的30%</li>"""
    html = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>A股超短期选股（{mode_label}） - {now}</title>
<style>
*{{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}}
body{{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#f0f2f5;color:#333;line-height:1.6;-webkit-font-smoothing:antialiased}}
.container{{max-width:1000px;margin:0 auto;padding:12px}}
.header{{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;padding:24px 16px;border-radius:16px;margin-bottom:12px;text-align:center}}
.header h1{{font-size:20px;margin-bottom:6px;letter-spacing:1px}}
.header .subtitle{{opacity:.9;font-size:13px}}
.header .time{{margin-top:8px;font-size:12px;opacity:.75}}
.section{{background:#fff;border-radius:16px;padding:16px;margin-bottom:12px;box-shadow:0 2px 12px rgba(0,0,0,.06)}}
.section h2{{font-size:16px;color:#333;margin-bottom:12px;padding-bottom:8px;border-bottom:2px solid #667eea}}
.market-info{{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}}
.market-item{{text-align:center;padding:12px 8px;background:#f8f9fa;border-radius:12px}}
.market-item .label{{display:block;font-size:11px;color:#888;margin-bottom:2px}}
.market-item .value{{font-size:18px;font-weight:bold}}
.table-wrap{{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 -4px;padding:0 4px}}
table{{width:100%;border-collapse:collapse}}
th{{background:#f8f9fa;padding:10px 8px;text-align:left;font-size:12px;color:#666;font-weight:600;border-bottom:2px solid #eee;white-space:nowrap}}
td{{padding:10px 8px;border-bottom:1px solid #f0f0f0;font-size:13px}}
tr:active{{background:#f8f9ff}}
.rank{{font-weight:bold;color:#667eea;text-align:center;width:40px}}
.code{{font-family:'SF Mono',Monaco,monospace;font-weight:600;font-size:13px}}
.name{{font-weight:500}}
.prob{{min-width:100px}}
.prob-bar{{height:6px;background:#eee;border-radius:3px;overflow:hidden;margin-bottom:3px}}
.prob-fill{{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);border-radius:3px;transition:width .3s}}
.prob-text{{font-size:12px;font-weight:bold;color:#667eea}}
.prob-raw{{display:block;font-size:10px;color:#999;margin-top:2px}}
.text-success{{color:#52c41a}}
.text-danger{{color:#ff4d4f}}
.badge{{display:inline-block;padding:4px 10px;border-radius:12px;font-size:12px;font-weight:600;white-space:nowrap}}
.badge-danger{{background:#fff1f0;color:#ff4d4f;border:1px solid #ffa39e}}
.badge-warning{{background:#fffbe6;color:#faad14;border:1px solid #ffe58f}}
.badge-info{{background:#e6f7ff;color:#1890ff;border:1px solid #91d5ff}}
.badge-secondary{{background:#f5f5f5;color:#8c8c8c;border:1px solid #d9d9d9}}
.tips{{background:#fffbe6;border:1px solid #ffe58f;border-radius:12px;padding:14px;margin-top:14px}}
.tips h3{{color:#d48806;font-size:13px;margin-bottom:6px}}
.tips ul{{padding-left:18px;font-size:12px;color:#8c6900}}
.tips li{{margin-bottom:3px}}
.llm-report{{background:#f8f9fa;padding:14px;border-radius:10px;font-size:13px;line-height:1.8}}
.llm-report h1,.llm-report h2,.llm-report h3{{margin:12px 0 6px;color:#333;font-size:15px}}
.llm-report table{{margin:10px 0;width:100%;border-collapse:collapse;table-layout:fixed}}
.llm-report th,.llm-report td{{padding:6px 10px;border:1px solid #ddd;font-size:12px;word-break:break-word}}
.llm-report th:nth-child(1),.llm-report td:nth-child(1){{width:15%}}
.llm-report th:nth-child(2),.llm-report td:nth-child(2){{width:15%}}
.llm-report th:nth-child(3),.llm-report td:nth-child(3){{width:10%}}
.llm-report th:nth-child(4),.llm-report td:nth-child(4){{width:60%}}
.footer{{text-align:center;color:#999;font-size:11px;padding:16px 8px}}
@media(min-width:640px){{
.container{{padding:20px}}
.header{{padding:30px;margin-bottom:20px;border-radius:12px}}
.header h1{{font-size:24px}}
.section{{padding:24px;margin-bottom:16px;border-radius:12px}}
.section h2{{font-size:18px;margin-bottom:16px;padding-bottom:10px}}
.market-info{{grid-template-columns:repeat(4,1fr);gap:16px}}
.market-item{{padding:15px;border-radius:8px}}
.market-item .label{{font-size:12px}}
.market-item .value{{font-size:20px}}
th{{padding:12px 10px;font-size:13px}}
td{{padding:12px 10px;font-size:14px}}
.prob{{min-width:120px}}
.prob-bar{{height:8px}}
.prob-text{{font-size:13px}}
.badge{{padding:4px 10px;font-size:12px}}
.tips{{padding:16px}}
.tips h3{{font-size:14px}}
.tips ul{{font-size:13px}}
.footer{{font-size:12px;padding:20px}}
.llm-report th,.llm-report td{{padding:8px 12px;font-size:13px}}
}}
</style>
</head>
<body>
<div class="container">
    <div class="header">
        <h1>A股超短期选股报告 · {mode_label}</h1>
        <div class="subtitle">ML + LLM 智能量化选股系统</div>
        <div class="time">{now}</div>
        <div class="time">{title_note}</div>
    </div>

    {market_html}

    <div class="section">
        <h2>选股结果 Top {len(results)}</h2>
        <div class="table-wrap">
        <table>
            <thead>
                <tr>
                    <th>排名</th>
                    <th>代码</th>
                    <th>名称</th>
                    <th>买入概率</th>
                    <th>涨跌幅</th>
                    <th>建议</th>
                </tr>
            </thead>
            <tbody>
                {rows_html}
            </tbody>
        </table>
        </div>
        <div class="tips">
            <h3>操作建议</h3>
            <ul>
                {tips}
            </ul>
        </div>
    </div>

    {llm_html}

    <div class="footer">
        A股超短期选股系统 | ML: LightGBM + XGBoost | LLM: DeepSeek<br>
        仅供参考，不构成投资建议。股市有风险，入市需谨慎。
    </div>
</div>
</body>
</html>"""

    filepath.write_text(html, encoding="utf-8")
    return str(filepath)


def generate_analyze_report(symbol, stock_name, buy_prob, tech_indicators, tech_analysis, advice, llm_analysis=None, output_dir=None):
    if output_dir is None:
        output_dir = Path(__file__).parent / "reports"
    output_dir.mkdir(exist_ok=True)
    timestamp = datetime.now().strftime("%Y%m%d_%H%M")
    filename = f"analyze_{symbol}_{timestamp}.html"
    filepath = Path(output_dir) / filename

    prob_pct = f"{buy_prob*100:.1f}%"
    if buy_prob >= 0.65:
        rating = "强烈推荐买入"
        stars = "★★★"
        rating_color = "#ff4d4f"
    elif buy_prob >= 0.55:
        rating = "可以考虑买入"
        stars = "★★☆"
        rating_color = "#faad14"
    elif buy_prob >= 0.45:
        rating = "建议观望"
        stars = "★☆☆"
        rating_color = "#1890ff"
    else:
        rating = "不建议买入"
        stars = "☆☆☆"
        rating_color = "#8c8c8c"

    tech_rows = ""
    indicators = [
        ("RSI(14)", "rsi_14", "{:.1f}"),
        ("MACD差值", "macd_diff", "{:.4f}"),
        ("布林带位置", "bb_pct", "{:.2f}"),
        ("5日量比", "vol_ratio_5", "{:.2f}"),
        ("ATR波动率", "atr_ratio", "{:.4f}"),
        ("ADX趋势", "adx_14", "{:.1f}"),
        ("MFI资金流", "mfi_14", "{:.1f}"),
        ("OBV趋势", "obv_ret", "{:.4f}"),
    ]
    for label, key, fmt in indicators:
        val = tech_indicators.get(key, 0)
        status = tech_analysis.get(key, "")
        if val and status:
            tech_rows += f"""
            <tr>
                <td>{label}</td>
                <td class="value">{fmt.format(val)}</td>
                <td>{status}</td>
            </tr>"""

    now = datetime.now().strftime("%Y-%m-%d %H:%M")
    html = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>{symbol} {stock_name} 分析报告</title>
<style>
*{{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}}
body{{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#f0f2f5;color:#333;line-height:1.6;-webkit-font-smoothing:antialiased}}
.container{{max-width:800px;margin:0 auto;padding:12px}}
.header{{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;padding:24px 16px;border-radius:16px;margin-bottom:12px;text-align:center}}
.header h1{{font-size:20px;margin-bottom:4px;letter-spacing:1px}}
.header .subtitle{{opacity:.9;font-size:13px}}
.section{{background:#fff;border-radius:16px;padding:16px;margin-bottom:12px;box-shadow:0 2px 12px rgba(0,0,0,.06)}}
.section h2{{font-size:16px;margin-bottom:12px;padding-bottom:8px;border-bottom:2px solid #667eea}}
.prob-card{{text-align:center;padding:24px 16px}}
.prob-big{{font-size:52px;font-weight:bold;color:{rating_color};line-height:1}}
.prob-label{{font-size:13px;color:#888;margin-top:4px}}
.rating{{font-size:18px;color:{rating_color};margin-top:10px;font-weight:bold}}
.info-grid{{display:grid;grid-template-columns:1fr 1fr;gap:10px}}
.info-item{{padding:14px 12px;background:#f8f9fa;border-radius:12px}}
.info-item .label{{font-size:11px;color:#888}}
.info-item .value{{font-size:20px;font-weight:bold;margin-top:3px}}
.table-wrap{{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 -4px;padding:0 4px}}
table{{width:100%;border-collapse:collapse}}
th{{background:#f8f9fa;padding:10px 8px;text-align:left;font-size:12px;color:#666;font-weight:600;border-bottom:2px solid #eee}}
td{{padding:10px 8px;border-bottom:1px solid #f0f0f0;font-size:13px}}
td.value{{font-weight:bold;font-family:'SF Mono',Monaco,monospace}}
.advice-card{{background:linear-gradient(135deg,#f5f7fa 0%,#c3cfe2 100%);border-radius:12px;padding:16px}}
.advice-item{{margin-bottom:14px}}
.advice-item:last-child{{margin-bottom:0}}
.advice-item .label{{font-size:11px;color:#666;font-weight:bold}}
.advice-item .value{{font-size:14px;margin-top:3px}}
.llm-section{{background:#f8f9fa;padding:14px;border-radius:10px;font-size:13px;line-height:1.8}}
.llm-section h1,.llm-section h2,.llm-section h3{{margin:12px 0 6px;font-size:15px}}
.llm-section table{{margin:10px 0;width:100%;border-collapse:collapse;table-layout:fixed}}
.llm-section th,.llm-section td{{padding:6px 10px;border:1px solid #ddd;font-size:12px;word-break:break-word}}
.llm-section th:nth-child(1),.llm-section td:nth-child(1){{width:15%}}
.llm-section th:nth-child(2),.llm-section td:nth-child(2){{width:15%}}
.llm-section th:nth-child(3),.llm-section td:nth-child(3){{width:10%}}
.llm-section th:nth-child(4),.llm-section td:nth-child(4){{width:60%}}
.footer{{text-align:center;color:#999;font-size:11px;padding:16px 8px}}
@media(min-width:640px){{
.container{{padding:20px}}
.header{{padding:30px;margin-bottom:20px;border-radius:12px}}
.header h1{{font-size:22px}}
.section{{padding:24px;margin-bottom:16px;border-radius:12px}}
.section h2{{font-size:18px;margin-bottom:16px;padding-bottom:10px}}
.prob-card{{padding:30px}}
.prob-big{{font-size:64px}}
.info-item{{padding:15px;border-radius:8px}}
.info-item .value{{font-size:20px}}
th{{padding:12px 10px;font-size:13px}}
td{{padding:12px 10px;font-size:14px}}
.advice-item .value{{font-size:15px}}
.footer{{font-size:12px;padding:20px}}
.llm-section th,.llm-section td{{padding:8px 12px;font-size:13px}}
}}
</style>
</head>
<body>
<div class="container">
    <div class="header">
        <h1>{symbol} {stock_name}</h1>
        <div class="subtitle">个股分析报告 | {now}</div>
    </div>

    <div class="section">
        <h2>ML预测</h2>
        <div class="prob-card">
            <div class="prob-big">{prob_pct}</div>
            <div class="prob-label">买入概率</div>
            <div class="rating">{stars} {rating}</div>
        </div>
    </div>

    <div class="section">
        <h2>当前行情</h2>
        <div class="info-grid">
            <div class="info-item">
                <div class="label">最新价</div>
                <div class="value">{tech_indicators.get('close', 0):.2f}</div>
            </div>
            <div class="info-item">
                <div class="label">涨跌幅</div>
                <div class="value">{tech_indicators.get('change_pct', 0):.2f}%</div>
            </div>
        </div>
    </div>

    <div class="section">
        <h2>技术指标</h2>
        <div class="table-wrap">
        <table>
            <thead>
                <tr><th>指标</th><th>数值</th><th>解读</th></tr>
            </thead>
            <tbody>
                {tech_rows}
            </tbody>
        </table>
        </div>
    </div>

    <div class="section">
        <h2>操作建议</h2>
        <div class="advice-card">
            <div class="advice-item">
                <div class="label">综合建议</div>
                <div class="value">{advice.get('summary', '')}</div>
            </div>
            <div class="advice-item">
                <div class="label">买入条件</div>
                <div class="value">{advice.get('buy_condition', '')}</div>
            </div>
            <div class="advice-item">
                <div class="label">止损位</div>
                <div class="value" style="color:#ff4d4f">{advice.get('stop_loss', '')}</div>
            </div>
            <div class="advice-item">
                <div class="label">止盈位</div>
                <div class="value" style="color:#52c41a">{advice.get('take_profit', '')}</div>
            </div>
        </div>
    </div>

    {"<div class='section'><h2>LLM深度分析</h2><div class='llm-section'>" + _md_to_html(llm_analysis) + "</div></div>" if llm_analysis else ""}

    <div class="footer">
        A股超短期选股系统 | 仅供参考，不构成投资建议
    </div>
</div>
</body>
</html>"""

    filepath.write_text(html, encoding="utf-8")
    return str(filepath)


def _md_to_html(md_text):
    if not md_text:
        return ""
    lines = md_text.split("\n")
    html_lines = []
    in_table = False
    for line in lines:
        stripped = line.strip()
        if stripped.startswith("|") and stripped.endswith("|"):
            if not in_table:
                html_lines.append("<table>")
                in_table = True
            cells = [c.strip() for c in stripped.split("|")[1:-1]]
            if all(set(c) <= set("- :") for c in cells):
                continue
            tag = "th" if not in_table else "td"
            row = "".join(f"<{tag}>{c}</{tag}>" for c in cells)
            html_lines.append(f"<tr>{row}</tr>")
        else:
            if in_table:
                html_lines.append("</table>")
                in_table = False
            if stripped.startswith("### "):
                html_lines.append(f"<h3>{stripped[4:]}</h3>")
            elif stripped.startswith("## "):
                html_lines.append(f"<h2>{stripped[3:]}</h2>")
            elif stripped.startswith("# "):
                html_lines.append(f"<h1>{stripped[2:]}</h1>")
            elif stripped.startswith("- "):
                html_lines.append(f"<li>{stripped[2:]}</li>")
            elif stripped.startswith("**") and stripped.endswith("**"):
                html_lines.append(f"<p><strong>{stripped[2:-2]}</strong></p>")
            elif stripped:
                html_lines.append(f"<p>{stripped}</p>")
    if in_table:
        html_lines.append("</table>")
    return "\n".join(html_lines)
