import { createApi } from '@reduxjs/toolkit/query/react'
import { gql } from 'graphql-request'
import { graphqlRequestBaseQuery } from '@rtk-query/graphql-request-base-query'

export const categoriesApi = createApi({
  reducerPath: 'categoriesApi',
  baseQuery: graphqlRequestBaseQuery({
    url: 'http://shop-roles.node.ed.asmer.org.ua/graphql',
    prepareHeaders: (headers, { getState }) => {
      // By default, if we have a token in the store, let's use that for authenticated requests
      const token = getState().auth.token;
      if (token) {
        headers.set("Authorization", `Bearer ${token}`);
      }
      return headers;
    }
  }),
  endpoints: (builder) => ({
    getCategories: builder.query({
      query: () => ({
        document: gql`query baseCategory($searchNullparent: String){
                    CategoryFind(query: $searchNullparent){
                      _id name parent {
                        _id
                        name
                      }
                    }
                  }`,
        variables: {
          searchNullparent: JSON.stringify([{ parent: null }]),
        },
      })
    }),
    getCategory: builder.query({
      query: (_id) => ({
        document: gql`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 }])
        }
      })
    }),
    getProduct: builder.query({
      query: (_id) => ({
        document: gql`query oneProduct($GoodId: String){
                    GoodFindOne(query: $GoodId){
                      _id
                      description
                      name
                      price
                      categories{
                        _id
                        name
                      }
                      images{
                        _id
                        url                        
                      }
                    }  
                  }`,
        variables: {
          GoodId: JSON.stringify([{ _id }])
        }
      })
    }),
    getLogin: builder.mutation({
      query: ({ login, password }) => ({
        document: gql`query login($login:String, $password:String){
                    login(login:$login, password:$password)
                  }`,
        variables: {
          login,
          password
        }
      }),
      invalidatesTags: (result, error, arg) => ([{ type: 'UserOrders' }])
    }),
    getUser: builder.query({
      query: (_id) => ({
        document: gql`query oneUser($UserId: String){
                UserFindOne(query: $UserId){
                    _id
                    login
                    nick
                    avatar
                    
                  }
                }`,
        variables: {
          UserId: JSON.stringify([{ _id }])
        }
      })
    }),
    getUserById: builder.query({
      query: (_id) => ({
        document: gql`
                query GetUser($q: String) {
                    UserFindOne(query: $q) {
                        _id
                        login
                        nick
                        avatar { url }
                    }
                }
            `,
        variables: { q: JSON.stringify([{ _id }]) }
      }),
      providesTags: (result, error, id) => ([{ type: 'User', id }])
    }),
    getUserOrders: builder.query({
      query: ({ limit, skip, sort }) => ({
        document: gql`
        query( $q: String ) {
          OrderFind(query: $q) {
              _id
              createdAt
              total
              orderGoods {
                _id
                createdAt
                price
                count
                goodName
                total
              }
          }
      }`,
        variables: {
          q: JSON.stringify([{}, { limit: [limit], skip: [skip], sort: [sort] }])
        }
      }),
      providesTags: (result, error, id) => ([{ type: 'UserOrders' }])
    }),
    getOrdersCount: builder.query({
      query: () => ({
        document: gql`
        query {
          OrderCount(query: "[{}]")
        }
        `,
        variables: {}
      }),
      providesTags: (result, error, id) => ([{ type: 'UserOrders' }])
    }),
    setNick: builder.mutation({
      query: ({ _id, nick }) => ({
        document: gql`
              mutation SetNick($_id:String, $nick: String){
                  UserUpsert(user: {_id: $_id, nick: $nick}){
                      _id, nick
                  }
              }
          `,
        variables: { _id, nick }
      }),
      invalidatesTags: (result, error, arg) => ([{ type: 'User', id: arg._id }])
    }),
    setNewUser: builder.mutation({
      query: ({ login, password, ...args }) => ({
        document: gql`
        mutation registration($login:String, $password: String,  $nick: String){
          UserUpsert(user: {login: $login, password: $password, nick: $nick}){
              _id login createdAt nick
          }
        }
          `,
        variables: { login, password, nick: args?.nick || "" }
      }),
      invalidatesTags: (result, error, arg) => ([{ type: 'UserOrders' }])
    }),
    setOrderUpsert: builder.mutation({
      query: (arrGoods) => ({
        document: gql`
        mutation ($arrGoods: [OrderGoodInput]){
          OrderUpsert(order: {orderGoods: $arrGoods}) {
            _id, total, orderGoods {
              good {
                name
              }
            }
          }
        }
          `,
        variables: { arrGoods }
      }),
      invalidatesTags: (result, error, arg) => ([{ type: 'UserOrders' }])
    }),
    getGoodFind: builder.query({
      query: ({ categoryId = null, sort = null, limit = null, skip = null }) => ({
        document: gql`
        query($q: String) {
          GoodFind(query:$q){
      _id
      name
      price
      createdAt
      description
      categories{
        _id
        name
      }
      images{
        url
      }
    }
    }
        `,
        variables: {
          q: JSON.stringify([categoryId ? { "categories._id": categoryId } : {}, { limit: [limit], sort: [sort], skip: [skip] }])
          // sort должен быть обьект вида {поле сортировки: 1 или -1} где 1 сортировка по возрастаниюб -1 по убыванию.
          // limit число от 1 до 100
          // categoryId обязательный параметр иначе вернет пустой массив goods
        }
      }),
      providesTags: (result, error, arg) => ([{ type: 'Good' }])
    }),
    getGoodCount: builder.query({
      query: ({ categoryId = null }) => ({
        document: gql`
        query($q: String) {
          GoodCount(query: $q)
        }
        `,
        variables: {
          q: JSON.stringify([categoryId ? { "categories._id": categoryId } : {}])
        }
      }),
      providesTags: (result, error, arg) => ([{ type: 'Good' }])
    }),
    getUserOrders2: builder.query({
      query: ({ limit, skip, sort, userId = null }) => ({
        document: gql`
        query( $q: String ) {
          OrderFind(query: $q) {
              _id
              createdAt
              total
              orderGoods {
                _id
                createdAt
                price
                count
                goodName
                total
              }
          }
      }`,
        variables: {
          q: JSON.stringify([{ ___owner: userId }, { limit: [limit], skip: [skip], sort: [sort] }])
        }
      }),
      providesTags: (result, error, id) => ([{ type: 'UserOrders' }])
    }),
    setGoodUpsert: builder.mutation({
      query: (good) => ({
        document: gql`
        mutation GoodUpsert($good: GoodInput){
          GoodUpsert(good:$good)
           {
              _id
              createdAt
              name
              description
              price
              categories {_id name}
              images {_id url}
            }
        }
          `,
        variables: {
          good
        }
      }),
      invalidatesTags: (result, error, arg) => ([{ type: 'Good' }])

    }),
    getCategoriesAll: builder.query({
      query: () => ({
        document: gql`
      query CategoryFindAll{
        CategoryFind(query:"[{}]") {
          _id
          name
          parent{ _id }
          subCategories {_id}
          
        }
      }
      `,
        variables: {

        }
      }),
      providesTags: (result, error, arg) => ([{ type: 'Category' }])
    }),
  })
})

export const {
  useGetCategoriesQuery,
  useGetCategoryQuery,
  useGetProductQuery,
  useGetLoginMutation,
  useGetUserQuery,
  useGetUserByIdQuery,
  useGetUserOrdersQuery,
  useGetOrdersCountQuery,
  useGetGoodFindQuery,
  useGetGoodCountQuery,
  useGetUserOrders2Query,
  useSetGoodUpsertMutation,
  useGetCategoriesAllQuery,
} = categoriesApi







