from __future__ import annotations

from sqlalchemy import func
from sqlalchemy.orm import Session

from ..database.orm import AttendanceRecordORM, SalaryRecordORM


class ReportRepository:
    """报表仓库：只负责聚合工资、考勤等已落库数据。"""

    def __init__(self, session: Session):
        self.session = session

    def payroll_totals(self, *, salary_month: str | None = None) -> dict[str, float]:
        query = self.session.query(
            func.count(SalaryRecordORM.id),
            func.sum(SalaryRecordORM.base_pay),
            func.sum(SalaryRecordORM.commission_amount),
            func.sum(SalaryRecordORM.overtime_pay),
            func.sum(SalaryRecordORM.deduction_amount),
            func.sum(SalaryRecordORM.gross_salary),
            func.sum(SalaryRecordORM.net_salary),
        )
        if salary_month:
            query = query.filter(SalaryRecordORM.salary_month == salary_month)
        row = query.one()
        return {
            "employee_count": int(row[0] or 0),
            "base_pay": float(row[1] or 0),
            "commission_amount": float(row[2] or 0),
            "overtime_pay": float(row[3] or 0),
            "deduction_amount": float(row[4] or 0),
            "gross_salary": float(row[5] or 0),
            "net_salary": float(row[6] or 0),
        }

    def attendance_totals(self, *, salary_month: str | None = None) -> dict[str, float]:
        query = self.session.query(
            func.count(AttendanceRecordORM.id),
            func.sum(AttendanceRecordORM.overtime_hours),
            func.sum(AttendanceRecordORM.leave_hours),
            func.sum(AttendanceRecordORM.missing_card_count),
        )
        if salary_month:
            query = query.filter(func.date_format(AttendanceRecordORM.work_date, "%Y-%m") == salary_month)
        row = query.one()
        return {
            "attendance_record_count": int(row[0] or 0),
            "overtime_hours": float(row[1] or 0),
            "leave_hours": float(row[2] or 0),
            "missing_card_count": float(row[3] or 0),
        }

    def department_totals(self, *, salary_month: str | None = None) -> list[dict[str, float | str]]:
        query = self.session.query(
            SalaryRecordORM.department,
            func.count(SalaryRecordORM.id),
            func.sum(SalaryRecordORM.gross_salary),
            func.sum(SalaryRecordORM.net_salary),
        )
        if salary_month:
            query = query.filter(SalaryRecordORM.salary_month == salary_month)
        rows = query.group_by(SalaryRecordORM.department).order_by(func.sum(SalaryRecordORM.net_salary).desc()).all()
        return [
            {
                "department": department or "未分配",
                "employee_count": int(count or 0),
                "gross_salary": float(gross or 0),
                "net_salary": float(net or 0),
            }
            for department, count, gross, net in rows
        ]

    def recent_salary_records(self, *, salary_month: str | None = None, limit: int = 10) -> list[SalaryRecordORM]:
        query = self.session.query(SalaryRecordORM)
        if salary_month:
            query = query.filter(SalaryRecordORM.salary_month == salary_month)
        return query.order_by(SalaryRecordORM.created_at.desc(), SalaryRecordORM.id.desc()).limit(limit).all()
