// ignore_for_file: public_member_api_docs, sort_constructors_first
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import 'dart:convert';

import 'package:http/http.dart';
import 'package:wyatt_http_client/src/models/unfreezed_request.dart';
import 'package:wyatt_http_client/src/utils/convert.dart';
import 'package:wyatt_http_client/src/utils/request_utils.dart';

class MiddlewareRequest {
  UnfreezedRequest unfreezedRequest;
  Request _httpRequest;

  Request get request => _httpRequest;

  // Proxy
  String get method => _httpRequest.method;
  Uri get url => _httpRequest.url;
  Map<String, String> get headers => _httpRequest.headers;
  Encoding get encoding => _httpRequest.encoding;
  String get encodedBody => _httpRequest.body;
  Object? get body => unfreezedRequest.body;

  MiddlewareRequest({
    required this.unfreezedRequest,
  }) : _httpRequest = Request(unfreezedRequest.method, unfreezedRequest.url);

  MiddlewareRequest copyWith({
    UnfreezedRequest? unfreezedRequest,
  }) =>
      MiddlewareRequest(
        unfreezedRequest: unfreezedRequest ?? this.unfreezedRequest,
      );

  void modifyRequest(UnfreezedRequest unfreezedRequest) {
    String? body;
    if (unfreezedRequest.body != null) {
      var body = unfreezedRequest.body;
      if (body is String) {
        body = body;
      } else if (body is List) {
        body = String.fromCharCodes(body.cast<int>());
      } else if (body is Map) {
        body = Convert.mapToQuery(body.cast<String, String>());
      }
    }
    _httpRequest = RequestUtils.copyRequestWith(
      _httpRequest,
      method: unfreezedRequest.method,
      url: unfreezedRequest.url,
      headers: unfreezedRequest.headers,
      body: body,
    ) as Request;
    if (unfreezedRequest.encoding != null) {
      _httpRequest.encoding = unfreezedRequest.encoding!;
    }
    this.unfreezedRequest = unfreezedRequest;
  }

  void apply() {
    modifyRequest(unfreezedRequest);
  }

  @override
  String toString() => 'MiddlewareRequest(unfreezedRequest: $unfreezedRequest)';
}
