"""
复盘计划接口 - 提供复盘与交易计划相关数据 (V1 + V2)
"""
import logging
from datetime import datetime
from typing import Optional, List

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy.orm import Session

from app.database import get_db
from app.analysis_db import get_analysis_db
from app.analysis_models import (
    ReviewDate, SymbolRanking, TradingPlan,
    ReviewPlanV2, SymbolScoreV2, TradingPlanV2, SectorHeat,
)
from app.services.plan_generator import generate_plan, save_plan_to_db, get_plan_data

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/review", tags=["复盘计划"])


# ==================== 请求体模型 ====================

class GeneratePlanRequest(BaseModel):
    review_date: str


# ==================== V1 复盘日期管理 ====================

@router.get("/dates")
def get_review_dates(limit: int = 10, db: Session = Depends(get_analysis_db)):
    """获取复盘日期列表"""
    dates = db.query(ReviewDate).order_by(
        ReviewDate.review_date.desc()
    ).limit(limit).all()

    return {
        "success": True,
        "data": [{
            "id": d.id,
            "review_date": d.review_date,
            "week_day": d.week_day
        } for d in dates]
    }


@router.post("/dates")
def create_review_date(
    review_date: str,
    week_day: Optional[str] = None,
    db: Session = Depends(get_analysis_db)
):
    """创建复盘日期"""
    existing = db.query(ReviewDate).filter(
        ReviewDate.review_date == review_date
    ).first()

    if existing:
        return {
            "success": False,
            "message": f"日期 {review_date} 已存在"
        }

    if not week_day:
        try:
            dt = datetime.strptime(review_date, "%Y-%m-%d")
            week_days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
            week_day = week_days[dt.weekday()]
        except:
            week_day = ""

    new_date = ReviewDate(
        review_date=review_date,
        week_day=week_day
    )
    db.add(new_date)
    db.commit()
    db.refresh(new_date)

    return {
        "success": True,
        "data": {
            "id": new_date.id,
            "review_date": new_date.review_date,
            "week_day": new_date.week_day
        }
    }


# ==================== V1 品种排名 ====================

@router.get("/rankings/{review_date_id}")
def get_rankings(review_date_id: int, db: Session = Depends(get_analysis_db)):
    """获取指定日期的品种排名"""
    review_date = db.query(ReviewDate).filter(
        ReviewDate.id == review_date_id
    ).first()

    if not review_date:
        raise HTTPException(status_code=404, detail="复盘日期不存在")

    rankings = db.query(SymbolRanking).filter(
        SymbolRanking.review_date_id == review_date_id
    ).order_by(
        SymbolRanking.rank_type,
        SymbolRanking.rank
    ).all()

    rank_types = ["volume", "amplitude", "change", "open_interest"]
    rank_type_names = {
        "volume": "成交量排名",
        "amplitude": "振幅排名",
        "change": "涨跌幅排名",
        "open_interest": "持仓量排名"
    }

    result = {}
    for rt in rank_types:
        result[rt] = {
            "title": rank_type_names.get(rt, rt),
            "items": []
        }

    for r in rankings:
        if r.rank_type in result:
            result[r.rank_type]["items"].append({
                "id": r.id,
                "symbol": r.symbol,
                "name": r.name or r.symbol,
                "rank": r.rank,
                "value": r.value,
                "price": r.price,
                "change_pct": r.change_pct
            })

    return {
        "success": True,
        "data": {
            "review_date": review_date.review_date,
            "week_day": review_date.week_day,
            "rankings": result
        }
    }


