import api from '@config/api';
import {sentryLogs} from '@shared/utils';

import {CHATS_BASE_URL} from './constants';
import {
  GetUserInfoParams,
  GetUserInfoResponse,
  GetUsersInfoResponse,
  GetUsersListParams,
  GetUsersListResponse,
} from './interfaces';
import {getUserById, getUsersById} from '../db/repositories/users';
import {mapUserFromDB, mapUserFromServer} from '../utils/mappers/userMapper';
import {HuDataMember} from '../interfaces';

export const getUsersList = async (params: GetUsersListParams) => {
  const response = await api.get<GetUsersListResponse>(
    `${CHATS_BASE_URL}/users.list`,
    params,
  );

  if (!response.ok || !response.data?.ok) {
    throw new Error(response.problem || 'Failed to fetch users list');
  }

  return {
    data: response.data.members,
    nextCursor: response.data.response_metadata?.next_cursor,
  };
};

export const getUserInfo = async (params: GetUserInfoParams) => {
  if (isNaN(params.user)) {
    throw new Error(`Invalid user ID. ${params.user} is not a number.`);
  }

  if (!params.fromServer) {
    const localUser = await getUserById(params.user);

    if (localUser) {
      return [
        mapUserFromDB(localUser),
        {isFromDB: true, isFromServer: false},
      ] as const;
    }
  }

  const response = await api.get<GetUserInfoResponse>(
    `${CHATS_BASE_URL}/users.info`,
    params,
  );

  if (!response.ok || !response.data?.ok) {
    throw new Error(response.problem || 'Failed to fetch users list');
  }

  const user = mapUserFromServer(response.data.user);

  return [user, {isFromDB: false, isFromServer: true}] as const;
};

export const getUsersInfo = async (ids: number[]) => {
  const usersRecord: Record<number, HuDataMember> = {};

  // Get users info from DB
  const users = await getUsersById(ids);

  for (const user of users) {
    usersRecord[user.id] = mapUserFromDB(user);
  }

  // Check if we have all users in the record
  const missingUserIds = ids.filter(id => !usersRecord[id]);

  if (missingUserIds.length) {
    const response = await api.get<GetUsersInfoResponse>(
      `${CHATS_BASE_URL}/users.infos`,
      {userIds: missingUserIds},
    );

    if (!response.ok || !response.data?.ok) {
      sentryLogs.error({
        message: 'Failed to fetch user infos for IDs',
        module: 'CHATS',
        component: 'getUsersInfo',
        data: {
          problem: response.problem,
          status: response.status,
          data: response.data,
          userIdsCount: missingUserIds.length,
        },
      });
      throw new Error(
        `Failed to fetch users infos: ${response.problem} (status: ${response.status})`,
      );
    }

    for (const user of response.data.members) {
      const mappedUser = mapUserFromServer(user);
      usersRecord[mappedUser.id] = mappedUser;
    }
  }

  return usersRecord;
};
