#[repr(u16)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum StatusCode {
    // ===== 1xx Informational =====
    Continue = 100,
    SwitchingProtocols = 101,
    Processing = 102,
    EarlyHints = 103,

    // ===== 2xx Success =====
    Ok = 200,
    Created = 201,
    Accepted = 202,
    NonAuthoritativeInformation = 203,
    NoContent = 204,
    ResetContent = 205,
    PartialContent = 206,
    MultiStatus = 207,
    AlreadyReported = 208,
    ImUsed = 226,

    // ===== 3xx Redirection =====
    MultipleChoices = 300,
    MovedPermanently = 301,
    Found = 302,
    SeeOther = 303,
    NotModified = 304,
    UseProxy = 305,
    TemporaryRedirect = 307,
    PermanentRedirect = 308,

    // ===== 4xx Client Error =====
    BadRequest = 400,
    Unauthorized = 401,
    PaymentRequired = 402,
    Forbidden = 403,
    NotFound = 404,
    MethodNotAllowed = 405,
    NotAcceptable = 406,
    ProxyAuthenticationRequired = 407,
    RequestTimeout = 408,
    Conflict = 409,
    Gone = 410,
    LengthRequired = 411,
    PreconditionFailed = 412,
    PayloadTooLarge = 413,
    URITooLong = 414,
    UnsupportedMediaType = 415,
    RangeNotSatisfiable = 416,
    ExpectationFailed = 417,
    ImATeapot = 418,
    MisdirectedRequest = 421,
    UnprocessableEntity = 422,
    Locked = 423,
    FailedDependency = 424,
    TooEarly = 425,
    UpgradeRequired = 426,
    PreconditionRequired = 428,
    TooManyRequests = 429,
    RequestHeaderFieldsTooLarge = 431,
    UnavailableForLegalReasons = 451,

    // ===== 5xx Server Error =====
    InternalServerError = 500,
    NotImplemented = 501,
    BadGateway = 502,
    ServiceUnavailable = 503,
    GatewayTimeout = 504,
    HTTPVersionNotSupported = 505,
    VariantAlsoNegotiates = 506,
    InsufficientStorage = 507,
    LoopDetected = 508,
    NotExtended = 510,
    NetworkAuthenticationRequired = 511,
}

impl StatusCode {
    #[inline]
    pub fn to_http_status(&self) -> http::StatusCode {
        match self {
            StatusCode::Ok => http::StatusCode::OK,
            StatusCode::Created => http::StatusCode::CREATED,
            StatusCode::Accepted => http::StatusCode::ACCEPTED,
            StatusCode::NoContent => http::StatusCode::NO_CONTENT,
            StatusCode::BadRequest => http::StatusCode::BAD_REQUEST,
            StatusCode::Unauthorized => http::StatusCode::UNAUTHORIZED,
            StatusCode::Forbidden => http::StatusCode::FORBIDDEN,
            StatusCode::NotFound => http::StatusCode::NOT_FOUND,
            StatusCode::MethodNotAllowed => http::StatusCode::METHOD_NOT_ALLOWED,
            StatusCode::RequestTimeout => http::StatusCode::REQUEST_TIMEOUT,
            StatusCode::Conflict => http::StatusCode::CONFLICT,
            StatusCode::Gone => http::StatusCode::GONE,
            StatusCode::InternalServerError => http::StatusCode::INTERNAL_SERVER_ERROR,
            StatusCode::NotImplemented => http::StatusCode::NOT_IMPLEMENTED,
            StatusCode::BadGateway => http::StatusCode::BAD_GATEWAY,
            StatusCode::ServiceUnavailable => http::StatusCode::SERVICE_UNAVAILABLE,
            StatusCode::GatewayTimeout => http::StatusCode::GATEWAY_TIMEOUT,
            _ => http::StatusCode::OK,
        }
    }

    /// 从 u16 转 StatusCode 枚举
    pub fn from_u16(code: u16) -> Option<Self> {
        match code {
            100 => Some(StatusCode::Continue),
            101 => Some(StatusCode::SwitchingProtocols),
            102 => Some(StatusCode::Processing),
            103 => Some(StatusCode::EarlyHints),

            200 => Some(StatusCode::Ok),
            201 => Some(StatusCode::Created),
            202 => Some(StatusCode::Accepted),
            203 => Some(StatusCode::NonAuthoritativeInformation),
            204 => Some(StatusCode::NoContent),
            205 => Some(StatusCode::ResetContent),
            206 => Some(StatusCode::PartialContent),
            207 => Some(StatusCode::MultiStatus),
            208 => Some(StatusCode::AlreadyReported),
            226 => Some(StatusCode::ImUsed),

            300 => Some(StatusCode::MultipleChoices),
            301 => Some(StatusCode::MovedPermanently),
            302 => Some(StatusCode::Found),
            303 => Some(StatusCode::SeeOther),
            304 => Some(StatusCode::NotModified),
            305 => Some(StatusCode::UseProxy),
            307 => Some(StatusCode::TemporaryRedirect),
            308 => Some(StatusCode::PermanentRedirect),

            400 => Some(StatusCode::BadRequest),
            401 => Some(StatusCode::Unauthorized),
            402 => Some(StatusCode::PaymentRequired),
            403 => Some(StatusCode::Forbidden),
            404 => Some(StatusCode::NotFound),
            405 => Some(StatusCode::MethodNotAllowed),
            406 => Some(StatusCode::NotAcceptable),
            407 => Some(StatusCode::ProxyAuthenticationRequired),
            408 => Some(StatusCode::RequestTimeout),
            409 => Some(StatusCode::Conflict),
            410 => Some(StatusCode::Gone),
            411 => Some(StatusCode::LengthRequired),
            412 => Some(StatusCode::PreconditionFailed),
            413 => Some(StatusCode::PayloadTooLarge),
            414 => Some(StatusCode::URITooLong),
            415 => Some(StatusCode::UnsupportedMediaType),
            416 => Some(StatusCode::RangeNotSatisfiable),
            417 => Some(StatusCode::ExpectationFailed),
            418 => Some(StatusCode::ImATeapot),
            421 => Some(StatusCode::MisdirectedRequest),
            422 => Some(StatusCode::UnprocessableEntity),
            423 => Some(StatusCode::Locked),
            424 => Some(StatusCode::FailedDependency),
            425 => Some(StatusCode::TooEarly),
            426 => Some(StatusCode::UpgradeRequired),
            428 => Some(StatusCode::PreconditionRequired),
            429 => Some(StatusCode::TooManyRequests),
            431 => Some(StatusCode::RequestHeaderFieldsTooLarge),
            451 => Some(StatusCode::UnavailableForLegalReasons),

            500 => Some(StatusCode::InternalServerError),
            501 => Some(StatusCode::NotImplemented),
            502 => Some(StatusCode::BadGateway),
            503 => Some(StatusCode::ServiceUnavailable),
            504 => Some(StatusCode::GatewayTimeout),
            505 => Some(StatusCode::HTTPVersionNotSupported),
            506 => Some(StatusCode::VariantAlsoNegotiates),
            507 => Some(StatusCode::InsufficientStorage),
            508 => Some(StatusCode::LoopDetected),
            510 => Some(StatusCode::NotExtended),
            511 => Some(StatusCode::NetworkAuthenticationRequired),

            _ => None,
        }
    }

