"""
SCM Domain Entities — Vendor Management.

تأمین‌کنندگان، دسته‌بندی، مخاطبین، حساب بانکی، آدرس.
"""
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Optional, List
from uuid import UUID, uuid4

from shared.base_classes.entity import TenantEntity


# ─── Enums ────────────────────────────────────────────────────────────────

class VendorStatus(str, Enum):
    ACTIVE = "ACTIVE"
    INACTIVE = "INACTIVE"
    BLOCKED = "BLOCKED"
    PENDING_APPROVAL = "PENDING_APPROVAL"


class VendorType(str, Enum):
    INDIVIDUAL = "INDIVIDUAL"
    COMPANY = "COMPANY"
    GOVERNMENT = "GOVERNMENT"


class AddressType(str, Enum):
    MAIN = "MAIN"
    BILLING = "BILLING"
    SHIPPING = "SHIPPING"
    WAREHOUSE = "WAREHOUSE"


# ─── Value Objects ────────────────────────────────────────────────────────

@dataclass(frozen=True)
class VendorCode:
    """کد یکتای تأمین‌کننده."""
    value: str

    def __post_init__(self):
        if not self.value or len(self.value) > 50:
            raise ValueError("Vendor code must be 1-50 characters")


@dataclass(frozen=True)
class NationalId:
    """شناسه ملی / کد ملی."""
    value: str

    def __post_init__(self):
        if self.value and len(self.value) > 20:
            raise ValueError("National ID must be <= 20 characters")


@dataclass(frozen=True)
class IBAN:
    """شماره شبا."""
    value: str

    def __post_init__(self):
        if self.value and (len(self.value) < 24 or len(self.value) > 34):
            raise ValueError("IBAN must be 24-34 characters")


# ─── Entities ─────────────────────────────────────────────────────────────

@dataclass
class VendorCategory(TenantEntity):
    """دسته‌بندی تأمین‌کنندگان — سلسله‌مراتبی."""
    category_code: str = ""
    category_name: str = ""
    parent_category_id: Optional[UUID] = None
    level: int = 0
    description: str = ""
    is_active: bool = True


@dataclass
class VendorContact(TenantEntity):
    """مخاطب تأمین‌کننده."""
    vendor_id: Optional[UUID] = None
    contact_name: str = ""
    contact_title: str = ""
    phone: str = ""
    mobile: str = ""
    email: str = ""
    is_primary: bool = False
    is_active: bool = True


@dataclass
class VendorBankAccount(TenantEntity):
    """حساب بانکی تأمین‌کننده."""
    vendor_id: Optional[UUID] = None
    bank_name: str = ""
    branch_name: str = ""
    account_number: str = ""
    iban: str = ""
    account_holder_name: str = ""
    is_default: bool = False
    is_active: bool = True


@dataclass
class VendorAddress(TenantEntity):
    """آدرس تأمین‌کننده."""
    vendor_id: Optional[UUID] = None
    address_type: AddressType = AddressType.MAIN
    address_line1: str = ""
    address_line2: str = ""
    city: str = ""
    province: str = ""
    postal_code: str = ""
    country: str = "IR"
    phone: str = ""
    fax: str = ""
    is_default: bool = False


@dataclass
class Vendor(TenantEntity):
    """تأمین‌کننده — Aggregate Root."""

    vendor_code: str = ""
    vendor_name: str = ""
    vendor_name_en: str = ""
    vendor_type: VendorType = VendorType.COMPANY
    category_id: Optional[UUID] = None
    status: VendorStatus = VendorStatus.PENDING_APPROVAL

    # Identification
    national_id: str = ""
    economic_code: str = ""
    registration_number: str = ""

    # Communication
    phone: str = ""
    fax: str = ""
    email: str = ""
    website: str = ""

    # HRM Link
    representative_employee_id: Optional[UUID] = None

    # Settings
    payment_terms_days: int = 30
    credit_limit: int = 0
    currency_code: str = "IRR"

    # Metadata
    notes: str = ""
    is_active: bool = True

    # Related (not persisted directly, loaded separately)
    contacts: List[VendorContact] = field(default_factory=list)
    bank_accounts: List[VendorBankAccount] = field(default_factory=list)
    addresses: List[VendorAddress] = field(default_factory=list)

    def activate(self):
        """فعال کردن تأمین‌کننده."""
        self.status = VendorStatus.ACTIVE
        self.is_active = True

    def block(self, reason: str = ""):
        """مسدود کردن تأمین‌کننده."""
        self.status = VendorStatus.BLOCKED
        self.is_active = False
        if reason:
            self.notes = f"{self.notes}\nBlocked: {reason}".strip()

    def deactivate(self):
        """غیرفعال کردن تأمین‌کننده."""
        self.status = VendorStatus.INACTIVE
        self.is_active = False

    def validate(self):
        """اعتبارسنجی تأمین‌کننده."""
        if not self.vendor_code:
            raise ValueError("Vendor code is required")
        if not self.vendor_name:
            raise ValueError("Vendor name is required")
