import { toast } from 'react-toastify';
const axios = require('axios');
axios.defaults.baseURL = 'http://localhost:3000/api';

const error = (message:string) =>
  toast.error(`🔥 ${message}!`, {
    position: 'bottom-left',
    autoClose: 3000,
    hideProgressBar: false,
    closeOnClick: true,
    pauseOnHover: true,
    draggable: true,
    progress: undefined,
  });

const success = (message:string) =>
  toast.success(`⚡ ${message}`, {
    position: 'bottom-left',
    autoClose: 3000,
    hideProgressBar: false,
    closeOnClick: true,
    pauseOnHover: true,
    draggable: true,
    progress: undefined,
  });

const setToken = {
  set(token:string) {
    axios.defaults.headers.common.Authorization = `Bearer ${token}`;
  },
  unset() {
    axios.defaults.headers.common.Authorization = '';
  },
};

const forbidden = ({ message }: any) => {
  if (message.slice(-3) === '403') {
    localStorage.removeItem('persist:auth')
    window.location.reload(true);
  }
}

const authorizeUser = async (number:string,country:string):Promise<string | undefined> => {
  try {
    const { data : {data} } = await axios.post('/auth/register', { number,country });
    success(`code ${data}`);
    return data
  } catch (e) {
    return undefined
  }
};

const loginUser = async <T>(number:string,code:string):Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.patch('/auth/login', { number,code });
    return data
  } catch (e) {
    return undefined
  }
};

const logoutUser = async <T>():Promise<T | undefined> => {
  try {
    const { data } = await axios.patch('/auth/logout');
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const onlineUser = async <T>():Promise<T | undefined> => {
  try {
    const { data } = await axios.patch('/auth/online');
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const updateCredentials = async <T>(body:object):Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.patch('/users/current', body);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const updateUserAvatar = async <T>(formData: object): Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.patch('/users/avatars', formData);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  } 
};

const currentUser = async <T>(): Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.get('/users/current');
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  } 
};

const addContact = async <T>(number:string): Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.post('/contacts', { number });
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const removeContact = async <T>(id:string): Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.delete(`/contacts/${id}`);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const updateContact = async <T>(id:string,_id:string,name:string,lastName:string): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.patch('/contacts', { id, _id, name, lastName });
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const getContacts = async <T>(): Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.get('/contacts');
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const getChatById = async <T>(id:string): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.get(`/chats/${id}`);
    return data._doc
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const startChat = async <T>(id:string): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.post('/chats', { id });
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const removeChatForBoth = async <T>(id:string): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.delete(`/chats/both/${id}`);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const muteChat = async <T>(id:string): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.patch('/chats/mute', {id});
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const sortChat = async <T>(id:string): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.patch('/chats/sort', {id});
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const seenChat = async <T>(id:string): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.patch('/chats/seen', { id });
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const typingChat = async <T>(id:string,typing:boolean): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.patch('/chats/typing', { id,typing});
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const getChats = async <T>(): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.get('/chats');
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const sentMessageById = async <T>(id:string,message:any): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.post('/messages', { id, message });
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const sentImgMessageById = async <T>(id:string,formData: object): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.post(`/messages/image/${id}`, formData);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const sentAudioMessageById = async <T>(id:string,formData: object): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.post(`/messages/audio/${id}`, formData);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const sentVideoMessageById = async <T>(id:string,formData: object): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.post(`/messages/video/${id}`, formData);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const sentFileMessageById = async <T>(id:string,formData: object): Promise<T | undefined> => {
  try {
    const { data: { data } } = await axios.post(`/messages/file/${id}`, formData);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const getMessagesById = async <T>(id:string): Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.get(`/messages/${id}`);
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

const getAllMessages = async <T>(): Promise<T | undefined> => {
  try {
    const { data : {data} } = await axios.get('/messages');
    return data
  } catch (e) {
    forbidden(e)
    return undefined
  }
};

export {
  setToken,
  error,
  success,
  authorizeUser,
  loginUser,
  logoutUser,
  onlineUser,
  updateCredentials,
  updateUserAvatar,
  currentUser,
  addContact,
  removeContact,
  updateContact,
  getContacts,
  startChat,
  removeChatForBoth,
  getChatById,
  muteChat,
  sortChat,
  seenChat,
  typingChat,
  getChats,
  sentMessageById,
  sentImgMessageById,
  sentAudioMessageById,
  sentVideoMessageById,
  sentFileMessageById,
  getMessagesById,
  getAllMessages
};
