from __future__ import annotations

import logging

from app.modules.projects.domain.ports.project_repository_port import ProjectCrudPort
from app.models.schemas import ProjectManagementResponse, ProjectManagementRecord

from .contract_compliance import ContractComplianceMixin

logger = logging.getLogger("dscons.project_management")


class ProjectManagementService(ContractComplianceMixin):
    """Fetch project management data from PostgreSQL with safe fallback behavior."""

    def __init__(self, repo: ProjectCrudPort | None = None) -> None:
        if repo is None:
            # Lazy import to keep Domain layer clean — only at composition root
            from app.core.postgres import PostgresClient
            repo = PostgresClient()
        self._repo = repo

    def get_project_management_data(self) -> ProjectManagementResponse:
        """Return PostgreSQL-backed data. Strictly no synthetic/mock data per Rule 1."""
        if not self._repo.is_enabled():
            return ProjectManagementResponse(
                items=[],
                source="postgres",
                used_fallback=False,
                message="PostgreSQL chưa được cấu hình nên chưa thể hiển thị dữ liệu quản lý dự án thực tế."
            )

        try:
            items = self._repo.fetch_project_management_records()
        except Exception as exc:
            return ProjectManagementResponse(
                items=[],
                source="postgres",
                used_fallback=False,
                message=f"Không thể kết nối PostgreSQL. Chi tiết: {exc}"
            )

        if not items:
            return ProjectManagementResponse(
                items=[],
                source="postgres",
                used_fallback=False,
                message="PostgreSQL không có dữ liệu quản lý dự án thực tế trong các bảng vận hành."
            )

        return ProjectManagementResponse(
            items=[ProjectManagementRecord(**item) for item in items],
            source="postgres",
            used_fallback=False,
            message=None,
        )
