import {maxCachedEvents} from '@configs/appNonSaveVar';
import {appNonSaveVarActions} from '@configs/appNonSaveVarReducer';
import {AccountName, XAuthorization} from '@configs/types';
import {makeRequest, apiBackendRequest} from '@helper/request';
import BigDataManager from '@helper/storage/BigDataManager';
import {RootState, store} from '@redux/store';
import {useSelector} from 'react-redux';
import {
  BasicEventProp,
  createEventProp,
  EventBannerPicture,
  EventBannerPictureType,
  EventID,
  EventType,
  NumToEventType,
  PAEvent,
} from './types';

import {SourceProp} from '@user/types';

let cachedEventList: EventID[] = [];

async function getEvent(
  UUID: EventID,
  save?: boolean,
): Promise<PAEvent | undefined> {
  if (UUID === 'none') {
    return undefined;
  }

  let event: PAEvent | undefined;

  let state = store.getState();
  let eventIsInCache = false;

  {
    const eve = state.nonSaveVariables.cachedEvents[UUID];
    if (eve !== undefined) {
      event = eve;
      eventIsInCache = true;
    }
  }

  if (event === undefined) {
    const eveDBKeys = BigDataManager.databases.events.keys;
    const eve = await BigDataManager.databases.events.getEntry(UUID);

    if (eve !== undefined && eve !== null) {
      let EventBannerPicture: EventBannerPicture = {
        lq:
          eve[eveDBKeys.EventBannerPictureBinaryLQ].byteLength !== 0
            ? createEventProp(
                SourceProp.offline,
                //Buffer.from(eve[eveDBKeys.EventBannerPictureBinaryLQ]),
                new Blob([
                  eve[
                    eveDBKeys.EventBannerPictureBinaryLQ
                  ] as unknown as string,
                ]),
              )
            : createEventProp(
                SourceProp.online,
                undefined,
                eve[eveDBKeys.EventBannerPicture],
              ),
        hq:
          eve[eveDBKeys.EventBannerPictureBinaryHQ].byteLength !== 0
            ? createEventProp(
                SourceProp.offline,
                //Buffer.from(eve[eveDBKeys.EventBannerPictureBinaryHQ]),
                new Blob([
                  eve[
                    eveDBKeys.EventBannerPictureBinaryHQ
                  ] as unknown as string,
                ]),
              )
            : createEventProp(
                SourceProp.online,
                undefined,
                eve[eveDBKeys.EventBannerPicture],
              ),
      };

      event = {
        UUID,
        Name: createEventProp(SourceProp.offline, eve[eveDBKeys.Name]),
        Description: createEventProp(
          SourceProp.offline,
          eve[eveDBKeys.Description],
        ),
        StartDate: createEventProp(
          SourceProp.offline,
          eve[eveDBKeys.StartDate],
        ),
        EndDate: createEventProp(SourceProp.offline, eve[eveDBKeys.EndDate]),
        Latitude: createEventProp(SourceProp.offline, eve[eveDBKeys.Latitude]),
        Longitude: createEventProp(
          SourceProp.offline,
          eve[eveDBKeys.Longitude],
        ),
        Type: createEventProp(
          SourceProp.offline,
          NumToEventType(eve[eveDBKeys.Type]),
        ),
        Theme: createEventProp(SourceProp.offline, eve[eveDBKeys.Theme]),
        FriendList: createEventProp(
          SourceProp.offline,
          eve[eveDBKeys.FriendList],
        ),
        UserLength: createEventProp(
          SourceProp.offline,
          eve[eveDBKeys.UserLength],
        ),
        ButtonAction: createEventProp(
          SourceProp.offline,
          eve[eveDBKeys.ButtonAction],
        ),
        lastUpdateTimestamp: eve[eveDBKeys.lastUpdateTimestamp],
        EventBannerPicture,
      };
    }
  }

  if (event === undefined) {
    try {
      /*const resp = await makeRequest({
        path: apiBackendRequest.GET_USER_PROFILE,
        requestGET: {':UUID': UUID},
        response: {
          Description: '',
          FollowersCount: 0,
          FollowingCount: 0,
          Eventname: '',
          XpLevel: 0,
          XpPoints: 0,
          AvatarUrl: '',
        },
      });*/

      /* Name: BasicEventProp<string>;
  Description: BasicEventProp<string>;
  StartDate: BasicEventProp<timestamp>;
  EndDate: BasicEventProp<timestamp>;
  Latitude: BasicEventProp<number>;
  Longitude: BasicEventProp<number>;
  Type: BasicEventProp<EventType>;
  Theme: BasicEventProp<EventThemes>;
  lastUpdateTimestamp: timestamp;
  FriendList: BasicEventProp<string[]>;
  UserLength: BasicEventProp<number>;
  EventBannerPicture: EventBannerPicture;
  ButtonAction: BasicEventProp<string>; */

      const resp = {
        response: {
          Name: 'test event',
          Description:
            'das Event "Tech House Germany" am 08.12.2023 im legendären Bootshaus Köln verspricht eine unvergessliche Nacht voller elektrisierender Beats und pulsierender Rhythmen. Jeder DJ bringt seinen einzigartigen Stil und Energie in das Line-up ein, was eine perfekte Mischung aus klassischem und modernem Tech House garantiert. \n\n' +
            'Das Bootshaus, bekannt für seine hervorragende Akustik und beeindruckende Lichtshow, bietet die perfekte Kulisse für eine Nacht voller Tanz und Musik. Erleben Sie eine Reise durch die Welt des Tech House, begleitet von den besten Künstlern der Szene. \n\n' +
            '\n\n\n' +
            'das Event "Tech House Germany" am 08.12.2023 im legendären Bootshaus Köln verspricht eine unvergessliche Nacht voller elektrisierender Beats und pulsierender Rhythmen. Jeder DJ bringt seinen einzigartigen Stil und Energie in das Line-up ein, was eine perfekte Mischung aus klassischem und modernem Tech House garantiert. \n\n' +
            'Das Bootshaus, bekannt für seine hervorragende Akustik und beeindruckende Lichtshow, bietet die perfekte Kulisse für eine Nacht voller Tanz und Musik. Erleben Sie eine Reise durch die Welt des Tech House, begleitet von den besten Künstlern der Szene. \n\n' +
            '\n\n\n' +
            'das Event "Tech House Germany" am 08.12.2023 im legendären Bootshaus Köln verspricht eine unvergessliche Nacht voller elektrisierender Beats und pulsierender Rhythmen. Jeder DJ bringt seinen einzigartigen Stil und Energie in das Line-up ein, was eine perfekte Mischung aus klassischem und modernem Tech House garantiert. \n\n' +
            'Das Bootshaus, bekannt für seine hervorragende Akustik und beeindruckende Lichtshow, bietet die perfekte Kulisse für eine Nacht voller Tanz und Musik. Erleben Sie eine Reise durch die Welt des Tech House, begleitet von den besten Künstlern der Szene. \n\n' +
            '\n\n\n' +
            'das Event "Tech House Germany" am 08.12.2023 im legendären Bootshaus Köln verspricht eine unvergessliche Nacht voller elektrisierender Beats und pulsierender Rhythmen. Jeder DJ bringt seinen einzigartigen Stil und Energie in das Line-up ein, was eine perfekte Mischung aus klassischem und modernem Tech House garantiert. \n\n' +
            'Das Bootshaus, bekannt für seine hervorragende Akustik und beeindruckende Lichtshow, bietet die perfekte Kulisse für eine Nacht voller Tanz und Musik. Erleben Sie eine Reise durch die Welt des Tech House, begleitet von den besten Künstlern der Szene. \n\n' +
            '\n\n\n' +
            'das Event "Tech House Germany" am 08.12.2023 im legendären Bootshaus Köln verspricht eine unvergessliche Nacht voller elektrisierender Beats und pulsierender Rhythmen. Jeder DJ bringt seinen einzigartigen Stil und Energie in das Line-up ein, was eine perfekte Mischung aus klassischem und modernem Tech House garantiert. \n\n' +
            'Das Bootshaus, bekannt für seine hervorragende Akustik und beeindruckende Lichtshow, bietet die perfekte Kulisse für eine Nacht voller Tanz und Musik. Erleben Sie eine Reise durch die Welt des Tech House, begleitet von den besten Künstlern der Szene. \n\n' +
            '\n\n\n' +
            'Blckbx: \n' +
            'NIGHTFUNK \n' +
            'FINIQ \n' +
            'DAVID HERRLICH \n' +
            'ELTERNHOUSE \n' +
            'LA RENZO',
          StartDate: 1702230005,
          EndDate: new Date().getTime() + 100000,
          Latitude: 48.7758,
          Longitude: 9.1829,
          Type: 0,
          Theme: 0,
          FriendList: [],
          UserLength: 5,
          pic: 'https://www.w3schools.com/w3css/img_lights.jpg',
          ButtonAction:
            '{"url":"https://www.w3schools.com/w3css/img_lights.jpg"}',
        },
      };

      event = {
        UUID,
        Description: createEventProp(
          SourceProp.cached,
          resp.response.Description,
        ),
        lastUpdateTimestamp: Math.floor(new Date().getTime() / 1000),
        EventBannerPicture: {
          lq: createEventProp(
            SourceProp.online,
            undefined,
            resp.response.pic + '?type=low',
          ),
          hq: createEventProp(SourceProp.online, undefined, resp.response.pic),
        },
        Name: createEventProp(SourceProp.cached, resp.response.Name),
        StartDate: createEventProp(SourceProp.cached, resp.response.StartDate),
        EndDate: createEventProp(SourceProp.cached, resp.response.EndDate),
        Latitude: createEventProp(SourceProp.cached, resp.response.Latitude),
        Longitude: createEventProp(SourceProp.cached, resp.response.Longitude),
        Type: createEventProp(
          SourceProp.cached,
          NumToEventType(resp.response.Type),
        ),
        Theme: createEventProp(SourceProp.cached, resp.response.Theme),
        FriendList: createEventProp(
          SourceProp.cached,
          resp.response.FriendList,
        ),
        UserLength: createEventProp(
          SourceProp.cached,
          resp.response.UserLength,
        ),
        ButtonAction: createEventProp(
          SourceProp.cached,
          resp.response.ButtonAction,
        ),
      };

      //BigDataManager.setEntry('events', event);
    } catch (error: any) {
      console.error(error.status);
    }
  }

  if (eventIsInCache === false && event !== undefined) {
    console.log('save in cache');
    store.dispatch(appNonSaveVarActions.setCachedEvent(event));
    cachedEventList.push(event.UUID);

    if (cachedEventList.length > maxCachedEvents) {
      let eveId = cachedEventList[0];
      cachedEventList.shift();
      console.log('eveId', eveId);

      store.dispatch(appNonSaveVarActions.removeCachedEvent(eveId));
    }
  }

  return event;
}

