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

import 'package:http/http.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;

class ChatApiClient {
  static final ChatApiClient _instance = ChatApiClient._internal();

  ChatApiClient._internal();

  factory ChatApiClient() => _instance;

  Future<user.UserAutoLoginModel> getUserLoginToken() async {
    Response response = await ApiClient().postJsonForResponse(
      "${ApiConsts.chatLoginTokenUrl}externaluserlogin",
      {
        "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
        "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
      },
    );
    user.UserAutoLoginModel userLoginResponse = user.userAutoLoginModelFromJson(
      response.body,
    );
    return userLoginResponse;
  }

  Future<List<ChatUser>?> getChatMemberFromSearch(String sName, int cUserId) async {
    Response response = await ApiClient().getJsonForResponse(
      "${ApiConsts.chatLoginTokenUrl}getUserWithStatusAndFavAsync/$sName/$cUserId",
      token: AppState().chatDetails!.response!.token,
    );
    return searchUserJsonModel(response.body);
  }

  List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(
        json.decode(str).map((x) => ChatUser.fromJson(x)),
      );

  Future<ChatUserModel> getRecentChats() async {
    Response response = await ApiClient().getJsonForResponse(
      "${ApiConsts.chatRecentUrl}getchathistorybyuserid",
      token: AppState().chatDetails!.response!.token,
    );
    return ChatUserModel.fromJson(
      json.decode(response.body),
    );
  }

  Future<ChatUserModel> getFavUsers() async {
    Response favRes = await ApiClient().getJsonForResponse(
      "${ApiConsts.chatFavUser}getFavUserById/${AppState().chatDetails!.response!.id}",
      token: AppState().chatDetails!.response!.token,
    );
    return ChatUserModel.fromJson(
      json.decode(favRes.body),
    );
  }

  Future<Response> getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async {
    Response response = await ApiClient().getJsonForResponse(
      "${ApiConsts.chatSingleUserHistoryUrl}GetUserChatHistory/$senderUID/$receiverUID/$paginationVal",
      token: AppState().chatDetails!.response!.token,
    );
    return response;
  }

  Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async {
    Response response = await ApiClient().postJsonForResponse(
        "${ApiConsts.chatFavUser}addFavUser",
        {
          "targetUserId": targetUserID,
          "userId": userID,
        },
        token: AppState().chatDetails!.response!.token);
    fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
    return favoriteChatUser;
  }

  Future<fav.FavoriteChatUser> unFavUser({required int userID, required int targetUserID}) async {
    Response response = await ApiClient().postJsonForResponse(
      "${ApiConsts.chatFavUser}deleteFavUser",
      {"targetUserId": targetUserID, "userId": userID},
      token: AppState().chatDetails!.response!.token,
    );
    fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
    return favoriteChatUser;
  }

  Future<StreamedResponse> uploadMedia(String userId, File file) async {
    dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}upload'));
    request.fields.addAll({'userId': userId, 'fileSource': '1'});
    request.files.add(await MultipartFile.fromPath('files', file.path));
    request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
    StreamedResponse response = await request.send();
    return response;
  }
}
