import React, { createContext, useContext, useState, ReactNode, useEffect } from 'react';
import { listLessonCategories } from '../public_data';
import { Drivers, Storage } from '@ionic/storage';
import ILesson from '../interfaces/ILesson';
import { FULLMARK_COUNT_KEY } from '../constants';

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

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

export const MyIonStoreProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const [db, setDB] = useState<[]>([]);
  const [lesson_content, setLessonContent] = useState<ILesson[] | []>([]);

  const [my_context, setMyContext] = useState<string>('initial value');
  const [test_first, setTestFirst] = useState<IFirst | undefined>(undefined);
  const [test_second, setTestSecond] = useState<ISecond | undefined>(undefined);
  const [test_third, setTestThird] = useState<IThird | undefined>(undefined);

  async function myIonStoreRead(key: string, not_found_output: string = '{}'): Promise<string> {
    const output = (await user_store.get(key)) || not_found_output;
    return output;
  }

  async function myIonStoreWrite(key: string, value: string): Promise<void> {
    await user_store.set(key, value);
  }

  useEffect(() => {
    (async () => {
      let cats = await listLessonCategories();
      setLessonContent(cats);
    })();

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

  return (
    <MyContext.Provider
      value={{
        db,
        setDB,
        lesson_contents: lesson_content,
        setLessonContent,
        user_store,
        //
        myIonStoreRead,
        myIonStoreWrite,
        //
        my_context,
        setMyContext,
        test_first,
        setTestFirst,
        test_second,
        setTestSecond,
        test_third,
        setTestThird
      }}
    >
      {children}
    </MyContext.Provider>
  );
};

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

interface MyContextProps {
  //
  db: [];
  setDB: React.Dispatch<React.SetStateAction<[]>>;
  lesson_contents: ILesson[] | [];
  setLessonContent: React.Dispatch<React.SetStateAction<ILesson[] | []>>;
  user_store: Storage;
  //
  myIonStoreRead: (key: string, not_found_output?: any) => Promise<string>;
  myIonStoreWrite: (key: string, value: string) => Promise<void>;
  //
  my_context: string;
  setMyContext: React.Dispatch<React.SetStateAction<string>>;
  test_first: IFirst | undefined;
  setTestFirst: React.Dispatch<React.SetStateAction<IFirst | undefined>>;
  test_second: ISecond | undefined;
  setTestSecond: React.Dispatch<React.SetStateAction<ISecond | undefined>>;
  test_third: IThird | undefined;
  setTestThird: React.Dispatch<React.SetStateAction<IThird | undefined>>;
}

interface IFirst {
  test_s: string;
  test_i: number;
}

interface ISecond {
  test_s: string;
  test_i: number;
  content: IFirst[] | [];
}

interface IThird {
  test_s: string;
  test_i: number;
  content: ISecond[] | [];
}
