import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';

abstract class BaseRepository {
  final Dio dio;
  BaseRepository({required this.dio});

  Future<Map<String, dynamic>> post({
    required Map<String, dynamic> param,
    required String service,
    String? token,
  }) async {
    try {
      final response = await dio.post(
        // Constant.baseUrl + service,
        service,
        data: jsonEncode(param),
        options: Options(
          headers: token != null
              ? {
                  HttpHeaders.contentTypeHeader: "application/json",
                  HttpHeaders.authorizationHeader: "Bearer $token",
                }
              : {
                  HttpHeaders.contentTypeHeader: "application/json",
                },
          contentType: "application/json",
        ),
      );
      if (response.statusCode != 200) {
        throw BaseRepositoryException(
          message: "Invalid Http Response ${response.statusCode}",
        );
      }
      Map<String, dynamic> jsonData = jsonDecode(response.data);
      if (jsonData["status"] != "OK") {
        throw BaseRepositoryException(
          message: jsonData["message"],
        );
      } else {
        return jsonData;
      }
    } on DioError catch (e) {
      if (e.type == DioErrorType.connectTimeout) {
        print("Conection Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Conection Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.sendTimeout) {
        print("Send Data Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Send Data Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.receiveTimeout) {
        print("Get Data Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Get Data Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.response) {
        print("Response Error, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Response Error, periksa koneksi anda");
      } else {
        print("else");
        throw BaseRepositoryException(message: e.message);
      }
      // throw BaseRepositoryException(message: e.message);
    } on SocketException catch (e) {
      throw BaseRepositoryException(message: e.message);
    } on BaseRepositoryException catch (e) {
      throw BaseRepositoryException(message: e.message);
    }
  }

  Future<Map<String, dynamic>> get({
    required String service,
  }) async {
    try {
      final response = await dio.get(
        // Constant.baseUrl + service,
        service,
      );
      if (response.statusCode != 200) {
        throw BaseRepositoryException(
          message: "Invalid Http Response ${response.statusCode}",
        );
      }
      // print(jsonDecode(response.data));
      Map<String, dynamic> jsonData = response.data;
      if (jsonData["status"] != "OK") {
        throw BaseRepositoryException(
          message: jsonData["message"],
        );
      } else {
        return jsonData;
      }
    } on DioError catch (e) {
      if (e.type == DioErrorType.connectTimeout) {
        print("Conection Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Conection Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.sendTimeout) {
        print("Send Data Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Send Data Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.receiveTimeout) {
        print("Get Data Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Get Data Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.response) {
        print("Response Error, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Response Error, periksa koneksi anda");
      } else {
        print("else");
        throw BaseRepositoryException(message: e.message);
      }
    } on SocketException catch (e) {
      throw BaseRepositoryException(message: e.message);
    } on BaseRepositoryException catch (e) {
      throw BaseRepositoryException(message: e.message);
    }
  }

  Future<Map<String, dynamic>> getBooth({
    required String service,
  }) async {
    try {
      final response = await dio.get(
        // Constant.baseUrl + service,
        service,
      );
      if (response.statusCode != 200) {
        throw BaseRepositoryException(
          message: "Invalid Http Response ${response.statusCode}",
        );
      }
      // print(jsonDecode(response.data));
      Map<String, dynamic> jsonData = jsonDecode(response.data);
      if (jsonData["status"] != "OK") {
        throw BaseRepositoryException(
          message: jsonData["message"],
        );
      } else {
        return jsonData;
      }
    } on DioError catch (e) {
      if (e.type == DioErrorType.connectTimeout) {
        print("Conection Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Conection Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.sendTimeout) {
        print("Send Data Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Send Data Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.receiveTimeout) {
        print("Get Data Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Get Data Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.response) {
        print("Response Error, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Response Error, periksa koneksi anda");
      } else {
        print("else");
        throw BaseRepositoryException(message: e.message);
      }
    } on SocketException catch (e) {
      throw BaseRepositoryException(message: e.message);
    } on BaseRepositoryException catch (e) {
      throw BaseRepositoryException(message: e.message);
    }
  }

  Future<Map<String, dynamic>> getService({
    required String service,
  }) async {
    try {
      final response = await dio.get(
        // Constant.baseUrl + service,
        service,
      );
      if (response.statusCode != 200) {
        throw BaseRepositoryException(
          message: "Invalid Http Response ${response.statusCode}",
        );
      }
      // print(jsonDecode(response.data));
      Map<String, dynamic> jsonData = jsonDecode(response.data);
      if (jsonData["status"] != "OK") {
        throw BaseRepositoryException(
          message: jsonData["message"],
        );
      } else {
        return jsonData;
      }
    } on DioError catch (e) {
      if (e.type == DioErrorType.connectTimeout) {
        print("Conection Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Conection Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.sendTimeout) {
        print("Send Data Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Send Data Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.receiveTimeout) {
        print("Get Data Timeout, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Get Data Timeout, periksa koneksi anda");
      } else if (e.type == DioErrorType.response) {
        print("Response Error, periksa koneksi anda");
        throw BaseRepositoryException(
            message: "${e.message} Response Error, periksa koneksi anda");
      } else {
        print("else");
        throw BaseRepositoryException(message: e.message);
      }
    } on SocketException catch (e) {
      throw BaseRepositoryException(message: e.message);
    } on BaseRepositoryException catch (e) {
      throw BaseRepositoryException(message: e.message);
    }
  }
}

class BaseRepositoryException implements Exception {
  final String message;
  BaseRepositoryException({
    required this.message,
  });
}
