from datetime import date
from fastapi import APIRouter, Depends, Form, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from sqlalchemy.orm import Session
from app.database import get_db
from app.models import Round, Position, Contract, Product

router = APIRouter(prefix="/positions", tags=["positions"])


def get_active_contracts(db: Session) -> list[str]:
    contracts = (
        db.query(Contract.code)
        .filter(Contract.is_active == True)
        .order_by(Contract.code)
        .all()
    )
    return [c[0] for c in contracts]


def get_product_contracts(db: Session) -> dict:
    result: dict[str, list[str]] = {}
    products = db.query(Product).order_by(Product.code).all()
    for p in products:
        codes = [c.code for c in p.contracts if c.is_active]
        if codes:
            result[p.code] = codes
    return result


@router.get("/", response_class=HTMLResponse)
def positions_page(request: Request, db: Session = Depends(get_db)):
    active_rounds = (
        db.query(Round)
        .filter(Round.status == "active")
        .order_by(Round.started_at.desc())
        .all()
    )

    # Compute stop-profit threshold: latest position A × point_value per round
    round_thresholds: dict[int, dict] = {}
    for r in active_rounds:
        if r.positions:
            latest_a = r.positions[-1].amp_threshold
        else:
            latest_a = 0
        contract = db.query(Contract).filter(Contract.code == r.contract_code).first()
        pv = contract.product.point_value if contract and contract.product else 20
        round_thresholds[r.id] = {
            "amp": latest_a,
            "point_value": pv,
            "daily_hands": r.daily_hands,
            "threshold": latest_a * pv * r.daily_hands,
        }

    template = request.app.state.templates.get_template("positions.html")
    return HTMLResponse(
        template.render(
            request=request,
            active_nav="positions",
            contracts=get_active_contracts(db),
            product_contracts=get_product_contracts(db),
            active_rounds=active_rounds,
            round_thresholds=round_thresholds,
        )
    )


@router.post("/round")
def create_round(
    request: Request,
    contract_code: str = Form(...),
    daily_hands: int = Form(1),
    db: Session = Depends(get_db),
):
    code = contract_code.upper()
    existing = db.query(Round).filter(
        Round.status == "active", Round.contract_code == code
    ).first()
    if existing:
        return RedirectResponse(f"/positions/?error={code} 已有活跃轮次", status_code=303)

    r = Round(
        contract_code=code,
        daily_hands=daily_hands,
        status="active",
        started_at=date.today(),
    )
    db.add(r)
    db.commit()
    return RedirectResponse("/positions/", status_code=303)


@router.post("/{round_id}/add")
def add_position(
    request: Request,
    round_id: int,
    open_price: int = Form(...),
    amp_threshold: int = Form(...),
    lock_price: str = Form(""),
    hands: int = Form(1),
    db: Session = Depends(get_db),
):
    r = db.query(Round).filter(Round.id == round_id).first()
    if not r or r.status != "active":
        return RedirectResponse("/positions/?error=轮次不存在或已结束", status_code=303)

    final_lock = int(lock_price) if lock_price else open_price + amp_threshold
    p = Position(
        round_id=r.id,
        open_price=open_price,
        amp_threshold=amp_threshold,
        lock_price=final_lock,
        hands=hands,
        opened_at=date.today(),
    )
    db.add(p)
    db.commit()
    return RedirectResponse("/positions/", status_code=303)


@router.post("/{position_id}/lock")
def lock_position(
    position_id: int,
    lock_price: str = Form(""),
    db: Session = Depends(get_db),
):
    p = db.query(Position).filter(Position.id == position_id).first()
    if p and p.locked_count < p.hands:
        if lock_price:
            p.lock_price = int(lock_price)
        p.locked_count += 1
        db.commit()
    return RedirectResponse("/positions/", status_code=303)


@router.post("/{position_id}/unlock")
def unlock_position(position_id: int, db: Session = Depends(get_db)):
    p = db.query(Position).filter(Position.id == position_id).first()
    if p and p.locked_count > 0:
        p.locked_count -= 1
        db.commit()
    return RedirectResponse("/positions/", status_code=303)


@router.post("/{position_id}/update-lock-price")
def update_lock_price(
    position_id: int,
    lock_price: int = Form(...),
    db: Session = Depends(get_db),
):
    p = db.query(Position).filter(Position.id == position_id).first()
    if p and p.locked_count == 0:
        p.lock_price = lock_price
        db.commit()
    return RedirectResponse("/positions/", status_code=303)


@router.post("/{round_id}/max-locks")
def update_max_locks(
    round_id: int,
    max_locks: int = Form(...),
    db: Session = Depends(get_db),
):
    r = db.query(Round).filter(Round.id == round_id).first()
    if r and r.status == "active" and 1 <= max_locks <= 10:
        r.max_locks = max_locks
        db.commit()
    return RedirectResponse("/positions/", status_code=303)


@router.post("/{round_id}/close")
def close_round(
    request: Request,
    round_id: int,
    result: str = Form(...),
    db: Session = Depends(get_db),
):
    r = db.query(Round).filter(Round.id == round_id).first()
    if r and r.status == "active":
        r.status = result
        db.commit()
    return RedirectResponse("/positions/", status_code=303)


@router.post("/{round_id}/delete")
def delete_round(round_id: int, db: Session = Depends(get_db)):
    r = db.query(Round).filter(Round.id == round_id).first()
    if r:
        db.delete(r)
        db.commit()
    return RedirectResponse("/positions/", status_code=303)
