import { put, takeLatest, all, call, select } from 'redux-saga/effects';
import app from 'store/app';
import auth from 'store/auth';

import { userInit } from 'store/account/sagas';
import { StoreState } from 'store/rootReducer';

import { loadContent } from 'store/content/sagas';
import { config } from 'config/general';
import { onAuthStateChanged } from 'store/utils/firebase';
import { genericCall } from 'store/utils/sagas';
import { getRouteInfoFromLocation } from 'store/utils/routes';
import qs from 'query-string';
import StaticData from 'server/staticData';
import content from 'store/content';
import general from './general';
import workspace from './workspace';
import { treatmentSearch } from './workspace/sagas';
import account from './account';
import order from './order';

export function* bootupBackend(apiCalls) {
  apiCalls = apiCalls || [];

  // check for static files
  const instance = StaticData.getInstance();

  const data = instance?.data || {};
  // content caching
  if (data.content) {
    yield put(content.actions.content.set.action(data.content));
  } else {
    apiCalls.push(call(loadContent));
  }

  if (data.equipment) {
    yield put(general.actions.equipment.result.action(data.equipment, 'fulfilled'));
  } else {
    apiCalls.push(call(genericCall, general.actions.equipment));
  }

  if (data.feature) {
    yield put(general.actions.feature.result.action(data.feature, 'fulfilled'));
  } else {
    apiCalls.push(call(genericCall, general.actions.feature));
  }

  // other cacheable APIS can be added here

  if (apiCalls.length) {
    yield all(apiCalls);

    const loadedContent = yield select((state: StoreState) => state.content.raw);
    const loadedEquipments = yield select((state: StoreState) => state.general.equipment?.data);
    const loadedFeatures = yield select((state: StoreState) => state.general.feature?.data);

    instance.setData('content', loadedContent);
    instance.setData('equipment', loadedEquipments);
    instance.setData('feature', loadedFeatures);
  }
}

export function* bootup(url?: string, query?: object): Saga<void> {
  const routeInfo = url && getRouteInfoFromLocation(url);

  const { lg, params, searchParams, path } = routeInfo;

  console.log('route url - path', url, '-', path, query);

  yield put(app.actions.loader.show.action());

  const apiCalls = [];

  if (__SSR__) {
    yield call(bootupBackend, apiCalls);
  } else {
    yield call(loadContent);
    apiCalls.push(call(genericCall, general.actions.equipment));
    apiCalls.push(call(genericCall, general.actions.feature));
  }

  const session = yield select(auth.selectors.getSession);
  if (session) {
    // load user
    apiCalls.push(call(userInit));
    // load my workspaces
    apiCalls.push(call(genericCall, workspace.actions.mine));
    apiCalls.push(call(genericCall, order.actions.current));
  }

  // Home
  if (path === 'home') {
    apiCalls.push(
      call(genericCall, workspace.actions.list, {
        data: treatmentSearch(searchParams),
      }),
    );
  }

  yield all(apiCalls);

  yield put(app.actions.bootup.result.action());
  yield put(app.actions.loader.hide.action());
}

function* bootupWatcher(): Saga<void> {
  yield all([yield takeLatest(app.actions.bootup.request.constant, bootup)]);
}

export default function* saga(): Saga<void> {
  yield call(bootupWatcher);
}
