# app/exceptions/vendor_domain.py
"""
Vendor domain management specific exceptions.
"""

from .base import (
    BusinessLogicException,
    ConflictException,
    ExternalServiceException,
    ResourceNotFoundException,
    ValidationException,
)


class VendorDomainNotFoundException(ResourceNotFoundException):
    """Raised when a vendor domain is not found."""

    def __init__(self, domain_identifier: str, identifier_type: str = "ID"):
        if identifier_type.lower() == "domain":
            message = f"Domain '{domain_identifier}' not found"
        else:
            message = f"Domain with ID '{domain_identifier}' not found"

        super().__init__(
            resource_type="VendorDomain",
            identifier=domain_identifier,
            message=message,
            error_code="VENDOR_DOMAIN_NOT_FOUND",
        )


class VendorDomainAlreadyExistsException(ConflictException):
    """Raised when trying to add a domain that already exists."""

    def __init__(self, domain: str, existing_vendor_id: int | None = None):
        details = {"domain": domain}
        if existing_vendor_id:
            details["existing_vendor_id"] = existing_vendor_id

        super().__init__(
            message=f"Domain '{domain}' is already registered",
            error_code="VENDOR_DOMAIN_ALREADY_EXISTS",
            details=details,
        )


class InvalidDomainFormatException(ValidationException):
    """Raised when domain format is invalid."""

    def __init__(self, domain: str, reason: str = "Invalid domain format"):
        super().__init__(
            message=f"{reason}: {domain}",
            field="domain",
            details={"domain": domain, "reason": reason},
        )
        self.error_code = "INVALID_DOMAIN_FORMAT"


class ReservedDomainException(ValidationException):
    """Raised when trying to use a reserved domain."""

    def __init__(self, domain: str, reserved_part: str):
        super().__init__(
            message=f"Domain cannot use reserved subdomain: {reserved_part}",
            field="domain",
            details={"domain": domain, "reserved_part": reserved_part},
        )
        self.error_code = "RESERVED_DOMAIN"


class DomainNotVerifiedException(BusinessLogicException):
    """Raised when trying to activate an unverified domain."""

    def __init__(self, domain_id: int, domain: str):
        super().__init__(
            message=f"Domain '{domain}' must be verified before activation",
            error_code="DOMAIN_NOT_VERIFIED",
            details={"domain_id": domain_id, "domain": domain},
        )


class DomainVerificationFailedException(BusinessLogicException):
    """Raised when domain verification fails."""

    def __init__(self, domain: str, reason: str):
        super().__init__(
            message=f"Domain verification failed for '{domain}': {reason}",
            error_code="DOMAIN_VERIFICATION_FAILED",
            details={"domain": domain, "reason": reason},
        )


class DomainAlreadyVerifiedException(BusinessLogicException):
    """Raised when trying to verify an already verified domain."""

    def __init__(self, domain_id: int, domain: str):
        super().__init__(
            message=f"Domain '{domain}' is already verified",
            error_code="DOMAIN_ALREADY_VERIFIED",
            details={"domain_id": domain_id, "domain": domain},
        )


class MultiplePrimaryDomainsException(BusinessLogicException):
    """Raised when trying to set multiple primary domains."""

    def __init__(self, vendor_id: int):
        super().__init__(
            message="Vendor can only have one primary domain",
            error_code="MULTIPLE_PRIMARY_DOMAINS",
            details={"vendor_id": vendor_id},
        )


class DNSVerificationException(ExternalServiceException):
    """Raised when DNS verification service fails."""

    def __init__(self, domain: str, reason: str):
        super().__init__(
            service_name="DNS",
            message=f"DNS verification failed for '{domain}': {reason}",
            error_code="DNS_VERIFICATION_ERROR",
            details={"domain": domain, "reason": reason},
        )


class MaxDomainsReachedException(BusinessLogicException):
    """Raised when vendor tries to add more domains than allowed."""

    def __init__(self, vendor_id: int, max_domains: int):
        super().__init__(
            message=f"Maximum number of domains reached ({max_domains})",
            error_code="MAX_DOMAINS_REACHED",
            details={"vendor_id": vendor_id, "max_domains": max_domains},
        )


class UnauthorizedDomainAccessException(BusinessLogicException):
    """Raised when trying to access domain that doesn't belong to vendor."""

    def __init__(self, domain_id: int, vendor_id: int):
        super().__init__(
            message=f"Unauthorized access to domain {domain_id}",
            error_code="UNAUTHORIZED_DOMAIN_ACCESS",
            details={"domain_id": domain_id, "vendor_id": vendor_id},
        )
