import { store } from "."

const url = 'http://hipstagram.node.ed.asmer.org.ua/graphql'

// функция getGql
function getGql(endpoint) {
  return async function gql(query, variables = {}) {

    let headers = {
      'Content-Type': 'application/json;charset=utf-8',
      'Accept': 'application/json',
    }
    if (('authToken' in localStorage)) {
      headers.Authorization = 'Bearer ' + localStorage.authToken
    }

    let result = await fetch(endpoint, {
      method: 'POST',
      headers,
      body: JSON.stringify({
        query,
        variables
      })
    }).then(res => res.json())

    if (('errors' in result) && !('data' in result)) {
      throw new Error(JSON.stringify(result.errors))
    }

    result = Object.values(result.data)[0]

    return result
  }
}

const gql = getGql(url)

// акшоны для promiseReducer
export const actionPending = nameOfPromise => ({ nameOfPromise, type: 'PROMISE', status: 'PENDING' })
export const actionFulfilled = (nameOfPromise, payload) => ({ nameOfPromise, type: 'PROMISE', status: 'FULFILLED', payload })
export const actionRejected = (nameOfPromise, error) => ({ nameOfPromise, type: 'PROMISE', status: 'REJECTED', error })
export const actionPromise = (nameOfPromise, promise) =>
  async dispatch => {
    dispatch(actionPending(nameOfPromise)) //сигнализируем redux, что промис начался
    try {
      const payload = await promise //ожидаем промиса
      dispatch(actionFulfilled(nameOfPromise, payload)) //сигнализируем redux, что промис успешно выполнен
      return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
    }
    catch (error) {
      dispatch(actionRejected(nameOfPromise, error)) //в случае ошибки - сигнализируем redux, что промис несложился
    }
  }

// =============================================================
// запрос на поиск конкретного поста
export const actionFindPostOne = _id => actionPromise('PostFindOne', gql(`query OnePostFind ($postOne: String){
  PostFindOne (query: $postOne) {
    _id createdAt title text likesCount
    images {
      url
    }
    comments {
      _id createdAt text answers {
        _id createdAt text likes {
          _id
        }
        likesCount owner {
          _id login nick  avatar {
            _id url
          }
        }
      }
      likesCount
    }
    owner {
      _id login nick avatar {
        _id url
      }
    }
    
  }
}`, {
  postOne: JSON.stringify([{ _id }])
}))


// запрос на поиск конкретного юзера
export const actionFindUserOne = (_id, promiseName = 'UserFindOne') => actionPromise(promiseName, gql(`query OneUserFind ($userOne: String) {
    UserFindOne(query: $userOne) {
      _id createdAt login nick 
      avatar {
        _id url
      } 
       followers {
        _id login nick avatar {_id url}
      }
      following {
         _id login nick avatar {_id url}
      }
    }
  }`, {
  userOne: JSON.stringify([{ _id }])
}))


// запрос на поиск всех постов
export const actionfindPosts = () => actionPromise('PostsFind', gql(`query AllPostsFind ($allPosts: String){
  PostFind(query: $allPosts){
    _id createdAt title text likesCount
    images {
      url
    }
    owner {
      _id login nick
    }
    
  }
}`, {
  allPosts: JSON.stringify([{}])
}))


// =================
// акшон для логинизации
const actionAuthLogin = token => ({ type: 'AUTH_LOGIN', token })
// акшон для раззлогинивания
const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })

// Запрос на логин
export const actionLogin = (login, password) => actionPromise('Login', gql(`query Login($login: String!, $password: String!) {
login(login: $login, password: $password)
}`, {
  login,
  password
}))

// Запрос на логин и последующую логинизацию в authReduser (thunk)
export const actionFullLogin = (login, password) =>
  async dispatch => {
    const token = await dispatch(actionLogin(login, password))

    try {
      if (token != null) {
        if (typeof (token) === 'string') {
          dispatch(actionAuthLogin(token))
          localStorage.authToken = token
        }
      }
    }

    catch (error) {
      console.log(error)
    }
  }

// ========================







// Запрос на поиск ленты постов
export const actionFeedFindOne = (arr, sortOne) => actionPromise('Feed', gql(`query FeedFindOne ($feedOne: String){
	PostFind(query: $feedOne){
            _id createdAt title text likesCount owner{
              _id login avatar{
                url
              }
            }
            comments {
              _id
            }
    images{
      url
    }
    	}
    }`, {
  feedOne: JSON.stringify([{ ___owner: { $in: arr } }, { sort: [{ _id: sortOne }] }])
}))





// =============================
// Запрос для создания страницы юзера
export const actionFullUserFindOne = _id =>
  async dispatch => {
    await dispatch(actionFindUserOne(_id))
    dispatch(actionFeedFindOne([_id], -1))
  }
// ==============================



// запрос для главной страницы ленты
export const actionFeedFind = (id, sort) =>
  async (dispatch, getState) => {
    const userData = await dispatch(actionFindUserOne(id))
    console.log('userData: ', userData)

    // собираем список подписчиков
    let followingList = []

    for (const item of userData.following)
      for (const [key, value] of Object.entries(item)) {
        if (key === '_id') {
          followingList.push(value)
        }
      }
    console.log('followingList: ', followingList)

    // console.log(666, store.getState().promise?.Feed?.status !== 'FULFILLED')

    // if (store.getState().promise?.Feed?.status !== 'FULFILLED') {
    dispatch(actionFeedFindOne(followingList, sort))
    // }
  }




// запрос на загрузку картинок на бек
function fileUpload(file) {
  const formData = new FormData()
  formData.append('photo', file)


  return (
    fetch('http://hipstagram.node.ed.asmer.org.ua/upload', {
      method: 'POST',
      headers: {
        Authorization: 'Bearer ' + localStorage.authToken
      },
      body: formData
    }).then(res => res.json())
  )
}

function filesUpload(files) {
  return Promise.all(files.map(fileUpload))
}

export const actionFilesUpload = (files) => actionPromise('FilesUpload',
  filesUpload(files)
)



// запрос на создание поста
export const actionCreatePost = (params) => actionPromise('CreatePost', gql(
  `mutation CreatePost($createNewPost: PostInput){
  PostUpsert(post: $createNewPost){
    _id
  }
}`, {
  createNewPost: params
}))

// санк для создания поста и последующего перехода на его страницу
export const actionFullCreatePost = (params) =>
  async dispatch => {
    const newPost = await dispatch(actionCreatePost(params))
    console.log('Тут нужный резульата: ', newPost)

    if (newPost) {
      dispatch(actionFindPostOne(newPost._id))
    }
  }





