import 'package:dio/dio.dart';
import 'package:networks_sdk/src/data/dto/api_response_wrapper.dart';
import 'package:networks_sdk/src/domain/entities/api_error.dart';
import 'package:networks_sdk/src/domain/entities/api_request_type.dart';
import 'package:networks_sdk/src/domain/entities/http_method.dart';

/// API 请求基类
///
/// 只需 `@ApiRequest` 一个注解，声明字段和构造函数即可：
/// - `toJson()` 由 mixin 自动生成（只序列化类自身字段，不含继承属性）
/// - `path / method / requestType / includeToken` 由 mixin 自动提供
/// - Response 的 fromJson 在 mixin 的 `parameters` getter 中自动注册
/// - **不需要** `@JsonSerializable`，**不需要** 手写 `fromJson`
///
/// ```dart
/// @ApiRequest(
///   path: ApiPaths.authLogin,
///   method: HttpMethod.post,
///   responseType: LoginData,
///   requestType: ApiRequestType.login,
/// )
/// class LoginRequest extends ApiRequestable<LoginData>
///     with _$LoginRequestApi {
///   final String email;
///   final String password;
///
///   LoginRequest({required this.email, required this.password});
///   // 完毕！一行样板代码都不用写
/// }
/// ```
///
/// 字段名映射：在字段上加 `@JsonKey(name: 'server_name')` 即可，
/// 生成器会读取并使用该名称作为 JSON 键。
///
/// 特殊请求（如 upload）：在类中 override `toJson()` 即可，
/// 类的 override 优先于 mixin。
abstract class ApiRequestable<T> {
  /// API 路径（如 '/auth/login'）
  String get path;

  /// HTTP 方法
  HttpMethod get method;

  /// 序列化为 JSON（由 @ApiRequest 生成器在 mixin 中自动生成）
  /// Upload 等特殊请求可在类中 override 返回空 map
  Map<String, dynamic> toJson();

  /// 请求参数 — 默认调用 toJson()，upload 类型返回 null
  /// 绝大多数情况无需 override
  Map<String, dynamic>? get parameters =>
      requestType == ApiRequestType.upload ? null : toJson();

  /// 上传请求的 body — upload 类型 override 此方法
  ///
  /// 支持多种上传格式：
  /// - `FormData` — multipart 表单上传到自有后端
  /// - `Uint8List` — 二进制流上传到 S3 presigned URL
  /// - 其他 Dio 支持的类型
  ///
  /// ```dart
  /// // FormData 上传
  /// @override
  /// Object? get uploadData => FormData.fromMap({
  ///   'file': MultipartFile.fromFileSync(filePath),
  /// });
  ///
  /// // 二进制上传（S3 presigned URL）
  /// @override
  /// Object? get uploadData => fileBytes;  // Uint8List
  /// ```
  Object? get uploadData => null;

  /// 自定义 headers（合并时覆盖默认值）
  Map<String, String>? get customHeaders => null;

  /// 请求类型（默认 request，登录 override 为 login）
  ApiRequestType get requestType => ApiRequestType.request;

  /// 是否在 header 中包含 token（默认 true）
  bool get includeToken => true;

  /// 解码响应 — 自动从 fromJson 注册表查找解码器
  ///
  /// **无需 override**，只要注册了响应类型就能自动解码。
  /// 支持无响应数据的接口（如 logout）：data 为 null 时不查注册表，直接返回 null。
  T? decodeResponse(Response response) {
    try {
      final data = response.data;

      if (data is Map<String, dynamic>) {
        // fromJson 查找延迟到实际需要解码时执行
        // → 无 data 的接口（logout / delete）不会触发 StateError
        T fromJsonObject(Object? json) {
          final fromJsonFunc = fromJsonRegistry[T];

          if (fromJsonFunc == null) {
            // void 接口：生成器不注册 fromJson，服务端 data 字段直接忽略
            // ignore: null_check_on_nullable_type_parameter
            return null as dynamic;
          }

          if (fromJsonFunc is T Function(Object?)) {
            return fromJsonFunc(json);
          }
          if (json is Map<String, dynamic>) {
            final mapFunc = fromJsonFunc as T Function(Map<String, dynamic>);
            return mapFunc(json);
          }
          throw FormatException(
            'Expected Map<String, dynamic>, got ${json.runtimeType}',
          );
        }

        final wrapper = ApiResponseWrapper<T>.fromJson(data, fromJsonObject);

        // 业务错误码检查（RetryInterceptor 已处理的跳过，防止双重抛错）
        final handledByInterceptor =
            response.requestOptions.extra['_businessErrorHandled'] == true;
        if (wrapper.code != 0 && !handledByInterceptor) {
          throw ApiError.apiError(
            code: wrapper.code,
            message: wrapper.message ?? 'API error (code: ${wrapper.code})',
          );
        }

        return wrapper.data;
      }

      return null;
    } catch (e) {
      if (e is ApiError) rethrow;
      throw ApiError.decodingError(e.toString());
    }
  }
}

// ── fromJson 注册表 ──────────────────────────────────────────────────────────

/// 全局 fromJson 注册表
final fromJsonRegistry = <Type, Function>{};

/// 注册响应类型（标准 `Map<String, dynamic>` 类型）
///
/// 在定义 Response 类的文件顶层调用一次即可：
/// ```dart
/// final _reg = registerResponse<LoginData>(LoginData.fromJson);
/// ```
T Function(Map<String, dynamic>)? registerResponse<T>(
  T Function(Map<String, dynamic>) fromJson,
) {
  fromJsonRegistry[T] = fromJson;
  return fromJson;
}

/// 注册响应类型（`Object?` 类型，支持 List 等复杂结构）
///
/// ```dart
/// final _reg = registerResponseObject<DeviceList>(DeviceList.fromJson);
/// ```
T Function(Object?)? registerResponseObject<T>(T Function(Object?) fromJson) {
  fromJsonRegistry[T] = fromJson;
  return fromJson;
}
