import 'dart:typed_data';

import 'package:json_annotation/json_annotation.dart';
import 'package:networks_sdk/networks_sdk.dart';

import '../../../core/foundation/api_paths.dart';

part 'upload_file_request.g.dart';

/// # /upload/file — 文件上传（Upload 请求示例）
///
/// 演示两种上传模式：
///
/// ## 模式 A: FormData 上传到自有后端
/// 适用于后端直接接收文件的场景。
/// 使用 [UploadFileRequest] — path 为相对路径，SDK 自动拼 baseURL。
///
/// ## 模式 B: 二进制上传到 S3 presigned URL
/// 适用于先向后端获取 presigned URL，再直接上传到 S3 的场景。
/// 使用 [S3UploadRequest] — path 为完整 URL，override decodeResponse。
///
/// ## Upload 与普通请求的区别
///
/// | 普通请求 | Upload 请求 |
/// |---------|-----------|
/// | `toJson()` → JSON body | `uploadData` → FormData / Uint8List |
/// | `requestType: request` | `requestType: upload` |
/// | `parameters` 有值 | `parameters` 返回 null |
/// | 标准 `{ code, msg, data }` 响应 | 可能需要 override `decodeResponse` |

// ─────────────────────────────────────────────
//  Response DTO
// ─────────────────────────────────────────────

/// 文件上传接口的业务响应数据（对应服务端 `data` 字段）。纯 Dart 类，无需任何注解。
class UploadResult {
  final String url;

  @JsonKey(name: 'file_id')
  final String fileId;

  const UploadResult({required this.url, required this.fileId});
}

// ═════════════════════════════════════════════
//  模式 A: FormData 上传到自有后端
// ═════════════════════════════════════════════

/// FormData 上传请求
///
/// 上传到自有后端 `/upload/file`，响应为标准 `{ code, message, data }` 格式。
/// 无需 override `decodeResponse`。
@ApiRequest(
  path: ApiPaths.uploadFile,
  method: HttpMethod.post,
  responseType: UploadResult,
  requestType: ApiRequestType.upload,
)
class UploadFileRequest extends ApiRequestable<UploadResult>
    with _$UploadFileRequestApi {
  final String filePath;
  final String? fileName;

  UploadFileRequest({required this.filePath, this.fileName});

  @override
  Map<String, dynamic> toJson() => {};

  /// FormData — SDK 通过 uploadData 获取上传数据
  @override
  Object? get uploadData {
    return FormData.fromMap({
      'file': MultipartFile.fromFileSync(filePath, filename: fileName),
    });
  }
}

// ═════════════════════════════════════════════
//  模式 B: 二进制上传到 S3 presigned URL
// ═════════════════════════════════════════════

/// S3 presigned URL 上传响应
class S3UploadResponse {
  final bool success;
  final String? message;

  const S3UploadResponse({this.success = true, this.message});
}

/// S3 presigned URL 上传请求
///
/// 特点：
/// - path 为完整的 presigned URL（SDK 检测到 http 开头不拼 baseURL）
/// - uploadData 为 Uint8List 二进制数据
/// - 自定义 headers（Content-Type: application/octet-stream）
/// - override decodeResponse — S3 返回 204 No Content 或 XML，不是标准响应格式
class S3UploadRequest extends ApiRequestable<S3UploadResponse> {
  final Uint8List data;
  final String presignedURL;

  S3UploadRequest({required this.data, required this.presignedURL});

  @override
  String get path => presignedURL;

  @override
  HttpMethod get method => HttpMethod.put;

  @override
  ApiRequestType get requestType => ApiRequestType.upload;

  @override
  Map<String, String>? get customHeaders => {
    'Content-Type': 'application/octet-stream',
  };

  @override
  Map<String, dynamic> toJson() => {};

  /// 二进制数据
  @override
  Object? get uploadData => data;

  /// S3 响应不走标准 { code, message, data } 格式，需要自定义解码
  ///
  /// 可能的响应：
  /// - 204 No Content（空 body）→ 成功
  /// - 200 + XML body → 成功
  /// - 200 + JSON body → 尝试解码
  @override
  S3UploadResponse? decodeResponse(Response response) {
    // 空响应或 2xx 状态码 → 成功
    if (response.data == null ||
        (response.data is List && (response.data as List).isEmpty)) {
      return const S3UploadResponse(success: true);
    }

    // JSON 响应 → 尝试解码
    if (response.data is Map<String, dynamic>) {
      final json = response.data as Map<String, dynamic>;
      return S3UploadResponse(
        success: true,
        message: json['message'] as String?,
      );
    }

    // 2xx 状态码 → 成功
    if (response.statusCode != null &&
        response.statusCode! >= 200 &&
        response.statusCode! < 300) {
      return const S3UploadResponse(success: true);
    }

    return const S3UploadResponse(success: true);
  }
}
