import { OrganizationApi } from '@openapi/idm';
import omit from 'lodash/omit';
import { ActionContext, ActionTree, GetterTree, MutationTree } from 'vuex';
import { State } from '@/types/store/scopes';

const countPending: Record<string, any> = {};
const countCache: Record<string, any> = {};
const organizationApi: OrganizationApi = new OrganizationApi();

let lastOpts: string | number = '';

export const state: State = {
  card: null,
  loading: false,
  records: [],
  rowsNumber: 0,
};

export const getters: GetterTree<State, State> = {
  organizationName(state) {
    return (
      state.card?.shortname || state.card?.name || state.card?.fullname || ''
    );
  },
  organizationsCard(state) {
    return state.card;
  },
  organizationsLastRecord(state) {
    return state.lastRecord;
  },
  organizationsLoading(state) {
    return state.loading;
  },
  organizationsRecords(state) {
    return state.records;
  },
  organizationsRowsNumber(state) {
    return state.rowsNumber;
  },
};

export const mutations: MutationTree<State> = {
  organizationsCard(state, card: null | any) {
    state.card = card;
  },
  organizationsLastRecord(state, val) {
    state.lastRecord = val || 0;
  },
  organizationsLoading(state, loading) {
    state.loading = loading;
  },
  organizationsRecords(state, records) {
    state.records = records;
  },
  organizationsRowsNumber(state, rowsNumber) {
    state.rowsNumber = rowsNumber;
  },
};

export const actions: ActionTree<State, State> = {
  getOrganization(
    { commit }: ActionContext<State, State>,
    { id, opts = {} } = {}
  ) {
    commit('organizationsLoading', true);

    return organizationApi
      .getOrganization(id, opts.expand)
      .then(({ data }) => {
        commit('organizationsLoading', false);
        commit('organizationsCard', data);

        return data;
      })
      .catch(() => {
        throw new Error('[store][modules][organizations][getOrganizations]');
      });
  },
  dispatchOrganizations({ commit }: ActionContext<State, State>, opts = {}) {
    commit('organizationsLoading', true);

    lastOpts = JSON.stringify(omit(opts, 'perPage', 'page'));

    if (typeof countCache[lastOpts] === 'number') {
      commit('organizationsRowsNumber', countCache[lastOpts]);
    }

    return organizationApi
      .pagingOrganizations(
        opts.handler,
        opts.page,
        opts.perPage,
        opts.query,
        opts.fulltext,
        opts.sort,
        opts.expand,
        opts.options
      )
      .then(({ data }) => {
        commit('organizationsLoading', false);
        commit('organizationsRecords', data.records);

        if (lastOpts) {
          countCache[lastOpts] = Number(data.totalRows || 0);
          commit('organizationsRowsNumber', countCache[lastOpts]);
        }

        return data.records;
      })
      .catch(() => {
        throw new Error(
          '[store][modules][idm][organizations][dispatchOrganizations]'
        );
      });
  },
};
