"""Localization & media-ref domain policies — Phase 11.5."""
from __future__ import annotations

from typing import Any

from app.models.types import LocalizationStatus, MediaRefStatus
from app.validators.localization import (
    ensure_localization_status_transition,
    ensure_media_ref_status_transition,
    ensure_no_binary_media_payload,
    validate_storage_file_ref,
)
from shared.exceptions import AppError


class SiteLocaleBindingPolicy:
    def assert_profile_usable(self, profile: Any) -> None:
        if profile is None:
            raise AppError(
                "پروفایل locale یافت نشد",
                error_code="locale_profile_not_found",
                status_code=404,
            )
        if getattr(profile, "is_deleted", False):
            raise AppError(
                "پروفایل locale حذف‌شده قابل اتصال نیست",
                error_code="locale_profile_deleted",
                status_code=409,
            )
        status = getattr(profile, "status", None)
        status_value = getattr(status, "value", status)
        if status_value in {"archived", "suspended", "inactive"}:
            raise AppError(
                "پروفایل locale غیرفعال قابل اتصال نیست",
                error_code="locale_profile_inactive",
                status_code=409,
                details={"status": status_value},
            )


class LocalizationPolicy:
    def assert_status_change(
        self, *, current: LocalizationStatus, target: LocalizationStatus
    ) -> LocalizationStatus:
        ensure_localization_status_transition(current, target)
        return target


class MediaRefPolicy:
    def assert_storage_ref_only(
        self, *, storage_file_ref: str, metadata_json: dict | None = None
    ) -> str:
        cleaned = validate_storage_file_ref(storage_file_ref)
        ensure_no_binary_media_payload(metadata_json)
        return cleaned

    def assert_status_change(
        self, *, current: MediaRefStatus, target: MediaRefStatus
    ) -> MediaRefStatus:
        ensure_media_ref_status_transition(current, target)
        return target