@router.post("/rankings")
def create_or_update_rankings(
    review_date_id: int,
    rankings: List[dict],
    db: Session = Depends(get_analysis_db)
):
    """创建或更新品种排名"""
    review_date = db.query(ReviewDate).filter(
        ReviewDate.id == review_date_id
    ).first()

    if not review_date:
        raise HTTPException(status_code=404, detail="复盘日期不存在")

    db.query(SymbolRanking).filter(
        SymbolRanking.review_date_id == review_date_id
    ).delete()

    created = []
    for r in rankings:
        new_ranking = SymbolRanking(
            review_date_id=review_date_id,
            symbol=r.get("symbol"),
            name=r.get("name"),
            rank_type=r.get("rank_type"),
            rank=r.get("rank", 1),
            value=r.get("value"),
            price=r.get("price"),
            change_pct=r.get("change_pct")
        )
        db.add(new_ranking)
        created.append({
            "id": new_ranking.id,
            "symbol": new_ranking.symbol,
            "rank_type": new_ranking.rank_type,
            "rank": new_ranking.rank
        })

    db.commit()

    return {
        "success": True,
        "data": created
    }


# ==================== V1 交易计划 ====================

@router.get("/plans/{review_date_id}")
def get_trading_plans(review_date_id: int, db: Session = Depends(get_analysis_db)):
    """获取指定日期的交易计划"""
    review_date = db.query(ReviewDate).filter(
        ReviewDate.id == review_date_id
    ).first()

    if not review_date:
        raise HTTPException(status_code=404, detail="复盘日期不存在")

    plans = db.query(TradingPlan).filter(
        TradingPlan.review_date_id == review_date_id
    ).order_by(
        TradingPlan.score.desc()
    ).all()

    return {
        "success": True,
        "data": {
            "review_date": review_date.review_date,
            "week_day": review_date.week_day,
            "plans": [{
                "id": p.id,
                "symbol": p.symbol,
                "name": p.name or p.symbol,
                "plan_type": p.plan_type,
                "score": p.score,
                "logic": p.logic,
                "reason": p.reason,
                "entry_price": p.entry_price,
                "stop_loss": p.stop_loss,
                "take_profit": p.take_profit,
                "confidence": p.confidence,
                "position_suggestion": p.position_suggestion,
                "created_at": p.created_at.isoformat() if p.created_at else None
            } for p in plans]
        }
    }


@router.post("/plans")
def create_or_update_plans(
    review_date_id: int,
    plans: List[dict],
    db: Session = Depends(get_analysis_db)
):
    """创建或更新交易计划"""
    review_date = db.query(ReviewDate).filter(
        ReviewDate.id == review_date_id
    ).first()

    if not review_date:
        raise HTTPException(status_code=404, detail="复盘日期不存在")

    db.query(TradingPlan).filter(
        TradingPlan.review_date_id == review_date_id
    ).delete()

    created = []
    for p in plans:
        new_plan = TradingPlan(
            review_date_id=review_date_id,
            symbol=p.get("symbol"),
            name=p.get("name"),
            plan_type=p.get("plan_type"),
            score=p.get("score", 0),
            logic=p.get("logic"),
            reason=p.get("reason"),
            entry_price=p.get("entry_price"),
            stop_loss=p.get("stop_loss"),
            take_profit=p.get("take_profit"),
            confidence=p.get("confidence"),
            position_suggestion=p.get("position_suggestion")
        )
        db.add(new_plan)
        created.append({
            "id": new_plan.id,
            "symbol": new_plan.symbol,
            "plan_type": new_plan.plan_type,
            "score": new_plan.score
        })

    db.commit()

    return {
        "success": True,
        "data": created
    }


