import { useLocation, useNavigate } from 'react-router-dom';
import { categoriesApi, useGetLoginMutation } from '../../store/categoriesApi';
import { setCredentials } from '../../store/authSlice';
import { CartClear } from '../../store/cartSlice';

export function getGql (endpoint){
    let headers = {
        'Content-Type': 'application/json;charset=utf-8',
        'Accept': 'application/json'
    }
    


    return async function gql(query, variables={}) {
      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

    }
}

 export const gql = getGql('http://shop-roles.node.ed.asmer.org.ua/graphql')


    /*Запрос на список корневых категорий
Используем CategoryFind, однако в параметре query используем поиск по полю parent, которое должно быть равно null. (у корневых категорий нет родителя)*/

 export const gqlRootCats = () => 
    gql(`query baseCategory($searchNullparent: String){
      CategoryFind(query: $searchNullparent){
        _id name parent {
          _id
          name
        }
      }
    }`, {
      searchNullparent: JSON.stringify([{parent: null}])
    })

  //gqlRootCats().then(console.log)

 export const gqlRootCats1 = {
  query: `query baseCategory($searchNullparent: String){
    CategoryFind(query: $searchNullparent){
      _id name parent {
        _id
        name
      }
    }
  }`,
  variables: {
    searchNullparent: JSON.stringify([{parent: null}])
  }
 }


  /*Запрос для получения одной категории с товарами и картинками
Используем CategoryFindOne, передав _id. Попросите GraphQL прислать вам товары из этой категории, а так же подкатегории. Параметр: _id*/


export const gqlCategoryGoodsAndSubCategoryGoods = (_id) => 
gql(`query CategoryGoodsAndSubCategoryGoods($qCategoryId: String) {
  CategoryFindOne(query: $qCategoryId){
    _id
    name
    parent{
      _id
      name
    }
    subCategories{
      _id
      name
      goods{
        _id
        name
      }
    }
    goods{
      _id name price 
      images {
        url
      }
    }
  }
}`, {
  qCategoryId: JSON.stringify([{ _id }])
})

//gqlCategoryGoodsAndSubCategoryGoods("62c94b10b74e1f5f2ec1a0dd").then(console.log)

export const CategoryFindOne = (_id) => ({
  query: `query CategoryFindOne($qCategoryId: String) {
    CategoryFindOne(query: $qCategoryId){
      _id
      name
      parent{
        _id
        name
      }
      subCategories{
        _id
        name
        goods{
          _id
          name
        }
      }
      goods{
        _id name price 
        images {
          url
        }
      }
    }
  }`,
  variables: {
    qCategoryId: JSON.stringify([{ _id }])
  }
 })

/*Запрос на получение товара с описанием и картинками
Аналогично предыдущему запросу, но используем GoodFindOne, так же по _id. Параметр: _id*/

export const GoodFindOne = (_id) => ({
  query: `query oneProduct($GoodId: String){
  GoodFindOne(query: $GoodId){
    _id
    description
    name
    price
    images{
      url
    }
  }  
}`,
variables: {
    GoodId: JSON.stringify( [{ _id }] )
}
})

//gqlOneGoodWithDescriptionAndImages("62c94990b74e1f5f2ec1a0db").then(console.log)

const gqlOneGoodWithDescriptionAndImages = (_id) => 
gql(`query oneGoodWithDescriptionAndImages($GoodId: String){
  GoodFindOne(query: $GoodId){
    _id
    description
    name
    price
    images{
      url
    }
  }  
}`, {
    GoodId: JSON.stringify( [{ _id }] )
})



/*Запрос на регистрацию
Используется мутация UserUpsert без указания _id пользователя. С указанием _id будет работать редактирование (обновление профиля). Параметры - логин и пароль*/

const gqlUserAdd = (login, password) => 
gql(`mutation registration($login:String, $password: String){
  UserUpsert(user: {login:$login, password: $password}){
      _id login createdAt
  }
}`, {
      login,
      password
  }
)

//gqlUserAdd("vasya321986320915sf5654755ssddgfg", "пороль").then(console.log)


/*Запрос на логин
query login. В ответ приходит токен. Пригодится для залогинивания через authReducer. Параметры: логин и пароль.*/

const gqllogin = (login, password) => 
gql(`query login($login:String, $password:String){
  login(login:$login, password:$password)
}`, {
      login,
      password
  }
)

// gqllogin("vasya321986320915sf5654755ssddgfg", "пороль").then(x => {console.log(x)
//   localStorage.authToken = x})



/*Запрос истории заказов
OrderFind. По умолчанию возвращает все ваши заказы (но не чужие). Если вы аноним - то и заказов у вас нет;*/

const gqlOrderFind = () => 
gql(`query {
    OrderFind(query: "[{}]") {
        _id
        createdAt
        total
    }
}`, 
)

//gqlOrderFind().then(console.log)


/*Запрос оформления заказа
Мутация OrderUpsert с массивом orderGoods, в которых есть объект good с единственным полем - _id, а также count. Используя этот запросы мы будем передавать информацию из cartReducer на сервер для оформления заказа. Параметр: массив orderGoods с элементами вида {good: {_id}, count}. Параметров нет, так как thunk может прочитать состояние редьюсера корзины используя передаваемый в него getState. После успешного оформления заказа на бэке задиспатчить экшон очистки корзины;*/

//version2

const OrderUpsert2 = (arrGoods) => 
gql(`mutation ($arrGoods: [OrderGoodInput]){
  OrderUpsert(order: {orderGoods: $arrGoods}) {
    _id, total, orderGoods {
      good {
        name
      }
    }
  }
}`, {
  arrGoods 
}
)

// єкшены

export const actionSetNick = (nick) =>
  async (dispatch, getState) => {
    const auth = getState().auth
    if (auth.token) {
      dispatch(categoriesApi.endpoints.setNick.initiate({ _id: auth.user.sub.id, nick }))
    }
  }

  export const actionSetNewUser = (userData) =>
  async (dispatch, getState) => {

    // const navigate = useNavigate()
    // const location = useLocation()
    // const fromPage = location.state?.from?.pathname || '/'

    console.log('userData', userData)
    const response = await dispatch(categoriesApi.endpoints.setNewUser.initiate(userData))
    console.log('setNewUser response',response)
    const payload = response?.data?.UserUpsert
    console.log('payload setNewUser', payload)
    const {data: tokenResponseData} = await dispatch( categoriesApi.endpoints.getLogin.initiate({
        login: userData.login,
        password: userData.password
    }))
    console.log(tokenResponseData)
    if (tokenResponseData?.login) {
      const user = jwtDecode(tokenResponseData?.login)
            if (user) {
                dispatch(setCredentials({ user, token: tokenResponseData.login  }))
                console.log(user.sub.id)
                // navigate(fromPage, {replace: true})
                return true
            }
    }

  }

  function jwtDecode(token) {
    let result;
    try {
        let secondPartToken = token.split('.')[1];
        result = JSON.parse(atob(secondPartToken));
    } catch (e) {
    }

    return result;
}

export const actionOrderUpsert = (arrGoods) =>
async (dispatch, getState) => {
    const res = await dispatch(categoriesApi.endpoints.setOrderUpsert.initiate(arrGoods))
    if (res?.data?.OrderUpsert) {
      dispatch(CartClear())
    }
  }