import {
  addUniversoUzanto,
  login_query,
  logout_query,
} from "src/queries/mutations";
import { listOrganizaiton, mi } from "src/queries/queries";
import { LocalStorage } from "quasar";

import { apollo } from "src/boot/apollo";

export default {
  namespaced: true,
  state() {
    return {
      auth: {
        user: null,
        isLoggedIn: null,
        konfirmita: null,
        isAdmin: null,
      },
      authData: null,
      authtoken: null,
      csrftoken: null,
      jwtToken: null,
      organizations: null,
    };
  },
  getters: {
    user: (state) => state.auth.user,
    isLoggedIn: (state) => state.auth.loggedIn,
    konfirmita: (state) => state.auth.konfirmita,
    isAdmin: (state) => state.auth.isAdmin,
    getAuthData: (state) => state.authData,
    getCsrfToken: (state) => state.csrftoken || null,
    getAuthToken: (state) => state.authtoken || null,
    getJwtToken: (state) => {
      if (state.jwtToken === "null") {
        return null;
      } else {
        return state.jwtToken || null;
      }
    },
    getMyOrganizations: (state) => {
      if (state.organizations && Array.isArray(state.organizations.edges)) {
        return state.organizations.edges.map((item) => item.node.uuid);
      } else return [];
    },
  },
  mutations: {
    setAuthData: (state, payload) => {
      state.authData = payload;
    },
    setUser: (state, payload) => (state.auth.user = payload),
    setIsLoggedIn: (state, payload) => (state.auth.loggedIn = payload),
    setKonfirmita: (state, payload) => (state.auth.konfirmita = payload),
    setIsAdmin: (state, payload) => (state.auth.isAdmin = payload),
    setAvataro: (state, payload) => {
      state.auth.user.avataro.bildoE.url = payload.bildoE.url;
      state.auth.user.avataro.bildoF.url = payload.bildoF.url;
    },
    setCsrfToken: (state, payload) => {
      state.csrftoken = payload;
      LocalStorage.set("csrftoken", payload);
    },
    setAuthToken: (state, payload) => {
      state.authtoken = payload;
      LocalStorage.set("authtoken", payload);
    },
    setJwtToken: (state, payload) => {
      state.jwtToken = payload;
      LocalStorage.set("jwtToken", payload);
    },
    setOrganizations: (state, payload) => {
      state.organizations = payload;
    },
    setAvatar: (state, payload) => {
      if (state.auth.user) {
        const temp = Object.assign({}, state.auth.user);
        temp.avataro = payload;
        state.auth.user = Object.assign({}, temp);
      }
    },
  },
  actions: {
    login({ commit }, { login, password }) {
      return apollo.registrado
        .mutate({
          mutation: login_query,
          variables: { login: login, password: password },
        })
        .then((data) => {
          const resp = data.data.ensaluti;
          if (resp.status) {
            // Успешная авторизация
            commit("setCsrfToken", resp.csrfToken);
            commit("setAuthToken", resp.token);
            commit("setJwtToken", resp.jwtToken);

            return Promise.resolve(resp);
          }
          // Неуспешная авторизация
          commit("setKonfirmita", resp.konfirmita);
          return Promise.reject(resp);

          // return Promise.reject(new Error(resp.message));
        })
        .catch((err) => {
          // console.error(err);
          // Ошибка запроса на уровне сети/протокола
          return Promise.reject(err);
        });
    },
    logout({ commit }) {
      return apollo.registrado
        .mutate({
          mutation: logout_query,
        })
        .then((data) => {
          const resp = data.data.elsaluti;
          if (resp.status) {
            // Успешный логаут
            commit("setCsrfToken", null);
            commit("setAuthToken", null);
            commit("setJwtToken", null);

            return Promise.resolve(resp);
          }
          // Неуспешная авторизация
          return Promise.reject(resp);
        })
        .catch((err) => {
          // console.error(err);
          // Ошибка запроса на уровне сети/протокола
          return Promise.reject(err);
        });
    },
    fetchOrganizations({ commit }, payload) {
      return apollo.default
        .query({
          query: listOrganizaiton,
          variables: payload,
          errorPolicy: "all",
          fetchPolicy: "network-only",
        })
        .then((data) => {
          const organizations = data.data.organizo;
          commit("setOrganizations", organizations);
          // return Promise.resolve(organizations);
        })
        .catch((error) => Promise.reject(error));
    },

    fetchUser({ commit, dispatch }) {
      return apollo.registrado
        .query({
          query: mi,
          errorPolicy: "all",
          fetchPolicy: "network-only",
        })
        .then((data) => {
          // Извлекаем результат
          const mi = data.data.mi;
          if (mi) {
            // Если получили данные пользователя
            // сохраняем данные в хранилище,
            // устанавливаем признак авторизации в True
            commit("setUser", mi);
            commit("setIsLoggedIn", true);
            commit("setKonfirmita", mi.konfirmita);
            commit("setIsAdmin", mi.isAdmin);
            dispatch("fetchOrganizations", {
              organizomembro_Uzanto_Id: mi.objId,
            });
            return Promise.resolve(mi);
          }
          // Иначе данные пользователя отсутствуют,
          // обнуляем сохранённые данные,
          // устанавливаем признак авторизации в False

          commit("setCsrfToken", null);
          commit("setAuthToken", null);
          commit("setJwtToken", null);

          commit("setUser", null);
          commit("setIsLoggedIn", false);
          commit("setIsAdmin", false);

          return Promise.resolve(data);
        })
        .catch((err) => {
          // console.error(err);
          // Если ошибка протокола/сети, то считаем, что авторизации нет, сбрасываем данные пользователя и признак авторизации
          commit("setUser", null);
          commit("setIsLoggedIn", false);
          commit("setKonfirmita", null);
          commit("setIsAdmin", null);

          return Promise.reject(err);
        });
    },
    addUniversoUzanto({ commit, dispatch }, { retnomo }) {
      return apollo.default
        .mutate({
          mutation: addUniversoUzanto,
          variables: { retnomo },
        })
        .then((data) => {
          const resp = data.data.redaktuUniversoUzanto;
          if (resp.status) {
            dispatch("fetchUser");
            return Promise.resolve(resp);
          } else {
            return Promise.reject(resp.message);
          }
        })
        .catch((err) => {
          // console.error(err);
          // Ошибка запроса на уровне сети/протокола
          return Promise.reject(err);
        });
    },
  },
};
