from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from sqlalchemy import func, and_, extract
from ..database import get_db
from ..dependencies import get_current_user
from ..models import DailyShift, PumpReading, Staff, Allowance, SystemSetting
from ..schemas import PerformanceSummary

router = APIRouter()


def _compute_performance(month: int, year: int, db: Session) -> list[dict]:
    """Compute performance metrics for all active staff for a given month/year."""
    active_staff = db.query(Staff).filter(Staff.status == 'ACTIVE').all()
    results = []

    for s in active_staff:
        shifts = (
            db.query(DailyShift)
            .filter(
                and_(
                    DailyShift.staff_id == s.id,
                    extract('month', DailyShift.record_date) == month,
                    extract('year',  DailyShift.record_date) == year,
                )
            )
            .all()
        )

        shifts_worked = len(shifts)
        shift_ids     = [sh.id for sh in shifts]

        total_liters = 0.0
        total_sale   = 0.0

        if shift_ids:
            agg = (
                db.query(
                    func.coalesce(func.sum(PumpReading.sale_ltr),    0).label('ltr'),
                    func.coalesce(func.sum(PumpReading.sale_amount), 0).label('amt'),
                )
                .filter(PumpReading.shift_id.in_(shift_ids))
                .first()
            )
            total_liters = float(agg.ltr)
            total_sale   = float(agg.amt)

        score = round(shifts_worked * total_liters, 2)

        results.append({
            "staff_id":      s.id,
            "staff_name":    s.full_name,
            "shifts_worked": shifts_worked,
            "total_liters":  round(total_liters, 3),
            "total_sale":    round(total_sale, 2),
            "days_present":  shifts_worked,  # 1 shift = present for that shift period
            "score":         score,
        })

    results.sort(key=lambda x: x["score"], reverse=True)
    return results


@router.get("/performance", response_model=list[PerformanceSummary])
def get_performance(
    month: int = Query(..., ge=1, le=12),
    year:  int = Query(..., ge=2020),
    db:    Session = Depends(get_db),
    _=Depends(get_current_user),
):
    return _compute_performance(month, year, db)


@router.get("/performance/top", response_model=list[PerformanceSummary])
def get_top_performers(
    month: int = Query(..., ge=1, le=12),
    year:  int = Query(..., ge=2020),
    limit: int = Query(default=3, ge=1, le=10),
    db:    Session = Depends(get_db),
    _=Depends(get_current_user),
):
    return _compute_performance(month, year, db)[:limit]


@router.post("/performance/award", status_code=201)
def award_performance_bonus(
    month: int = Query(..., ge=1, le=12),
    year:  int = Query(..., ge=2020),
    limit: int = Query(default=3, ge=1, le=10),
    db:    Session = Depends(get_db),
    user=Depends(get_current_user),
):
    """Create PERFORMANCE allowance entries for the top N performers."""
    pf_setting = db.query(SystemSetting).filter(
        SystemSetting.setting_key == 'allowance.performance.amount'
    ).first()
    pf_enabled = db.query(SystemSetting).filter(
        SystemSetting.setting_key == 'allowance.performance.enabled'
    ).first()

    if pf_enabled and pf_enabled.setting_value.lower() != 'true':
        return {"message": "Performance allowance is disabled", "created": 0}

    amount = float(pf_setting.setting_value) if pf_setting else 2000.0

    top = _compute_performance(month, year, db)[:limit]
    created = 0

    for perf in top:
        exists = (
            db.query(Allowance)
            .filter(
                and_(
                    Allowance.staff_id       == perf["staff_id"],
                    Allowance.month          == month,
                    Allowance.year           == year,
                    Allowance.allowance_type == 'PERFORMANCE',
                )
            )
            .first()
        )
        if not exists:
            db.add(Allowance(
                staff_id=perf["staff_id"],
                month=month,
                year=year,
                allowance_type='PERFORMANCE',
                amount=amount,
                notes=f'Top performer award – score {perf["score"]}',
                created_by=user.id,
            ))
            created += 1

    db.commit()
    return {"created": created, "month": month, "year": year, "amount": amount}
