from __future__ import annotations

from sqlalchemy import select
from sqlalchemy.orm import Session, selectinload

from app.algorithem.risk_graph.models import RiskGraphClaimSnapshot
from app.algorithem.risk_graph.profile_baselines import ProfileBaselineUpdater
from app.core.logging import get_logger
from app.models.financial_record import ExpenseClaim
from app.services.employee_behavior_profile_service import EmployeeBehaviorProfileService
from app.services.finance_report_tenant import require_report_tenant_id

logger = get_logger("app.services.hermes_employee_profile_scanner")


class HermesEmployeeProfileScannerService:
    def __init__(self, db: Session) -> None:
        self.db = db

    def scan_employee_profiles(
        self,
        log_id: str | None = None,
        *,
        tenant_id: str = "default",
    ) -> dict:
        tenant = require_report_tenant_id(tenant_id)
        logger.info("Starting Hermes employee behavior profile scan...")
        summary = EmployeeBehaviorProfileService(
            self.db,
            tenant_id=tenant,
        ).scan_profiles(log_id=log_id)
        baseline_summary = self._build_baseline_summary(tenant_id=tenant)
        summary["baseline_summary"] = baseline_summary
        logger.info(
            "Hermes employee profile scan completed: %s",
            self._build_log_summary(summary),
        )
        return summary

    def _build_log_summary(self, summary: dict) -> dict:
        baseline_summary = self._as_dict(summary.get("baseline_summary"))
        buckets = baseline_summary.get("buckets")
        return {
            "target_employee_count": self._to_int(summary.get("target_employee_count")),
            "snapshot_count": self._to_int(summary.get("snapshot_count")),
            "high_attention_employee_count": self._to_int(
                summary.get("high_attention_employee_count")
            ),
            "window_days": summary.get("window_days") or [],
            "baseline_bucket_count": len(buckets) if isinstance(buckets, list) else 0,
        }

    def _build_baseline_summary(self, *, tenant_id: str) -> dict:
        stmt = (
            select(ExpenseClaim)
            .options(selectinload(ExpenseClaim.items))
            .where(ExpenseClaim.tenant_id == tenant_id)
            .order_by(ExpenseClaim.occurred_at.desc())
            .limit(500)
        )
        claims = [RiskGraphClaimSnapshot.from_orm(claim) for claim in self.db.scalars(stmt).all()]
        return ProfileBaselineUpdater().build_from_claims(claims).as_dict()

    @staticmethod
    def _as_dict(value: object) -> dict:
        return value if isinstance(value, dict) else {}

    @staticmethod
    def _to_int(value: object) -> int:
        try:
            return int(value or 0)
        except (TypeError, ValueError):
            return 0
