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 OptionTrade, Contract, Product

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

OPTION_TYPES = [("C", "C 看涨"), ("P", "P 看跌")]
OPTION_DIRECTIONS = [("buy", "买"), ("sell", "卖")]


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


def today_str() -> str:
    return date.today().isoformat()


@router.get("/", response_class=HTMLResponse)
def option_page(request: Request, db: Session = Depends(get_db)):
    view = request.query_params.get("view", "")
    open_trades = (
        db.query(OptionTrade).filter(OptionTrade.status == "open")
        .order_by(OptionTrade.open_date.desc()).all()
    )
    closed_trades = (
        db.query(OptionTrade).filter(OptionTrade.status == "closed")
        .order_by(OptionTrade.close_date.desc()).limit(50).all()
    )

    template = request.app.state.templates.get_template("options.html")
    return HTMLResponse(
        template.render(
            request=request,
            active_nav="options",
            product_contracts=get_product_contracts(db),
            option_types=OPTION_TYPES,
            option_directions=OPTION_DIRECTIONS,
            open_trades=open_trades,
            closed_trades=closed_trades,
            today=today_str(),
            weekdays=["周一","周二","周三","周四","周五","周六","周日"],
        )
    )


@router.post("/open")
def open_trade(
    request: Request,
    contract_code: str = Form(...),
    option_type: str = Form(...),
    direction: str = Form(...),
    strike_price: float = Form(...),
    open_date: str = Form(...),
    open_price: float = Form(...),
    open_fee: float = Form(0.0),
    db: Session = Depends(get_db),
):
    code = contract_code.upper()
    contract = db.query(Contract).filter(Contract.code == code).first()
    if contract:
        product = contract.product
    else:
        product = db.query(Product).filter(Product.code == code[:2]).first()
    product_code = product.code if product else code[:2]
    point_value = product.point_value if product else 20

    t = OptionTrade(
        product_code=product_code,
        contract_code=code,
        option_type=option_type,
        direction=direction,
        strike_price=strike_price,
        open_date=date.fromisoformat(open_date),
        open_price=open_price,
        open_fee=open_fee,
        point_value=point_value,
        status="open",
    )
    db.add(t)
    db.commit()
    return RedirectResponse("/options/", status_code=303)


@router.post("/{trade_id}/close")
def close_trade(
    request: Request,
    trade_id: int,
    close_date: str = Form(...),
    close_price: float = Form(...),
    close_fee: float = Form(0.0),
    db: Session = Depends(get_db),
):
    t = db.query(OptionTrade).filter(OptionTrade.id == trade_id).first()
    if t and t.status == "open":
        t.close_date = date.fromisoformat(close_date)
        t.close_price = close_price
        t.close_fee = close_fee
        t.status = "closed"
        db.commit()
    return RedirectResponse("/options/", status_code=303)


@router.post("/{trade_id}/edit")
def edit_trade(
    request: Request,
    trade_id: int,
    contract_code: str = Form(...),
    option_type: str = Form(...),
    direction: str = Form(...),
    strike_price: float = Form(...),
    open_date: str = Form(...),
    open_price: float = Form(...),
    open_fee: float = Form(0.0),
    close_date: str = Form(""),
    close_price: str = Form(""),
    close_fee: str = Form(""),
    db: Session = Depends(get_db),
):
    t = db.query(OptionTrade).filter(OptionTrade.id == trade_id).first()
    if t:
        code = contract_code.upper()
        contract = db.query(Contract).filter(Contract.code == code).first()
        if contract:
            product = contract.product
        else:
            product = db.query(Product).filter(Product.code == code[:2]).first()
        t.product_code = product.code if product else code[:2]
        t.point_value = product.point_value if product else 20
        t.contract_code = code
        t.option_type = option_type
        t.direction = direction
        t.strike_price = strike_price
        t.open_date = date.fromisoformat(open_date)
        t.open_price = open_price
        t.open_fee = open_fee
        if close_date and close_price:
            t.close_date = date.fromisoformat(close_date)
            t.close_price = float(close_price)
            t.close_fee = float(close_fee) if close_fee else 0.0
        db.commit()
    return RedirectResponse("/options/", status_code=303)


@router.post("/{trade_id}/delete")
def delete_trade(trade_id: int, db: Session = Depends(get_db)):
    t = db.query(OptionTrade).filter(OptionTrade.id == trade_id).first()
    if t:
        db.delete(t)
        db.commit()
    return RedirectResponse("/options/", status_code=303)