    /// 返回标准描述字符串
    pub fn to_str(&self) -> &'static str {
        match self {
            // 1xx
            StatusCode::Continue => "Continue",
            StatusCode::SwitchingProtocols => "Switching Protocols",
            StatusCode::Processing => "Processing",
            StatusCode::EarlyHints => "Early Hints",

            // 2xx
            StatusCode::Ok => "OK",
            StatusCode::Created => "Created",
            StatusCode::Accepted => "Accepted",
            StatusCode::NonAuthoritativeInformation => "Non-Authoritative Information",
            StatusCode::NoContent => "No Content",
            StatusCode::ResetContent => "Reset Content",
            StatusCode::PartialContent => "Partial Content",
            StatusCode::MultiStatus => "Multi-Status",
            StatusCode::AlreadyReported => "Already Reported",
            StatusCode::ImUsed => "IM Used",

            // 3xx
            StatusCode::MultipleChoices => "Multiple Choices",
            StatusCode::MovedPermanently => "Moved Permanently",
            StatusCode::Found => "Found",
            StatusCode::SeeOther => "See Other",
            StatusCode::NotModified => "Not Modified",
            StatusCode::UseProxy => "Use Proxy",
            StatusCode::TemporaryRedirect => "Temporary Redirect",
            StatusCode::PermanentRedirect => "Permanent Redirect",

            // 4xx
            StatusCode::BadRequest => "Bad Request",
            StatusCode::Unauthorized => "Unauthorized",
            StatusCode::PaymentRequired => "Payment Required",
            StatusCode::Forbidden => "Forbidden",
            StatusCode::NotFound => "Not Found",
            StatusCode::MethodNotAllowed => "Method Not Allowed",
            StatusCode::NotAcceptable => "Not Acceptable",
            StatusCode::ProxyAuthenticationRequired => "Proxy Authentication Required",
            StatusCode::RequestTimeout => "Request Timeout",
            StatusCode::Conflict => "Conflict",
            StatusCode::Gone => "Gone",
            StatusCode::LengthRequired => "Length Required",
            StatusCode::PreconditionFailed => "Precondition Failed",
            StatusCode::PayloadTooLarge => "Payload Too Large",
            StatusCode::URITooLong => "URI Too Long",
            StatusCode::UnsupportedMediaType => "Unsupported Media Type",
            StatusCode::RangeNotSatisfiable => "Range Not Satisfiable",
            StatusCode::ExpectationFailed => "Expectation Failed",
            StatusCode::ImATeapot => "I'm a teapot",
            StatusCode::MisdirectedRequest => "Misdirected Request",
            StatusCode::UnprocessableEntity => "Unprocessable Entity",
            StatusCode::Locked => "Locked",
            StatusCode::FailedDependency => "Failed Dependency",
            StatusCode::TooEarly => "Too Early",
            StatusCode::UpgradeRequired => "Upgrade Required",
            StatusCode::PreconditionRequired => "Precondition Required",
            StatusCode::TooManyRequests => "Too Many Requests",
            StatusCode::RequestHeaderFieldsTooLarge => "Request Header Fields Too Large",
            StatusCode::UnavailableForLegalReasons => "Unavailable For Legal Reasons",

            // 5xx
            StatusCode::InternalServerError => "Internal Server Error",
            StatusCode::NotImplemented => "Not Implemented",
            StatusCode::BadGateway => "Bad Gateway",
            StatusCode::ServiceUnavailable => "Service Unavailable",
            StatusCode::GatewayTimeout => "Gateway Timeout",
            StatusCode::HTTPVersionNotSupported => "HTTP Version Not Supported",
            StatusCode::VariantAlsoNegotiates => "Variant Also Negotiates",
            StatusCode::InsufficientStorage => "Insufficient Storage",
            StatusCode::LoopDetected => "Loop Detected",
            StatusCode::NotExtended => "Not Extended",
            StatusCode::NetworkAuthenticationRequired => "Network Authentication Required",
        }
    }
}
