"""
HRM Value Objects - اشیاء ارزشی بدون هویت.
"""
from dataclasses import dataclass
from datetime import date
from decimal import Decimal
from typing import Optional

from shared.base_classes.value_object import ValueObject


@dataclass(frozen=True)
class NationalCode(ValueObject):
    """کد ملی ایران - ۱۰ رقمی."""

    value: str = ""

    def validate(self) -> None:
        if not self.value or len(self.value) != 10:
            raise ValueError("کد ملی باید ۱۰ رقم باشد")
        if not self.value.isdigit():
            raise ValueError("کد ملی فقط شامل اعداد است")
        # Luhn-like check for Iranian national code
        if self.value == self.value[0] * 10:
            raise ValueError("کد ملی نامعتبر است")
        check = sum(int(self.value[i]) * (10 - i) for i in range(9)) % 11
        digit = int(self.value[9])
        if not ((check < 2 and digit == check) or (check >= 2 and digit == 11 - check)):
            raise ValueError("رقم کنترل کد ملی نامعتبر است")


@dataclass(frozen=True)
class ShebaNumber(ValueObject):
    """شماره شبا - ۲۶ کاراکتر."""

    value: str = ""

    def validate(self) -> None:
        if not self.value:
            return  # Optional
        if len(self.value) != 26:
            raise ValueError("شماره شبا باید ۲۶ کاراکتر باشد")
        if not self.value.startswith("IR"):
            raise ValueError("شماره شبا باید با IR شروع شود")


@dataclass(frozen=True)
class Money(ValueObject):
    """مبلغ پولی با ارز."""

    amount: Decimal = Decimal("0")
    currency: str = "IRR"

    def validate(self) -> None:
        if self.amount < 0:
            raise ValueError("مبلغ نمی‌تواند منفی باشد")

    def __add__(self, other: 'Money') -> 'Money':
        if self.currency != other.currency:
            raise ValueError("ارزها باید یکسان باشند")
        return Money(amount=self.amount + other.amount, currency=self.currency)

    def __mul__(self, factor) -> 'Money':
        return Money(amount=self.amount * Decimal(str(factor)), currency=self.currency)

    @classmethod
    def zero(cls, currency: str = "IRR") -> 'Money':
        return cls(amount=Decimal("0"), currency=currency)


@dataclass(frozen=True)
class DateRange(ValueObject):
    """بازه تاریخی."""

    start_date: date = None
    end_date: Optional[date] = None

    def validate(self) -> None:
        if not self.start_date:
            raise ValueError("تاریخ شروع الزامی است")
        if self.end_date and self.end_date < self.start_date:
            raise ValueError("تاریخ پایان نمی‌تواند قبل از شروع باشد")

    @property
    def days(self) -> int:
        if not self.end_date:
            return (date.today() - self.start_date).days
        return (self.end_date - self.start_date).days

    def overlaps(self, other: 'DateRange') -> bool:
        """بررسی هم‌پوشانی دو بازه."""
        if not self.end_date:
            return other.end_date is None or other.end_date >= self.start_date
        if not other.end_date:
            return self.end_date >= other.start_date
        return self.start_date <= other.end_date and other.start_date <= self.end_date


@dataclass(frozen=True)
class Address(ValueObject):
    """آدرس پستی."""

    province: str = ""
    city: str = ""
    street: str = ""
    postal_code: str = ""
    country: str = "IR"

    def validate(self) -> None:
        if not self.city:
            raise ValueError("شهر الزامی است")

    @property
    def full_address(self) -> str:
        parts = [p for p in [self.province, self.city, self.street] if p]
        return "، ".join(parts)
