/// <reference lib="webworker" />
import { initDb } from '../db';
import { getAccounts, putAccount } from '../db/account';
import { cancelWatch, getAndWatch } from '../db/change-handler';
import {
  putNewGpx,
  existsGpx,
  pruneAndSaveImportedGpx,
  getGpx,
  putGpx,
  appendTrk,
  getAllGpxes,
  getAllGpxesWithSummary,
} from '../db/gpx';
import { putRte } from '../db/rte';
import { putRtept } from '../db/rtept';
import { getSettings, putSettings } from '../db/settings';
import { getState, setState } from '../db/state';
import { deleteTrk, getTrk, putNewTrk } from '../db/trk';
import { putTrkpt } from '../db/trkpt';
import { getTrkseg, appendTrkpt } from '../db/trkseg';
import { getWpt, putWpt } from '../db/wpt';
import { until } from '../lib/async-wait';

//const self = globalThis as unknown as WorkerGlobalScope;

console.log({ caller: 'dispatcher-worker' });

declare global {
  var dbReady: boolean;
}

globalThis.dbReady = false;

onmessage = async function (e) {
  const actions = {
    initDb,
    putNewGpx,
    putNewTrk,
    existsGpx,
    pruneAndSaveImportedGpx,
    getAllGpxes,
    getAllGpxesWithSummary,
    getGpx,
    putGpx,
    appendTrk,
    getTrk,
    getTrkseg,
    appendTrkpt,
    getWpt,

    putWpt,
    putRte,
    putRtept,
    putTrkpt,

    deleteTrk,

    getState,
    setState,

    getAndWatch,
    cancelWatch,

    getSettings,
    putSettings,

    getAccounts,
    putAccount,
  };

  console.log({ caller: 'dispatcher-worker / onmessage', e });
  const { id, payload } = e.data;
  var returnValue: any = 'unknownAction';
  if (payload.action in actions) {
    console.log({
      caller: 'dispatcher-worker / awaiting',
      id,
      payload,
      dbReady: globalThis.dbReady,
    });
    if (payload.action !== 'initDb' && !globalThis.dbReady) {
      console.log({
        caller: 'dispatcher-worker / waiting for dbReady',
        id,
        dbReady: globalThis.dbReady,
      });
      await until(() => globalThis.dbReady, 10);
      console.log({
        caller: 'dispatcher-worker / dbReady',
        id,
        dbReady: globalThis.dbReady,
      });
    }
    returnValue = await actions[<keyof typeof actions>payload.action]({
      ...payload.params,
      _dispatchId: id,
    });
  }
  postMessage({ id: id, payload: returnValue });
  console.log({
    caller: 'dispatcher-worker / response sent',
    id,
    returnValue,
    dbReady: globalThis.dbReady,
  });
};

export const returnAgain = (id: number, returnValue: any) => {
  console.log({ caller: 'dispatcher-worker / returnAgain', id, returnValue });
  postMessage({ id: id, payload: returnValue });
};

//export default self;