from __future__ import annotations

import uuid
from datetime import datetime
from decimal import Decimal

from app.models.site_operations_schemas import (
    MaterialRequisitionCreateRequest,
    MaterialRequisitionRecord,
    MRStatusEnum,
)

from .constants import PROJECT_NAMES


class MaterialRequisitionOperationsMixin:
    """Material Requisition (MR) workflow mixin."""

    def create_material_requisition(
        self, payload: MaterialRequisitionCreateRequest
    ) -> MaterialRequisitionRecord:
        mr_id = f"MR-{payload.project_code[:6]}-{uuid.uuid4().hex[:6].upper()}"
        proj_name = PROJECT_NAMES.get(
            payload.project_code, f"Dự Án {payload.project_code}"
        )

        total_est = sum(
            (item.requested_qty * item.unit_price_estimate for item in payload.items),
            Decimal("0.0000"),
        )

        record = MaterialRequisitionRecord(
            mr_id=mr_id,
            project_code=payload.project_code,
            project_name=proj_name,
            wbs_task_code=payload.wbs_task_code,
            urgency=payload.urgency,
            status=MRStatusEnum.SUBMITTED,
            required_date=payload.required_date,
            requester_name=payload.requester_name,
            total_estimated_amount=total_est,
            items=payload.items,
            created_at=datetime.now(),
            updated_at=datetime.now(),
        )
        self._requisitions[mr_id] = record
        return record

    def update_mr_status(
        self, mr_id: str, status: MRStatusEnum, approver_name: str | None = None
    ) -> MaterialRequisitionRecord:
        if mr_id not in self._requisitions:
            raise KeyError(f"MR {mr_id} not found")

        record = self._requisitions[mr_id]
        record.status = status
        record.updated_at = datetime.now()
        if status == MRStatusEnum.APPROVED:
            record.approver_name = approver_name or "Chỉ huy trưởng"
            record.approval_timestamp = datetime.now()
            for item in record.items:
                if item.approved_qty == Decimal("0.0000"):
                    item.approved_qty = item.requested_qty

        return record

    def list_requisitions(
        self, project_code: str | None = None, status: MRStatusEnum | None = None
    ) -> list[MaterialRequisitionRecord]:
        results = list(self._requisitions.values())
        if project_code:
            results = [r for r in results if r.project_code == project_code]
        if status:
            results = [r for r in results if r.status == status]
        return results
