"""
Costing & Valuation Domain Entities.
"""
from dataclasses import dataclass
from datetime import date, datetime
from enum import Enum
from typing import Optional
from uuid import UUID

from shared.base_classes.entity import TenantEntity


class CostingMethodCode(str, Enum):
    MAP = "MAP"
    STANDARD = "STANDARD"
    FIFO = "FIFO"
    LIFO = "LIFO"
    ACTUAL = "ACTUAL"


class PostingStatus(str, Enum):
    PENDING = "PENDING"
    POSTED = "POSTED"
    FAILED = "FAILED"


@dataclass
class CostingMethod(TenantEntity):
    """روش قیمت‌گذاری."""
    method_code: str = ""
    method_name: str = ""
    description: str = ""
    is_active: bool = True


@dataclass
class ItemCosting(TenantEntity):
    """قیمت‌گذاری کالا."""
    item_id: Optional[UUID] = None
    company_id: Optional[UUID] = None
    costing_method_id: Optional[UUID] = None

    standard_cost: float = 0.0
    moving_average_cost: float = 0.0
    last_purchase_cost: float = 0.0
    currency_code: str = "IRR"

    last_cost_update_date: Optional[date] = None
    is_active: bool = True


@dataclass
class CostLayer(TenantEntity):
    """لایه هزینه — FIFO/LIFO."""
    item_id: Optional[UUID] = None
    warehouse_id: Optional[UUID] = None
    batch_id: Optional[UUID] = None

    receipt_date: Optional[date] = None
    receipt_sle_id: Optional[UUID] = None

    unit_cost: float = 0.0
    original_quantity: float = 0.0
    remaining_quantity: float = 0.0
    uom_id: Optional[UUID] = None
    currency_code: str = "IRR"

    is_fully_consumed: bool = False
    company_id: Optional[UUID] = None


@dataclass
class FinancialPosting(TenantEntity):
    """ارسال به حسابداری."""
    stock_ledger_id: Optional[UUID] = None
    posting_date: Optional[date] = None
    journal_entry_id: Optional[UUID] = None

    debit_account: str = ""
    credit_account: str = ""
    amount: float = 0.0
    currency_code: str = "IRR"

    cost_center_id: Optional[UUID] = None
    project_id: Optional[UUID] = None

    posting_status: PostingStatus = PostingStatus.PENDING
    error_message: str = ""
    posted_date: Optional[date] = None
    posted_by: Optional[UUID] = None

    company_id: Optional[UUID] = None