@router.post("/plans/batch")
def batch_create_review_data(
    review_data: dict,
    db: Session = Depends(get_analysis_db)
):
    """批量创建复盘数据（日期+排名+计划）"""
    review_date_str = review_data.get("review_date")
    week_day = review_data.get("week_day")

    existing = db.query(ReviewDate).filter(
        ReviewDate.review_date == review_date_str
    ).first()

    if existing:
        review_date_id = existing.id
    else:
        if not week_day:
            try:
                dt = datetime.strptime(review_date_str, "%Y-%m-%d")
                week_days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
                week_day = week_days[dt.weekday()]
            except:
                week_day = ""

        new_date = ReviewDate(
            review_date=review_date_str,
            week_day=week_day
        )
        db.add(new_date)
        db.commit()
        db.refresh(new_date)
        review_date_id = new_date.id

    rankings = review_data.get("rankings", [])
    if rankings:
        db.query(SymbolRanking).filter(
            SymbolRanking.review_date_id == review_date_id
        ).delete()

        for r in rankings:
            new_ranking = SymbolRanking(
                review_date_id=review_date_id,
                symbol=r.get("symbol"),
                name=r.get("name"),
                rank_type=r.get("rank_type"),
                rank=r.get("rank", 1),
                value=r.get("value"),
                price=r.get("price"),
                change_pct=r.get("change_pct")
            )
            db.add(new_ranking)

    plans = review_data.get("plans", [])
    if plans:
        db.query(TradingPlan).filter(
            TradingPlan.review_date_id == review_date_id
        ).delete()

        for p in plans:
            new_plan = TradingPlan(
                review_date_id=review_date_id,
                symbol=p.get("symbol"),
                name=p.get("name"),
                plan_type=p.get("plan_type"),
                score=p.get("score", 0),
                logic=p.get("logic"),
                reason=p.get("reason"),
                entry_price=p.get("entry_price"),
                stop_loss=p.get("stop_loss"),
                take_profit=p.get("take_profit"),
                confidence=p.get("confidence"),
                position_suggestion=p.get("position_suggestion")
            )
            db.add(new_plan)

    db.commit()

    return {
        "success": True,
        "data": {
            "review_date_id": review_date_id,
            "review_date": review_date_str,
            "rankings_count": len(rankings),
            "plans_count": len(plans)
        }
    }


@router.get("/summary/{review_date_id}")
def get_review_summary(review_date_id: int, db: Session = Depends(get_analysis_db)):
    """获取复盘摘要（包含排名和计划的完整数据）"""
    review_date = db.query(ReviewDate).filter(
        ReviewDate.id == review_date_id
    ).first()

    if not review_date:
        raise HTTPException(status_code=404, detail="复盘日期不存在")

    rankings = db.query(SymbolRanking).filter(
        SymbolRanking.review_date_id == review_date_id
    ).order_by(
        SymbolRanking.rank_type,
        SymbolRanking.rank
    ).all()

    plans = db.query(TradingPlan).filter(
        TradingPlan.review_date_id == review_date_id
    ).order_by(
        TradingPlan.score.desc()
    ).all()

    rank_types = ["volume", "amplitude", "change", "open_interest"]
    rank_type_names = {
        "volume": "成交量排名 Top 5",
        "amplitude": "振幅排名 Top 5",
        "change": "涨跌幅排名 Top 5",
        "open_interest": "持仓量排名 Top 5"
    }

    rankings_result = {}
    for rt in rank_types:
        rankings_result[rt] = {
            "title": rank_type_names.get(rt, rt),
            "items": []
        }

    for r in rankings:
        if r.rank_type in rankings_result:
            rankings_result[r.rank_type]["items"].append({
                "symbol": r.symbol,
                "name": r.name or r.symbol,
                "rank": r.rank,
                "value": r.value,
                "price": r.price,
                "change_pct": r.change_pct
            })

    plans_result = [{
        "id": p.id,
        "symbol": p.symbol,
        "name": p.name or p.symbol,
        "plan_type": p.plan_type,
        "score": p.score,
        "logic": p.logic,
        "reason": p.reason,
        "entry_price": p.entry_price,
        "stop_loss": p.stop_loss,
        "take_profit": p.take_profit,
        "confidence": p.confidence,
        "position_suggestion": p.position_suggestion,
        "created_at": p.created_at.isoformat() if p.created_at else None
    } for p in plans]

    return {
        "success": True,
        "data": {
            "review_date": review_date.review_date,
            "week_day": review_date.week_day,
            "rankings": rankings_result,
            "plans": plans_result
        }
    }


@router.delete("/clear")
def clear_review_data(db: Session = Depends(get_analysis_db)):
    """清除所有V1复盘与交易计划数据"""
    try:
        db.query(TradingPlan).delete()
        db.query(SymbolRanking).delete()
        db.query(ReviewDate).delete()
        db.commit()

        return {
            "success": True,
            "message": "复盘数据已清除"
        }
    except Exception as e:
        db.rollback()
        return {
            "success": False,
            "message": f"清除失败: {str(e)}"
        }


