"""DMS业务异常。"""

from __future__ import annotations

from typing import Any


class DmsError(Exception):
    code = "INTERNAL_ERROR"
    status_code = 500
    default_message = "服务器内部错误"

    def __init__(
        self,
        message: str | None = None,
        *,
        details: Any = None,
        code: str | None = None,
    ) -> None:
        super().__init__(message or self.default_message)
        self.message = message or self.default_message
        self.details = details
        self.code = code or self.code


class InvalidArgumentError(DmsError):
    code = "INVALID_ARGUMENT"
    status_code = 400
    default_message = "请求参数错误"


class AuthenticationError(DmsError):
    code = "TOKEN_INVALID"
    status_code = 401
    default_message = "未认证或登录凭证无效"


class InvalidCredentialsError(AuthenticationError):
    code = "INVALID_CREDENTIALS"
    default_message = "用户名或密码错误"


class TokenExpiredError(AuthenticationError):
    code = "TOKEN_EXPIRED"
    default_message = "登录凭证已过期"


class UserDisabledError(AuthenticationError):
    code = "USER_DISABLED"
    default_message = "用户已被禁用"


class AuthVersionMismatchError(AuthenticationError):
    code = "AUTH_VERSION_MISMATCH"
    default_message = "登录状态已失效，请重新登录"


class ForbiddenError(DmsError):
    code = "FORBIDDEN"
    status_code = 403
    default_message = "无权限执行此操作"


class SecurityLevelForbiddenError(ForbiddenError):
    code = "SECURITY_LEVEL_FORBIDDEN"
    default_message = "用户密级不足，无法查看该文档"


class DocumentViewForbiddenError(ForbiddenError):
    code = "DOCUMENT_VIEW_FORBIDDEN"
    default_message = "无权查看该文档"


class DocumentDownloadForbiddenError(ForbiddenError):
    code = "DOCUMENT_DOWNLOAD_FORBIDDEN"
    default_message = "无权下载该文档"


class ResourceNotFoundError(DmsError):
    code = "RESOURCE_NOT_FOUND"
    status_code = 404
    default_message = "请求的资源不存在"


class ConflictError(DmsError):
    code = "DATA_VERSION_CONFLICT"
    status_code = 409
    default_message = "数据冲突"


class CategoryInUseError(ConflictError):
    code = "CATEGORY_IN_USE"
    default_message = "分类仍被子分类或方案文档占用"


class CategoryNotLeafError(ConflictError):
    code = "CATEGORY_NOT_LEAF"
    default_message = "只有有效叶子分类可以直接存放主案"


class MainPlanNotFoundError(ResourceNotFoundError):
    code = "MAIN_PLAN_NOT_FOUND"
    default_message = "主案不存在"


class FileNotFoundError(ResourceNotFoundError):
    code = "FILE_NOT_FOUND"
    default_message = "文档文件不存在"


class PreviewUnavailableError(DmsError):
    code = "PREVIEW_UNAVAILABLE"
    status_code = 415
    default_message = "当前文件类型不支持在线预览"

class PreviewConverterUnavailableError(DmsError):
    code = "PREVIEW_CONVERTER_UNAVAILABLE"
    status_code = 503
    default_message = "预览转换器未配置或不可用"

class PreviewConversionTimeoutError(DmsError):
    code = "PREVIEW_CONVERSION_TIMEOUT"
    status_code = 504
    default_message = "文档转换超时，请稍后重试"

class PreviewConversionFailedError(DmsError):
    code = "PREVIEW_CONVERSION_FAILED"
    status_code = 502
    default_message = "文档转换为PDF失败"


class BatchManifestMismatchError(InvalidArgumentError):
    code = "BATCH_MANIFEST_MISMATCH"
    default_message = "批量文件数量与元数据数量不一致"


class MainPlanHasChildrenError(ConflictError):
    code = "MAIN_PLAN_HAS_CHILDREN"
    default_message = "主案仍存在有效子方案"


class DocumentNameConflictError(ConflictError):
    code = "DOCUMENT_NAME_CONFLICT"
    default_message = "同一范围内已存在同名方案"


class AttachmentInUseError(ConflictError):
    code = "ATTACHMENT_IN_USE"
    default_message = "共享附件仍被主案挂载"


class AttachmentHasNoAclError(InvalidArgumentError):
    code = "ATTACHMENT_HAS_NO_ACL"
    default_message = "共享附件不配置访问权限"


class SubPlanPermissionInheritedError(ConflictError):
    code = "SUB_PLAN_PERMISSION_INHERITED"
    default_message = "子方案动态继承主案权限，不能独立配置"


class DuplicatePermissionSubjectError(InvalidArgumentError):
    code = "DUPLICATE_PERMISSION_SUBJECT"
    default_message = "权限主体不能重复"


class UnsupportedFileTypeError(DmsError):
    code = "UNSUPPORTED_FILE_TYPE"
    status_code = 415
    default_message = "不支持的文件类型"


class PayloadTooLargeError(DmsError):
    code = "PAYLOAD_TOO_LARGE"
    status_code = 413
    default_message = "请求内容过大"


class InternalError(DmsError):
    code = "INTERNAL_ERROR"
    status_code = 500
    default_message = "服务器内部错误"


class DocumentNotDeletedError(ConflictError):
    code = "DOCUMENT_NOT_DELETED"
    default_message = "文档当前不在回收站中"


class FileIntegrityMismatchError(ConflictError):
    code = "FILE_INTEGRITY_MISMATCH"
    default_message = "文档文件完整性校验失败"


class FilePathInvalidError(InternalError):
    code = "FILE_PATH_INVALID"
    default_message = "文档存储路径异常"


class RestoreFileChangedError(ConflictError):
    code = "RESTORE_FILE_CHANGED"
    default_message = "校验期间文件发生变化"


class RestoreCategoryInvalidError(ConflictError):
    code = "RESTORE_CATEGORY_INVALID"
    default_message = "原方案分类无效，无法恢复"


class RestoreParentInvalidError(ConflictError):
    code = "RESTORE_PARENT_INVALID"
    default_message = "原所属主案无效，无法恢复"


class RestorePermissionInvalidError(ConflictError):
    code = "RESTORE_PERMISSION_INVALID"
    default_message = "恢复后无法形成有效权限配置"


class RestoreRelationConflictError(ConflictError):
    code = "RESTORE_RELATION_CONFLICT"
    default_message = "历史权限或挂载关系与当前有效关系冲突"
