import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:unit2/utils/text_container.dart';
import 'package:unit2/utils/urls.dart';

class Request {
  static final Request _instance = Request();
  static Request get instance => _instance;
  int requestTimeout = 25;
  String host = Url.instance.host();

  Future<Response> getRequest(
      {String? path,
      Map<String, String>? headers,
      Map<String, String>? param}) async {
    Response response;
    try {
      response = await get(Uri.https(host, path!, param), headers: headers)
          .timeout(Duration(seconds: requestTimeout));
    } on TimeoutException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on SocketException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on FormatException catch (_) {
      throw const FormatException(formatError);
    } on HttpException catch (_) {
      throw const HttpException(httpError);
    } on Error catch (e) {
      debugPrint("get request error: $e");
      // Fluttertoast.showToast(
      //   msg: onError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (onError);
    }
    return response;
  }

  Future<Response> postRequest(
      {String? path,
      Map<String, String>? headers,
      Map? body,
      Map<String, String>? param}) async {
    Response response;
    try {
      response = await post(Uri.https(host, path!, param),
              headers: headers, body: jsonEncode(body))
          .timeout(Duration(seconds: requestTimeout));
    } on TimeoutException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on SocketException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on FormatException catch (_) {
      throw const FormatException(formatError);
    } on HttpException catch (_) {
      throw const HttpException(httpError);
    } on Error catch (e) {
      debugPrint("post request error: $e");
      // Fluttertoast.showToast(
      //   msg: onError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (e.toString());
    }
    return response;
  }

  Future<Response> putRequest(
      {required String path,
      required Map<String, String>? headers,
      required Map? body,
      required Map<String, dynamic>? param}) async {
    Response response;
    try {
      response = await put(Uri.https(host, path, param),
          headers: headers, body: jsonEncode(body));
    } on TimeoutException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on SocketException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on FormatException catch (_) {
      throw const FormatException(formatError);
    } on HttpException catch (_) {
      throw const HttpException(httpError);
    } on Error catch (e) {
      debugPrint("post request error: $e");
      // Fluttertoast.showToast(
      //   msg: onError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (e.toString());
    }
    return response;
  }

  Future<Response> patch(
      {required String path,
      required Map<String, String>? headers,
      required Map? body,
      required Map<String, dynamic>? param}) async {
    Response response;
    try {
      response = await patch(
          path: host + path, headers: headers, body: body, param: param);
    } on TimeoutException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on SocketException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on FormatException catch (_) {
      throw const FormatException(formatError);
    } on HttpException catch (_) {
      throw const HttpException(httpError);
    } on Error catch (e) {
      debugPrint("post request error: $e");
      // Fluttertoast.showToast(
      //   msg: onError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (e.toString());
    }
    return response;
  }

  Future<Response> deleteRequest(
      {required String path,
      required Map<String, String>? headers,
      required Map? body,
      required Map<String, dynamic>? param}) async {
    Response response;
    try {
      response = await delete(Uri.https(host, path, param),
              headers: headers, body: jsonEncode(body))
          .timeout(Duration(seconds: requestTimeout));
    } on TimeoutException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on SocketException catch (_) {
      // Fluttertoast.showToast(
      //   msg: timeoutError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (timeoutError);
    } on FormatException catch (_) {
      throw const FormatException(formatError);
    } on HttpException catch (_) {
      throw const HttpException(httpError);
    } on Error catch (e) {
      // Fluttertoast.showToast(
      //   msg: onError,
      //   toastLength: Toast.LENGTH_LONG,
      //   gravity: ToastGravity.BOTTOM,
      //   backgroundColor: Colors.black,
      // );
      throw (e.toString());
    }
    return response;
  }
}
