"""
Stock Domain Entities — StockLedgerEntry, StockBalance, StockStatus.
"""
from dataclasses import dataclass
from datetime import date, time, datetime
from enum import Enum
from typing import Optional
from uuid import UUID

from shared.base_classes.entity import TenantEntity


class StockStatusType(str, Enum):
    AVAILABLE = "AVAILABLE"
    RESERVED = "RESERVED"
    ALLOCATED = "ALLOCATED"
    BLOCKED = "BLOCKED"
    QUALITY_INSPECTION = "QUALITY_INSPECTION"
    QUARANTINE = "QUARANTINE"
    IN_TRANSIT = "IN_TRANSIT"
    DAMAGED = "DAMAGED"
    EXPIRED = "EXPIRED"


class TransactionType(str, Enum):
    GOODS_RECEIPT = "GR"
    GOODS_ISSUE = "GI"
    TRANSFER = "TRANSFER"
    ADJUSTMENT = "ADJUSTMENT"
    RETURN = "RETURN"
    SCRAP = "SCRAP"


class TransactionSubType(str, Enum):
    FROM_PURCHASE = "FROM_PURCHASE"
    TO_SALES = "TO_SALES"
    FROM_PRODUCTION = "FROM_PRODUCTION"
    TO_PRODUCTION = "TO_PRODUCTION"
    FROM_CUSTOMER_RETURN = "FROM_CUSTOMER_RETURN"
    TO_VENDOR_RETURN = "TO_VENDOR_RETURN"
    WAREHOUSE_TRANSFER = "WAREHOUSE_TRANSFER"
    LOCATION_TRANSFER = "LOCATION_TRANSFER"
    POSITIVE_ADJUSTMENT = "POSITIVE_ADJUSTMENT"
    NEGATIVE_ADJUSTMENT = "NEGATIVE_ADJUSTMENT"
    STATUS_CHANGE = "STATUS_CHANGE"
    OWNERSHIP_CHANGE = "OWNERSHIP_CHANGE"


class OwnershipType(str, Enum):
    OWN = "OWN"
    CONSIGNMENT_CUSTOMER = "CONSIGNMENT_CUSTOMER"
    CONSIGNMENT_VENDOR = "CONSIGNMENT_VENDOR"


@dataclass
class StockStatus(TenantEntity):
    """وضعیت موجودی."""
    status_code: str = ""
    status_name: str = ""
    status_type: StockStatusType = StockStatusType.AVAILABLE
    is_available_for_sales: bool = True
    is_available_for_production: bool = True
    is_blocked_for_movement: bool = False
    sort_order: int = 0
    is_active: bool = True


@dataclass
class StockLedgerEntry(TenantEntity):
    """ثبت دفتر کل موجودی — هر حرکت موجودی یک رکورد."""

    entry_number: str = ""
    posting_date: Optional[date] = None
    posting_time: Optional[time] = None

    # Dimensions
    item_id: Optional[UUID] = None
    warehouse_id: Optional[UUID] = None
    location_id: Optional[UUID] = None
    batch_id: Optional[UUID] = None
    serial_number_id: Optional[UUID] = None
    stock_status_id: Optional[UUID] = None
    ownership_type: OwnershipType = OwnershipType.OWN
    owner_id: Optional[UUID] = None
    project_id: Optional[UUID] = None

    # Transaction
    transaction_type: TransactionType = TransactionType.GOODS_RECEIPT
    transaction_sub_type: Optional[TransactionSubType] = None
    source_document_type: str = ""
    source_document_id: Optional[UUID] = None
    source_document_line_id: Optional[UUID] = None

    # Quantity
    quantity: float = 0.0
    uom_id: Optional[UUID] = None
    quantity_in_base_uom: float = 0.0

    # Costing
    unit_cost: float = 0.0
    total_cost: float = 0.0
    costing_method_id: Optional[UUID] = None
    currency_code: str = "IRR"

    # References
    reason_code: str = ""
    remarks: str = ""
    reference_number: str = ""

    # Reversal
    is_reversed: bool = False
    reversed_by_sle_id: Optional[UUID] = None

    # Company
    company_id: Optional[UUID] = None

    # Fiscal
    fiscal_year: int = 0
    fiscal_period: int = 0

    # Approval
    approved_by: Optional[UUID] = None
    approved_at: Optional[datetime] = None


@dataclass
class StockBalance(TenantEntity):
    """موجودی فعلی — Materialized / Calculated."""

    item_id: Optional[UUID] = None
    warehouse_id: Optional[UUID] = None
    location_id: Optional[UUID] = None
    batch_id: Optional[UUID] = None
    serial_number_id: Optional[UUID] = None
    stock_status_id: Optional[UUID] = None
    ownership_type: OwnershipType = OwnershipType.OWN
    owner_id: Optional[UUID] = None
    project_id: Optional[UUID] = None

    # Quantities
    quantity_on_hand: float = 0.0
    quantity_reserved: float = 0.0
    quantity_allocated: float = 0.0
    quantity_available: float = 0.0
    quantity_in_transit: float = 0.0
    uom_id: Optional[UUID] = None

    # Dates
    last_movement_date: Optional[date] = None
    last_count_date: Optional[date] = None

    # Valuation
    average_unit_cost: float = 0.0
    total_value: float = 0.0

    company_id: Optional[UUID] = None
