from __future__ import annotations

from datetime import UTC, datetime
from time import perf_counter
from typing import Any

from sqlalchemy.orm import Session

from app.core.agent_enums import (
    AgentName,
    AgentPermissionLevel,
    AgentRunSource,
    AgentRunStatus,
    AgentToolType,
)
from app.services.agent_runs import AgentRunService
from app.services.finance_report_tenant import require_report_tenant_id
from app.services.hermes_employee_profile_scanner import HermesEmployeeProfileScannerService

EMPLOYEE_PROFILE_SCAN_TASK_TYPE = "employee_behavior_profile_scan"
EMPLOYEE_PROFILE_SCAN_TOOL_NAME = "digital_employee.employee_behavior_profile.scan"


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

    def refresh_profiles(
        self,
        *,
        source: str = AgentRunSource.SCHEDULE.value,
        tenant_id: str = "default",
    ) -> dict[str, Any]:
        tenant = require_report_tenant_id(tenant_id)
        run_service = AgentRunService(self.db)
        run = run_service.create_run(
            agent=AgentName.HERMES.value,
            source=source,
            tenant_id=tenant,
            user_id="digital_employee",
            ontology_json={
                "scenario": "employee_behavior_profile",
                "intent": "scan",
            },
            route_json={
                "task_type": EMPLOYEE_PROFILE_SCAN_TASK_TYPE,
                "job_type": EMPLOYEE_PROFILE_SCAN_TASK_TYPE,
                "selected_agent": AgentName.HERMES.value,
                "phase": "running",
                "heartbeat_at": datetime.now(UTC).isoformat(),
            },
            permission_level=AgentPermissionLevel.READ.value,
            status=AgentRunStatus.RUNNING.value,
        )
        timer = perf_counter()
        try:
            # 画像快照表的 source_task_log_id 外键指向 Hermes 任务日志。
            # 这里用 agent_runs 记录数字员工轨迹，因此不写入该外键，避免错误关联。
            summary = HermesEmployeeProfileScannerService(self.db).scan_employee_profiles(
                log_id=None,
                tenant_id=tenant,
            )
            duration_ms = int((perf_counter() - timer) * 1000)
            report = self._build_report(summary)
            response = {
                "task_type": EMPLOYEE_PROFILE_SCAN_TASK_TYPE,
                "summary": summary,
                "report": report,
            }
            run_service.record_tool_call(
                run_id=run.run_id,
                tool_type=AgentToolType.DATABASE.value,
                tool_name=EMPLOYEE_PROFILE_SCAN_TOOL_NAME,
                request_json={
                    "task_type": EMPLOYEE_PROFILE_SCAN_TASK_TYPE,
                    "tenant_id": tenant,
                },
                response_json=response,
                status=AgentRunStatus.SUCCEEDED.value,
                duration_ms=duration_ms,
            )
            run_service.merge_route_json(
                run.run_id,
                {
                    "phase": "succeeded",
                    "summary": summary,
                    "report": report,
                    "heartbeat_at": datetime.now(UTC).isoformat(),
                },
                status=AgentRunStatus.SUCCEEDED.value,
                result_summary=(
                    "员工行为画像已生成："
                    f"覆盖 {summary.get('target_employee_count', 0)} 人，"
                    f"快照 {summary.get('snapshot_count', 0)} 条，"
                    f"重点关注 {summary.get('high_attention_employee_count', 0)} 人。"
                ),
                finished_at=datetime.now(UTC),
            )
            return response
        except Exception as exc:
            run_service.record_tool_call(
                run_id=run.run_id,
                tool_type=AgentToolType.DATABASE.value,
                tool_name=EMPLOYEE_PROFILE_SCAN_TOOL_NAME,
                request_json={
                    "task_type": EMPLOYEE_PROFILE_SCAN_TASK_TYPE,
                    "tenant_id": tenant,
                },
                response_json={},
                status=AgentRunStatus.FAILED.value,
                duration_ms=int((perf_counter() - timer) * 1000),
                error_message=str(exc),
            )
            run_service.merge_route_json(
                run.run_id,
                {
                    "phase": "failed",
                    "heartbeat_at": datetime.now(UTC).isoformat(),
                },
                status=AgentRunStatus.FAILED.value,
                error_message=str(exc),
                finished_at=datetime.now(UTC),
            )
            raise

    @staticmethod
    def _build_report(summary: dict[str, Any]) -> dict[str, Any]:
        return {
            "title": "员工财务行为画像扫描报告",
            "targetEmployeeCount": int(summary.get("target_employee_count") or 0),
            "profileSnapshotCount": int(summary.get("snapshot_count") or 0),
            "highAttentionEmployeeCount": int(summary.get("high_attention_employee_count") or 0),
            "windowDays": list(summary.get("window_days") or []),
            "algorithmVersion": str(summary.get("algorithm_version") or ""),
            "baselineSummary": summary.get("baseline_summary") or {},
        }
