"""Phase 6.2 sales engine validators."""
from __future__ import annotations

from decimal import Decimal

from shared.exceptions import AppError

from app.models.foundation import Opportunity, Pipeline, PipelineStage
from app.models.types import OpportunityStatus


def ensure_pipeline_active(pipeline: Pipeline) -> None:
    if not pipeline.is_active or pipeline.status != "active":
        raise AppError(
            "فقط پایپ‌لاین فعال مجاز است",
            status_code=422,
            error_code="pipeline_inactive",
        )


def ensure_stage_active(stage: PipelineStage) -> None:
    if not stage.is_active:
        raise AppError(
            "فقط مرحله فعال مجاز است",
            status_code=422,
            error_code="stage_inactive",
        )


def ensure_stage_belongs_to_pipeline(stage: PipelineStage, pipeline_id) -> None:
    if stage.pipeline_id != pipeline_id:
        raise AppError(
            "مرحله متعلق به پایپ‌لاین انتخاب‌شده نیست",
            status_code=422,
            error_code="stage_pipeline_mismatch",
        )


def ensure_opportunity_mutable(opportunity: Opportunity) -> None:
    if opportunity.status in {OpportunityStatus.WON, OpportunityStatus.LOST}:
        raise AppError(
            "فرصت بسته‌شده قابل ویرایش نیست",
            status_code=409,
            error_code="opportunity_immutable",
        )


def ensure_not_reopen_won(opportunity: Opportunity) -> None:
    if opportunity.status == OpportunityStatus.WON:
        raise AppError(
            "فرصت برنده‌شده قابل بازگشایی نیست",
            status_code=409,
            error_code="won_cannot_reopen",
        )


def validate_probability(value: int) -> int:
    if value < 0 or value > 100:
        raise AppError(
            "احتمال باید بین ۰ و ۱۰۰ باشد",
            status_code=422,
            error_code="invalid_probability",
        )
    return value


def validate_non_negative(amount: Decimal, *, field: str = "amount") -> Decimal:
    if amount < 0:
        raise AppError(
            f"{field} نمی‌تواند منفی باشد",
            status_code=422,
            error_code="invalid_amount",
            details={"field": field},
        )
    return amount


def validate_stage_flags(
    *,
    is_start_stage: bool,
    is_won_stage: bool,
    is_lost_stage: bool,
) -> None:
    flags = [is_start_stage, is_won_stage, is_lost_stage]
    if sum(1 for f in flags if f) > 1:
        raise AppError(
            "یک مرحله نمی‌تواند همزمان start/won/lost باشد",
            status_code=422,
            error_code="invalid_stage_flags",
        )


def validate_lost_requires_reason(reason_id, custom_reason: str | None) -> None:
    if reason_id is None and not (custom_reason and custom_reason.strip()):
        raise AppError(
            "از دست رفتن فرصت نیاز به دلیل دارد",
            status_code=422,
            error_code="lost_reason_required",
        )


def validate_win_loss_locked(is_locked: bool) -> None:
    if is_locked:
        raise AppError(
            "تحلیل برد/باخت قفل است و قابل تغییر نیست",
            status_code=409,
            error_code="win_loss_immutable",
        )
