import React, { createContext, useContext, ReactNode, useEffect } from 'react';
import { Drivers, Storage } from '@ionic/storage';
import { AppOnRecorderProvider } from '../AppOnRecorder';

import { Helloworld } from './Helloworld';
import { FullmarkCountProvider } from './FullmarkCount';
import { ListeningPracticeTimeSpentProvider } from './ListeningPracticeTimeSpent';
import { MatchingFrenzyCorrectCountProvider } from './MatchingFrenzyCorrectCount';
import { ConnectivesRevisionCorrectCountProvider } from './ConnectivesRevisionCorrectCount';
import { AppUseTimeProvider } from './AppUseTime';

const metric_store = new Storage({
  name: 'app_metrics',
  driverOrder: [Drivers.IndexedDB, Drivers.LocalStorage]
});

const MyContext = createContext<MyContextProps | undefined>(undefined);

export const MyIonMetricProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  async function myIonStoreRead(key: string, not_found_output: any = {}) {
    const output = (await metric_store.get(key)) || JSON.stringify(not_found_output);
    return output;
  }

  async function myIonStoreWrite(key: string, value: string) {
    await metric_store.set(key, value);
  }

  useEffect(() => {
    (async () => {
      await metric_store.create();
    })();
  }, []);

  return (
    <MyContext.Provider
      value={{
        myIonStoreRead,
        myIonStoreWrite,
        //
        Helloworld
      }}
    >
      <AppUseTimeProvider>
        <AppOnRecorderProvider />
        <FullmarkCountProvider>
          <ListeningPracticeTimeSpentProvider>
            <MatchingFrenzyCorrectCountProvider>
              <ConnectivesRevisionCorrectCountProvider>
                {/*  */}
                {children}
              </ConnectivesRevisionCorrectCountProvider>
            </MatchingFrenzyCorrectCountProvider>
          </ListeningPracticeTimeSpentProvider>
        </FullmarkCountProvider>
      </AppUseTimeProvider>
    </MyContext.Provider>
  );
};

export const useMyIonMetric = (): MyContextProps => {
  const context = useContext(MyContext);
  if (!context) {
    throw new Error('useMyContext must be used within a MyProvider');
  }
  return context;
};

interface MyContextProps {
  myIonStoreRead: (key: string, not_found_output: any) => Promise<any>;
  myIonStoreWrite: (key: string, value: string) => Promise<void>;
  //

  //
  Helloworld: () => void;
}
