// ╭──────────────────────────────────────────────────────────────────────────────────╮
// │ 📌 High Order Component Overview                                                 │
// ┣──────────────────────────────────────────────────────────────────────────────────┫
// │ ➤ Internal Svelte Code Format :|: V.8.0                                          │
// │ ➤ Status :|: 🔒 LOCKED                                                           │
// │ ➤ Author(s) :|: @migbash                                                         │
// ┣──────────────────────────────────────────────────────────────────────────────────┫
// │ 📝 Description                                                                   │
// ┣──────────────────────────────────────────────────────────────────────────────────┫
// │ > Client 'Svelte/Store' with 'LocalStorage' Persistance                          │
// ╰──────────────────────────────────────────────────────────────────────────────────╯

/* eslint-disable camelcase */

// #region ➤ 📦 Package Imports

import { writable } from 'svelte/store';

import type { IAdEngineStore } from './types/ad-engine.js';

// #endregion ➤ 📦 Package Imports

// #region ➤ 📌 VARIABLES

const
  /**
   * @description
   *  📣 Target `data` store.
   */
  userSettings: IAdEngineStore
    = {
      isBetarenaAdShownForToday: false,
      advertDateLastShown: null
    }
;

type IDataProp =
  | 'toggleAdShownState'
;

// #endregion ➤ 📌 VARIABLES

// #region ➤ 🛠️ METHODS

/**
 * @author
 *  @migbash
 * @summary
 *  🟥 MAIN
 * @description
 *  - 📣 Initializer of `svelte/stores` method.
 *  - 📣 Uses `localStorage` persistance.
 * @param { string } key
 *  💠 Target `key` to use for `svelte-stores` / `localStorage`.
 * @return
 *  📤 Store logic.
 */
function createLocalStore
(
  key: string
)
{
  const
    // ╭─────
    // │ NOTE: |:| 📣 default 'svelte/store' exports.
    // ╰─────
    {
      subscribe,
      set,
      update
    } = writable
    (
      userSettings
    ),
    /**
     * @description
     * 📝 complementary `store` added methods.
     */
    methods
      = {
        // ╭──────────────────────────────────────────────────────────────────────────────────╮
        // │ 🟦 Local Helper Logic                                                            │
        // ╰──────────────────────────────────────────────────────────────────────────────────╯

        /**
         * @author
         *  @migbash
         * @summary
         *  - 🟥 MAIN
         *  - 🔹 HELPER
         *  - IMPORTANT
         * @description
         *   📣 Instantiate `localStorage` data for target `key`.
         * @return { void }
         */
        useLocalStorage:
        (
        ): void =>
        {
          let
            localStore = methods.parseLocalStorage()
          ;

          // [🐞]
          // console.log('localStore', localStore);

          // ╭─────
          // │ CHECK :|: for absent localstorage object.
          // ╰─────
          if (localStore == null)
            localStore
            = {
                isBetarenaAdShownForToday: false,
                advertDateLastShown: null,
              }
            ;
          ;

          methods.setLocalStorage
          (
            localStore
          );

          // ╭─────
          // │ CHECK :|: for already shown advert
          // ╰─────
          if (
            localStore.isBetarenaAdShownForToday
            && new Date(localStore.advertDateLastShown!).getDate() != new Date().getDate()
          )
            methods.updateData
            (
              [
                ['toggleAdShownState', undefined]
              ]
            );
          ;

          return;
        },

        /**
         * @author
         *  @migbash
         * @summary
         *  - 🟥 MAIN
         *  - 🔹 HELPER
         *  - IMPORTANT
         * @description
         *   📣 Retrieves target `localStorage` for target `key`.
         * @return { IAdEngineStore }
         *  📤 Target `user` data object.
         */
        parseLocalStorage:
        (
        ): IAdEngineStore | NullUndef =>
        {
          const
            localStore = localStorage.getItem(key)
          ;

          if (!localStore) return null;

          return JSON.parse
          (
            localStore
          );
        },

        /**
         * @author
         *  @migbash
         * @summary
         *  - 🟥 MAIN
         *  - 🔹 HELPER
         *  - IMPORTANT
         * @description
         *   📣 Persists to `localStorage` target data for target `key`.
         * @param { IAdEngineStore } data
         *  💠 **[required]** Target `user` data to be persisted.
         * @return { void }
         */
        setLocalStorage:
        (
          data: IAdEngineStore
        ): void =>
        {
          localStorage.setItem
          (
            key,
            JSON.stringify
            (
              data
            )
          );

          set
          (
            data
          );

          return;
        },

        // ╭──────────────────────────────────────────────────────────────────────────────────╮
        // │ 📣 Main Logic                                                                    │
        // ╰──────────────────────────────────────────────────────────────────────────────────╯

        /**
         * @author
         *  @migbash
         * @summary
         *  - 🔹 HELPER
         *  - IMPORTANT
         * @description
         *  📣 Update **target** `list` data of target `properties` to update.
         * @param { [IDataProp, any][] } data
         *  💠 **[required]** Target data to update.
         * @return { void }
         */
        updateData:
        (
          data: [IDataProp, any][]
        ): void =>
        {
          const
            localStore = methods.parseLocalStorage()
          ;

          if (!localStore) return;

          // ╭─────
          // │ NOTE: |:| loop over data entries
          // ╰─────
          for (const iterator of data)
          {
            const
              /**
               * @description
               * 📝 Data point `name` to be updated
               */
              dataTarget = iterator[0],
              /**
               * @description
               * 📝 Data point `value` to be set to
               */
              dataPoint = iterator[1]
            ;

            if (dataTarget == 'toggleAdShownState')
            {
              localStore.isBetarenaAdShownForToday = !localStore.isBetarenaAdShownForToday;

              if (localStore.isBetarenaAdShownForToday)
                localStore.advertDateLastShown = new Date()
              else
                localStore.advertDateLastShown = null;
              ;
            }
          }

          methods.setLocalStorage
          (
            localStore
          );

          return;
        }
      }
  ;

  return {
    subscribe,
    set,
    update,
    ...methods,
  };
}

// #endregion ➤ 🛠️ METHODS

export const betarenaAdEngineStore = createLocalStore('betarena-ad-engine');
