import 'dart:io';

import 'package:dio/dio.dart';
import 'package:eitc_erm_dental_flutter/funcs.dart';

/// 自定义请求异常父类
class ApiException implements Exception {
  final int? code;
  final String? message;
  String? stackInfo;

  ApiException([this.code, this.message]);

  factory ApiException.fromDioException(DioException exception) {
    switch (exception.type) {
      case DioExceptionType.connectionTimeout:
        return BadRequestException(-1, getS().connectTimeout);
      case DioExceptionType.sendTimeout:
        return BadRequestException(-1, getS().requestTimeout);
      case DioExceptionType.receiveTimeout:
        return BadRequestException(-1, getS().responseTimeout);
      case DioExceptionType.cancel:
        return BadRequestException(-1, getS().requestCancel);
      case DioExceptionType.badResponse:
        int? errorCode = exception.response?.statusCode;
        switch (errorCode) {
          case 400:
            return BadRequestException(errorCode, getS().requestGrammarError);
          case 401:
            return UnauthorisedException(errorCode, getS().noPermissions);
          case 403:
            return UnauthorisedException(errorCode, getS().serverRejectExec);
          case 404:
            return UnauthorisedException(
                errorCode, getS().requestResourceExist);
          case 405:
            return UnauthorisedException(errorCode, getS().requestMethodBanned);
          case 500:
            return UnauthorisedException(errorCode, getS().serverInternalError);
          case 502:
            return UnauthorisedException(errorCode, getS().gateError);
          case 503:
            return UnauthorisedException(errorCode, getS().serverError);
          case 504:
            return UnauthorisedException(errorCode, getS().gateTimeout);
          case 505:
            return UnauthorisedException(
                errorCode, getS().notSupportHttpRequest);
          default:
            return ApiException(errorCode,
                exception.response?.statusMessage ?? getS().unknownException);
        }
      case DioExceptionType.connectionError:
        if (exception.error is SocketException) {
          return DisconnectException(-1, getS().notworkNotConnect);
        } else {
          return ApiException(-1, getS().connectError);
        }
      case DioExceptionType.badCertificate:
        return ApiException(-1, getS().certificateError);
      case DioExceptionType.unknown:
        return ApiException(
            -1,
            exception.error != null
                ? exception.error.toString()
                : getS().unknownException);
    }
  }

  // 将各种异常转换为ApiException方便进行统一处理
  factory ApiException.from(dynamic exception) {
    if (exception is DioException) {
      return ApiException.fromDioException(exception);
    } else if (exception is ApiException) {
      return exception;
    } else {
      return ApiException(-1, "未知错误")..stackInfo = exception.toString();
    }
  }

  @override
  String toString() {
    return 'ApiException{code: $code, message: $message, stackInfo: $stackInfo}';
  }
}

/// 错误请求异常
class BadRequestException extends ApiException {
  BadRequestException(super.code, super.message);
}

/// 未认证异常
class UnauthorisedException extends ApiException {
  UnauthorisedException(super.code, super.message);
}

/// 未登录异常
class NeedLoginException extends ApiException {
  NeedLoginException(super.code, super.message);
}

/// 网络未连接异常
class DisconnectException extends ApiException {
  DisconnectException(super.code, super.message);
}

/// 应用需要强更
class NeedUpdateException extends ApiException {
  NeedUpdateException(super.code, super.message);
}

/// 错误响应格式异常
class ErrorResponseFormatException extends ApiException {
  ErrorResponseFormatException(super.code, super.message);
}

/// 未知响应类型异常
class UnknowResponseTypeException extends ApiException {
  UnknowResponseTypeException(super.code, super.message);
}
