from fastapi import APIRouter, Depends, Form, Request
from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
from sqlalchemy.orm import Session
from app.database import get_db
from app.models import Product, Contract, DailyBar, PositionRanking
from app.collector import (
    sync_one_contract, sync_contract_bars_bg, sync_positions_bg, get_progress,
)

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

EXCHANGES = ["CZCE", "DCE", "SHFE", "CFFEX", "INE"]


@router.get("/", response_class=HTMLResponse)
def admin_page(request: Request, db: Session = Depends(get_db)):
    products = db.query(Product).order_by(Product.code).all()

    product_data = []
    for p in products:
        contracts = (
            db.query(Contract)
            .filter(Contract.product_id == p.id)
            .order_by(Contract.code)
            .all()
        )
        contract_list = []
        for c in contracts:
            bar_count = (
                db.query(DailyBar)
                .filter(DailyBar.contract == c.code)
                .count()
            )
            pos_days = len({
                r[0] for r in
                db.query(PositionRanking.date)
                .filter(PositionRanking.contract_code == c.code)
                .distinct().all()
            })
            contract_list.append({
                "id": c.id, "code": c.code, "name": c.name,
                "is_active": c.is_active, "bar_count": bar_count,
                "pos_days": pos_days,
            })

        product_data.append({
            "id": p.id,
            "code": p.code,
            "name": p.name,
            "exchange": p.exchange,
            "contracts": contract_list,
        })

    total_contracts = sum(len(pd["contracts"]) for pd in product_data)

    template = request.app.state.templates.get_template("admin.html")
    return HTMLResponse(
        template.render(
            request=request,
            active_nav="admin",
            products=product_data,
            total_contracts=total_contracts,
            exchanges=EXCHANGES,
        )
    )


@router.post("/product")
def create_product(
    request: Request,
    code: str = Form(...),
    name: str = Form(...),
    exchange: str = Form(...),
    db: Session = Depends(get_db),
):
    existing = db.query(Product).filter(Product.code == code.upper()).first()
    if not existing:
        p = Product(code=code.upper(), name=name, exchange=exchange)
        db.add(p)
        db.commit()
    return RedirectResponse("/admin/?tab=product", status_code=303)


@router.post("/contract")
def create_contract(
    request: Request,
    product_id: int = Form(...),
    month: str = Form(...),
    db: Session = Depends(get_db),
):
    product = db.query(Product).filter(Product.id == product_id).first()
    if not product:
        return RedirectResponse("/admin/?tab=contract", status_code=303)

    code = (product.code + month).upper()
    name = month.upper()

    existing = db.query(Contract).filter(Contract.code == code).first()
    if not existing:
        c = Contract(
            product_id=product_id,
            code=code,
            name=name,
            is_active=True,
        )
        db.add(c)
        db.commit()
    return RedirectResponse("/admin/?tab=contract", status_code=303)


@router.post("/contract/{contract_id}/toggle")
def toggle_contract(contract_id: int, db: Session = Depends(get_db)):
    c = db.query(Contract).filter(Contract.id == contract_id).first()
    if c:
        c.is_active = not c.is_active
        db.commit()
    return RedirectResponse("/admin/?tab=contract", status_code=303)


@router.post("/contract/{contract_id}/delete")
def delete_contract(contract_id: int, db: Session = Depends(get_db)):
    c = db.query(Contract).filter(Contract.id == contract_id).first()
    if c:
        db.query(DailyBar).filter(DailyBar.contract == c.code).delete()
        db.query(PositionRanking).filter(PositionRanking.contract_code == c.code).delete()
        db.delete(c)
        db.commit()
    return RedirectResponse("/admin/?tab=contract", status_code=303)


@router.post("/product/{product_id}/delete")
def delete_product(product_id: int, db: Session = Depends(get_db)):
    p = db.query(Product).filter(Product.id == product_id).first()
    if p:
        for c in p.contracts:
            db.query(DailyBar).filter(DailyBar.contract == c.code).delete()
            db.query(PositionRanking).filter(PositionRanking.contract_code == c.code).delete()
        db.delete(p)
        db.commit()
    return RedirectResponse("/admin/?tab=product", status_code=303)


@router.post("/sync/{contract_code}")
def sync_single(contract_code: str):
    count = sync_one_contract(contract_code.upper())
    return RedirectResponse(f"/admin/?tab=sync&synced={count}", status_code=303)


@router.post("/sync/{contract_code}/bg")
def sync_single_bg(contract_code: str):
    ok = sync_contract_bars_bg(contract_code.upper())
    return JSONResponse({"ok": ok})


@router.post("/sync-positions/{contract_code}/bg")
def sync_positions_bg_ep(contract_code: str):
    ok = sync_positions_bg(contract_code.upper())
    return JSONResponse({"ok": ok})


@router.get("/sync-status")
def sync_status():
    return JSONResponse(get_progress())


@router.post("/sync/product/{product_id}")
def sync_product(product_id: int, request: Request, db: Session = Depends(get_db)):
    contracts = db.query(Contract).filter(
        Contract.product_id == product_id, Contract.is_active == True
    ).all()
    total = 0
    for c in contracts:
        total += sync_one_contract(c.code)
    return RedirectResponse(f"/admin/?tab=sync&synced={total}", status_code=303)
