"""
SCM Domain Events — Internal domain events.

رویدادهای داخلی ماژول SCM.
"""
from dataclasses import dataclass
from datetime import datetime
from decimal import Decimal
from typing import Optional, List
from uuid import UUID


@dataclass(frozen=True)
class SCMDomainEvent:
    """رویداد پایه ماژول SCM."""
    event_id: UUID
    tenant_id: UUID
    occurred_at: datetime
    version: int = 1


# ─── Vendor Events ────────────────────────────────────────────

@dataclass(frozen=True)
class VendorCreatedEvent(SCMDomainEvent):
    event_type: str = "scm.vendor.created"
    vendor_id: Optional[UUID] = None
    vendor_code: str = ""
    vendor_name: str = ""
    category_id: Optional[UUID] = None


@dataclass(frozen=True)
class VendorUpdatedEvent(SCMDomainEvent):
    event_type: str = "scm.vendor.updated"
    vendor_id: Optional[UUID] = None
    vendor_code: str = ""
    changed_fields: tuple = ()


@dataclass(frozen=True)
class VendorBlockedEvent(SCMDomainEvent):
    event_type: str = "scm.vendor.blocked"
    vendor_id: Optional[UUID] = None
    vendor_code: str = ""
    reason: str = ""


@dataclass(frozen=True)
class VendorActivatedEvent(SCMDomainEvent):
    event_type: str = "scm.vendor.activated"
    vendor_id: Optional[UUID] = None
    vendor_code: str = ""


# ─── PR Events ────────────────────────────────────────────────

@dataclass(frozen=True)
class PRCreatedEvent(SCMDomainEvent):
    event_type: str = "scm.pr.created"
    pr_id: Optional[UUID] = None
    pr_number: str = ""
    requester_id: Optional[UUID] = None
    total_amount: Decimal = Decimal("0")


@dataclass(frozen=True)
class PRApprovedEvent(SCMDomainEvent):
    event_type: str = "scm.pr.approved"
    pr_id: Optional[UUID] = None
    pr_number: str = ""
    approved_by_id: Optional[UUID] = None


@dataclass(frozen=True)
class PRRejectedEvent(SCMDomainEvent):
    event_type: str = "scm.pr.rejected"
    pr_id: Optional[UUID] = None
    pr_number: str = ""
    reason: str = ""


@dataclass(frozen=True)
class PRConvertedEvent(SCMDomainEvent):
    event_type: str = "scm.pr.converted"
    pr_id: Optional[UUID] = None
    pr_number: str = ""
    po_id: Optional[UUID] = None
    po_number: str = ""


# ─── RFQ Events ───────────────────────────────────────────────

@dataclass(frozen=True)
class RFQCreatedEvent(SCMDomainEvent):
    event_type: str = "scm.rfq.created"
    rfq_id: Optional[UUID] = None
    rfq_number: str = ""


@dataclass(frozen=True)
class RFQSentEvent(SCMDomainEvent):
    event_type: str = "scm.rfq.sent"
    rfq_id: Optional[UUID] = None
    rfq_number: str = ""
    vendor_ids: tuple = ()


@dataclass(frozen=True)
class RFQAwardedEvent(SCMDomainEvent):
    event_type: str = "scm.rfq.awarded"
    rfq_id: Optional[UUID] = None
    rfq_number: str = ""
    awarded_vendor_id: Optional[UUID] = None


@dataclass(frozen=True)
class RFQClosedEvent(SCMDomainEvent):
    event_type: str = "scm.rfq.closed"
    rfq_id: Optional[UUID] = None
    rfq_number: str = ""


# ─── PO Events ────────────────────────────────────────────────

@dataclass(frozen=True)
class POCreatedEvent(SCMDomainEvent):
    event_type: str = "scm.po.created"
    po_id: Optional[UUID] = None
    po_number: str = ""
    vendor_id: Optional[UUID] = None
    total_amount: Decimal = Decimal("0")


@dataclass(frozen=True)
class POApprovedEvent(SCMDomainEvent):
    event_type: str = "scm.po.approved"
    po_id: Optional[UUID] = None
    po_number: str = ""
    approved_by_id: Optional[UUID] = None


@dataclass(frozen=True)
class POSentEvent(SCMDomainEvent):
    event_type: str = "scm.po.sent"
    po_id: Optional[UUID] = None
    po_number: str = ""
    vendor_id: Optional[UUID] = None


@dataclass(frozen=True)
class POPartiallyReceivedEvent(SCMDomainEvent):
    event_type: str = "scm.po.partially_received"
    po_id: Optional[UUID] = None
    po_number: str = ""


@dataclass(frozen=True)
class POFullyReceivedEvent(SCMDomainEvent):
    event_type: str = "scm.po.fully_received"
    po_id: Optional[UUID] = None
    po_number: str = ""


@dataclass(frozen=True)
class POCancelledEvent(SCMDomainEvent):
    event_type: str = "scm.po.cancelled"
    po_id: Optional[UUID] = None
    po_number: str = ""


@dataclass(frozen=True)
class POClosedEvent(SCMDomainEvent):
    event_type: str = "scm.po.closed"
    po_id: Optional[UUID] = None
    po_number: str = ""


# ─── Goods Receipt Events ────────────────────────────────────

@dataclass(frozen=True)
class GoodsReceiptConfirmedEvent(SCMDomainEvent):
    event_type: str = "scm.goods_receipt.confirmed"
    gr_id: Optional[UUID] = None
    gr_number: str = ""
    po_id: Optional[UUID] = None
    vendor_id: Optional[UUID] = None
    total_amount: Decimal = Decimal("0")


@dataclass(frozen=True)
class GoodsReceiptCancelledEvent(SCMDomainEvent):
    event_type: str = "scm.goods_receipt.cancelled"
    gr_id: Optional[UUID] = None
    gr_number: str = ""


# ─── Return Events ───────────────────────────────────────────

@dataclass(frozen=True)
class PurchaseReturnCompletedEvent(SCMDomainEvent):
    event_type: str = "scm.purchase_return.completed"
    return_id: Optional[UUID] = None
    return_number: str = ""
    vendor_id: Optional[UUID] = None
    total_amount: Decimal = Decimal("0")


# ─── Evaluation Events ───────────────────────────────────────

@dataclass(frozen=True)
class VendorEvaluationCompletedEvent(SCMDomainEvent):
    event_type: str = "scm.vendor_evaluation.completed"
    evaluation_id: Optional[UUID] = None
    vendor_id: Optional[UUID] = None
    total_score: Decimal = Decimal("0")
    rating: str = ""