enum GetParam {
  CACHE = 0,
  SAVE,
}

let getEventList: {[key: AccountName]: GetParam} = {};

async function refreshEvents() {
  for (let UUID in getEventList) {
    const param = getEventList[UUID];
    delete getEventList[UUID];

    await getEvent(UUID);
  }
}

setInterval(refreshEvents, 500);

function addEventToGetQueue(UUID: EventID, param: GetParam) {
  if (getEventList[UUID] === undefined) {
    getEventList[UUID] = param;
  } else if (getEventList[UUID] < param) {
    getEventList[UUID] = param;
  }
}

function getEventSelector(UUID: EventID) {
  addEventToGetQueue(UUID, GetParam.CACHE);

  const myEvent = useSelector(
    (state: RootState) => state.nonSaveVariables.cachedEvents[UUID],
  );

  if (myEvent === undefined) {
    return initUndefinedEvent(UUID);
  }

  return myEvent;
}

function getEventSelectorPicture(UUID: EventID): EventBannerPicture {
  addEventToGetQueue(UUID, GetParam.CACHE);

  const myEvent = useSelector(
    (state: RootState) =>
      state.nonSaveVariables.cachedEvents[UUID]?.EventBannerPicture,
  );

  if (myEvent === undefined) {
    return {
      lq: createEventProp(SourceProp.online),
      hq: createEventProp(SourceProp.online),
    };
  }

  return myEvent;
}

function initUndefinedEvent(UUID: EventID): PAEvent {
  return {
    UUID,
    Name: createEventProp(SourceProp.online),
    Description: createEventProp(SourceProp.online),
    StartDate: createEventProp(SourceProp.online),
    EndDate: createEventProp(SourceProp.online),
    Latitude: createEventProp(SourceProp.online),
    Longitude: createEventProp(SourceProp.online),
    Type: createEventProp(SourceProp.online),
    Theme: createEventProp(SourceProp.online),
    lastUpdateTimestamp: 0,
    FriendList: createEventProp(SourceProp.online),
    UserLength: createEventProp(SourceProp.online),
    EventBannerPicture: {
      lq: createEventProp(SourceProp.online),
      hq: createEventProp(SourceProp.online),
    },
    ButtonAction: createEventProp(SourceProp.online),
  };
}

const EventManager = {
  getEvent,
  getEventSelector,
  getEventSelectorPicture,
  initUndefinedEvent,
};
export default EventManager;
