import 'package:betting/routes/app_pages.dart';
import 'package:dio/dio.dart';
import 'package:get/get.dart' as geta;

import '../../commom/app_cache.dart';
import '../../commom/constants/error_code_constant.dart';
import '../model/base_model.dart';
import 'api_response.dart';
import 'data_fetch_call.dart';
import 'network_util.dart';


enum Request { POST, GET, PUT, DELETE }

class ApiService extends DataFetchCall<BaseModel> {
  String _path = "";
  dynamic _request;
  Map<String, dynamic>? _params;
  Map<String, dynamic>? _header;
  FormData? _fromData;
  String? sessionId;

  ApiService(String path,
      {Map<String, dynamic>? params,
      this.sessionId,
      FormData? fromData,
      dynamic request,
      Map<String, dynamic>? header}) {
    _request = request ?? {};
    _path = path;
    _fromData = fromData;
    _header = header;
    _params = params;
  }

  //
  // final Map<String, dynamic> header = {
  //   "Authorization": AppCache().token,
  //   "channel":"WEB"
  // };

  Map<String, dynamic> getHeader() {
    var token = AppCache().token;
    if (token != null && token.length == 0) {
      return {"channel": "APP_MOBILE"};
    } else {
      return {
        "Authorization": "Bearer ${AppCache().token}",
        "channel": "APP_MOBILE",
      };
    }
  }

  @override
  Future<Response> createApiAsync(Request request, {CancelToken? cancelToken}) {
    switch (request) {
      case Request.POST:
        return networkUtil.post(
          _path,
          formData: _fromData,
          mapData: _request,
          params: _params,
          headers: _header ?? getHeader(),
          cancelToken: cancelToken,
        );
      case Request.GET:
        return networkUtil.get(
          _path,
          _request,
          headers: _header ?? getHeader(),
          cancelToken: cancelToken,
        );
      case Request.PUT:
        return networkUtil.put(
          _path,
          formData: _fromData,
          mapData: _request,
          headers: _header ?? getHeader(),
        );
      default:
        return networkUtil.delete(
          _path,
          _request,
          headers: _header ?? getHeader(),
        );
    }
  }

  @override
  BaseModel parseJson(Response response) {
    return BaseModel.fromJson(response.data);
  }

  @override
  Future<ApiResponse<BaseModel>> request(Request request,
      {CancelToken? cancelToken}) async {
    {
      try {
        Response response =
            await createApiAsync(request, cancelToken: cancelToken);
        if (response.data is BaseModel) {
          return ApiResponse.failed<BaseModel>(response.data);
        }
        BaseModel responseModel = parseJson(response);
        if (responseModel.messageCode ==
            ErrorCodeConstant.INVALID_TOKEN.toString()) {
          geta.Get.offAllNamed(Routes.splash);
        }
        if (responseModel.code.toString().startsWith("2")) {
          return ApiResponse.success<BaseModel>(responseModel);
        } else {
          return ApiResponse.failed<BaseModel>(responseModel);
        }
      } catch (error, stacktrace) {
        return ApiResponse.failed<BaseModel>(BaseModel(
            code: -1,
            messageCode: ErrorCodeConstant.SERVER_ERROR,
            message: stacktrace.toString()));
      }
    }
  }
}
