import React, { useContext, useState } from "react";
import { executeEvent } from "../../utils/events";
import { getBaseApiReact, MyContext } from "../../App";
import { createEndpoint } from "../../background";
import { useRecoilState, useSetRecoilState } from "recoil";
import {
  settingsLocalLastUpdatedAtom,
  sortablePinnedAppsAtom,
} from "../../atoms/global";
import { saveToLocalStorage } from "./AppsNavBarDesktop";
import { base64ToBlobUrl } from "../../utils/fileReading";
import { base64ToUint8Array } from "../../qdn/encryption/group-encryption";
import { uint8ArrayToObject } from "../../backgroundFunctions/encryption";

export const useHandlePrivateApps = () => {
  const [status, setStatus] = useState("");
  const {
    openSnackGlobal,
    setOpenSnackGlobal,
    infoSnackCustom,
    setInfoSnackCustom,
  } = useContext(MyContext);
  const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(
    sortablePinnedAppsAtom
  );
  const setSettingsLocalLastUpdated = useSetRecoilState(
    settingsLocalLastUpdatedAtom
  );
  const openApp = async (
    privateAppProperties,
    addToPinnedApps,
    setLoadingStatePrivateApp
  ) => {
    try {
      
    
      if(setLoadingStatePrivateApp){
        setLoadingStatePrivateApp(`Downloading and decrypting private app.`);

      }
      setOpenSnackGlobal(true);

      setInfoSnackCustom({
        type: "info",
        message: "Fetching app data",
        duration: null
      });
      const urlData = `${getBaseApiReact()}/arbitrary/${
        privateAppProperties?.service
      }/${privateAppProperties?.name}/${
        privateAppProperties?.identifier
      }?encoding=base64`;
      let data;
      try {
        const responseData = await fetch(urlData, {
          method: "GET",
          headers: {
            "Content-Type": "application/json",
          },
        });

        if(!responseData?.ok){
          if(setLoadingStatePrivateApp){
            setLoadingStatePrivateApp("Error! Unable to download private app.");
          }
        
        throw new Error("Unable to fetch app");
        } 

        data = await responseData.text();
        if (data?.error) {
          if(setLoadingStatePrivateApp){

          setLoadingStatePrivateApp("Error! Unable to download private app.");
          }
          throw new Error("Unable to fetch app");
        }
      } catch (error) {
        if(setLoadingStatePrivateApp){

        setLoadingStatePrivateApp("Error! Unable to download private app.");
        }
        throw error;
      }

      let decryptedData;
      // eslint-disable-next-line no-useless-catch
      try {
        decryptedData = await window.sendMessage(
          "DECRYPT_QORTAL_GROUP_DATA",

          {
            base64: data,
            groupId: privateAppProperties?.groupId,
          }
        );
        if (decryptedData?.error) {
          if(setLoadingStatePrivateApp){

          setLoadingStatePrivateApp("Error! Unable to decrypt private app.");
          }
          throw new Error(decryptedData?.error);
        }
      } catch (error) {
        if(setLoadingStatePrivateApp){

        setLoadingStatePrivateApp("Error! Unable to decrypt private app.");
        }
        throw error;
      }

      try {
        const convertToUint = base64ToUint8Array(decryptedData);
        const UintToObject = uint8ArrayToObject(convertToUint);
  
        if (decryptedData) {
          setInfoSnackCustom({
            type: "info",
            message: "Building app",
          });
          const endpoint = await createEndpoint(
            `/arbitrary/APP/${privateAppProperties?.name}/zip?preview=true`
          );
          const response = await fetch(endpoint, {
            method: "POST",
            headers: {
              "Content-Type": "text/plain",
            },
            body: UintToObject?.app,
          });
          const previewPath = await response.text();
          const refreshfunc = async (tabId, privateAppProperties) => {
            const checkIfPreviewLinkStillWorksUrl = await createEndpoint(
              `/render/hash/HmtnZpcRPwisMfprUXuBp27N2xtv5cDiQjqGZo8tbZS?secret=E39WTiG4qBq3MFcMPeRZabtQuzyfHg9ZuR5SgY7nW1YH`
            );
            const res = await fetch(checkIfPreviewLinkStillWorksUrl);
            if (res.ok) {
              executeEvent("refreshApp", {
                tabId: tabId,
              });
            } else {
              const endpoint = await createEndpoint(
                `/arbitrary/APP/${privateAppProperties?.name}/zip?preview=true`
              );
              const response = await fetch(endpoint, {
                method: "POST",
                headers: {
                  "Content-Type": "text/plain",
                },
                body: UintToObject?.app,
              });
              const previewPath = await response.text();
              executeEvent("updateAppUrl", {
                tabId: tabId,
                url: await createEndpoint(previewPath),
              });
  
              setTimeout(() => {
                executeEvent("refreshApp", {
                  tabId: tabId,
                });
              }, 300);
            }
          };
  
          const appName = UintToObject?.name;
          const logo = UintToObject?.logo
            ? `data:image/png;base64,${UintToObject?.logo}`
            : null;
  
          const dataBody = {
            url: await createEndpoint(previewPath),
            isPreview: true,
            isPrivate: true,
            privateAppProperties: { ...privateAppProperties, logo, appName },
            filePath: "",
            refreshFunc: (tabId) => {
              refreshfunc(tabId, privateAppProperties);
            },
          };
          executeEvent("addTab", {
            data: dataBody,
          });
          setInfoSnackCustom({
            type: "success",
            message: "Opened",
          });
          if(setLoadingStatePrivateApp){

          setLoadingStatePrivateApp(``);
          }
          if (addToPinnedApps) {
            setSortablePinnedApps((prev) => {
              const updatedApps = [
                ...prev,
                {
                  isPrivate: true,
                  isPreview: true,
                  privateAppProperties: {
                    ...privateAppProperties,
                    logo,
                    appName,
                  },
                },
              ];
  
              saveToLocalStorage(
                "ext_saved_settings",
                "sortablePinnedApps",
                updatedApps
              );
              return updatedApps;
            });
            setSettingsLocalLastUpdated(Date.now());
          }
        }
      } catch (error) {
        if(setLoadingStatePrivateApp){

        setLoadingStatePrivateApp(`Error! ${error?.message || 'Unable to build private app.'}`);
        }
        throw error
      }
    }
      catch (error) {
        setInfoSnackCustom({
          type: "error",
          message: error?.message || "Unable to fetch app",
        });
      }
 
  };
  return {
    openApp,
    status,
  };
};