# ==================== V2 生成交易计划 ====================

@router.post("/generate")
def generate_review_plan(
    req: GeneratePlanRequest,
    buffer_db: Session = Depends(get_db),
    analysis_db: Session = Depends(get_analysis_db)
):
    """生成V2交易计划"""
    try:
        review_date_str = req.review_date
        dt = datetime.strptime(review_date_str, "%Y-%m-%d")
        week_days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
        week_day = week_days[dt.weekday()]

        # buffer_db 用于获取K线数据，analysis_db 用于保存计划
        plan_data = generate_plan(buffer_db, review_date_str, week_day)
        plan_id = save_plan_to_db(analysis_db, plan_data)

        return {
            "success": True,
            "data": {
                "plan_id": plan_id,
                "summary": {
                    "review_date": plan_data["review_date"],
                    "week_day": plan_data["week_day"],
                    "core_conclusion": plan_data.get("core_conclusion"),
                    "bull_count": plan_data.get("bull_count"),
                    "bear_count": plan_data.get("bear_count"),
                    "neutral_count": plan_data.get("neutral_count"),
                    "opportunity_count": plan_data.get("opportunity_count"),
                    "symbol_count": plan_data.get("symbol_count"),
                }
            }
        }
    except Exception as e:
        logger.exception("生成交易计划失败")
        return {
            "success": False,
            "message": f"生成失败: {str(e)}"
        }


# ==================== V2 查询接口 ====================

@router.get("/v2/plans")
def list_v2_plans(
    limit: int = 20,
    db: Session = Depends(get_analysis_db)
):
    """获取V2复盘计划列表"""
    try:
        plans = db.query(ReviewPlanV2).order_by(
            ReviewPlanV2.review_date.desc()
        ).limit(limit).all()

        return {
            "success": True,
            "data": [{
                "id": p.id,
                "review_date": p.review_date,
                "week_day": p.week_day,
                "core_conclusion": p.core_conclusion,
                "opportunity_count": p.opportunity_count,
                "created_at": p.created_at.isoformat() if p.created_at else None,
            } for p in plans]
        }
    except Exception as e:
        logger.exception("获取V2计划列表失败")
        return {
            "success": False,
            "message": f"查询失败: {str(e)}"
        }


@router.get("/v2/plan/{plan_id}")
def get_v2_plan(plan_id: int, db: Session = Depends(get_analysis_db)):
    """根据ID获取完整V2计划数据"""
    try:
        result = get_plan_data(db, plan_id)
        if not result:
            return {
                "success": False,
                "message": f"计划 {plan_id} 不存在"
            }

        return {
            "success": True,
            "data": result
        }
    except Exception as e:
        logger.exception(f"获取V2计划 {plan_id} 失败")
        return {
            "success": False,
            "message": f"查询失败: {str(e)}"
        }


@router.get("/v2/plan/by-date/{date}")
def get_v2_plan_by_date(date: str, db: Session = Depends(get_analysis_db)):
    """根据日期获取V2计划数据"""
    try:
        plan_meta = db.query(ReviewPlanV2).filter(
            ReviewPlanV2.review_date == date
        ).first()

        if not plan_meta:
            return {
                "success": False,
                "message": f"日期 {date} 的计划不存在"
            }

        result = get_plan_data(db, plan_meta.id)
        return {
            "success": True,
            "data": result
        }
    except Exception as e:
        logger.exception(f"获取V2计划 by-date {date} 失败")
        return {
            "success": False,
            "message": f"查询失败: {str(e)}"
        }


@router.delete("/v2/clear")
def clear_v2_data(db: Session = Depends(get_analysis_db)):
    """清除所有V2数据"""
    try:
        db.query(SectorHeat).delete()
        db.query(TradingPlanV2).delete()
        db.query(SymbolScoreV2).delete()
        db.query(ReviewPlanV2).delete()
        db.commit()

        return {
            "success": True,
            "message": "V2复盘数据已清除"
        }
    except Exception as e:
        db.rollback()
        return {
            "success": False,
            "message": f"清除失败: {str(e)}"
        }
