from __future__ import annotations

import logging
from datetime import datetime, timezone
from typing import Any

from app.core.postgres import PostgresClient
from app.models.schemas import CompanyOperationalStateResponse
from app.modules.core.application.employee_logs_service import EmployeeLogsService
from app.modules.operations.application.operations_case_management_service import (
    OperationsCaseManagementService,
)
from app.modules.projects.application.project_management_service import ProjectManagementService
from app.modules.core.application.remediation_planning_service import RemediationPlanningService

from .core_delegations import CompanyStateDelegationsMixin
from .core_safe_fetchers import CompanyStateSafeFetchersMixin
from .helpers import merge_messages

logger = logging.getLogger("dscons.company_state.core")


class CompanyOperationalStateService(
    CompanyStateSafeFetchersMixin,
    CompanyStateDelegationsMixin,
):
    """Build a consolidated operational state across projects, workforce, and dossier reviews."""

    def __init__(
        self,
        postgres_client: PostgresClient | None = None,
        project_management_service: ProjectManagementService | None = None,
        employee_logs_service: EmployeeLogsService | None = None,
        operations_case_management_service: OperationsCaseManagementService
        | None = None,
        remediation_planning_service: RemediationPlanningService | None = None,
    ) -> None:
        self._postgres_client = postgres_client or PostgresClient()
        self._project_management_service = (
            project_management_service
            or ProjectManagementService(self._postgres_client)
        )
        self._employee_logs_service = employee_logs_service or EmployeeLogsService(
            self._postgres_client
        )
        self._operations_case_management_service = (
            operations_case_management_service
            or OperationsCaseManagementService(self._postgres_client)
        )
        self._remediation_planning_service = (
            remediation_planning_service
            or RemediationPlanningService(self._postgres_client)
        )

    def get_company_operational_state(self) -> CompanyOperationalStateResponse:
        """Trả trạng thái vận hành tổng hợp."""
        generated_at = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
        project_response = self._safe_get_project_management_data()
        employee_response = self._safe_get_employee_logs()
        dossier_response, dossier_source, dossier_used_fallback, dossier_message = (
            self._fetch_dossier_reviews()
        )
        operations_cases_response = self._safe_list_operations_cases()
        operations_actions_response = self._safe_list_operations_actions()
        operations_blockers_response = self._safe_list_operations_blockers()
        remediation_response = self._safe_list_remediation_plans()

        projects = [self._build_project_state(item) for item in project_response.items]
        risks = self._build_risks(project_response.items, dossier_response)
        blocked_items = self._build_blocked_items(
            projects=project_response.items,
            dossier_reviews=dossier_response,
            operations_blockers=operations_blockers_response.items,
        )
        backlog = self._build_backlog(
            projects=project_response.items,
            dossier_reviews=dossier_response,
            operations_actions=operations_actions_response.items,
        )
        workforce = self._build_workforce(employee_response.items)
        summary = self._build_summary(
            projects=projects,
            risks=risks,
            blocked_items=blocked_items,
            backlog=backlog,
            workforce=workforce,
            operations_cases=operations_cases_response.items,
            operations_actions=operations_actions_response.items,
            dossier_reviews=dossier_response,
        )
        source_status = self._build_source_status_list(
            project_response=project_response,
            employee_response=employee_response,
            dossier_response=dossier_response,
            dossier_source=dossier_source,
            dossier_used_fallback=dossier_used_fallback,
            dossier_message=dossier_message,
            operations_cases_response=operations_cases_response,
            operations_actions_response=operations_actions_response,
            operations_blockers_response=operations_blockers_response,
            remediation_response=remediation_response,
        )
        used_fallback = any(item.used_fallback for item in source_status)
        message = self._build_response_message(
            project_response.message,
            employee_response.message,
            dossier_message,
            operations_cases_response.message,
            operations_actions_response.message,
            operations_blockers_response.message,
            remediation_response.message,
        )

        response_payload: dict[str, Any] = {
            "generated_at": generated_at,
            "source": "aggregated",
            "used_fallback": used_fallback,
            "summary": summary,
            "projects": projects,
            "risks": risks,
            "blocked_items": blocked_items,
            "backlog": backlog,
            "workforce": workforce,
            "source_status": source_status,
            "message": message,
        }
        optional_payload, optional_message = self._build_optional_top_level_payload(
            summary=summary,
            operations_cases_response=operations_cases_response,
            operations_actions_response=operations_actions_response,
            operations_blockers_response=operations_blockers_response,
            remediation_response=remediation_response,
            dossier_response=dossier_response,
        )
        self._attach_supported_optional_fields(response_payload, optional_payload)
        final_message = merge_messages(message, optional_message)
        if final_message is not None:
            response_payload["message"] = final_message
        return CompanyOperationalStateResponse(**response_payload)
