import { useEffect, useState } from 'react';
import {
  clearPreviewRuntimeTokenFromUrl,
  isPreviewRuntime,
  readPreviewRuntimeTokenFromUrl,
} from './previewRuntime';

export const TOKEN_ACCESS_STORAGE_KEY = 'work-app.token-access.registered-token';
export const TOKEN_ACCESS_SYNC_EVENT = 'work-app:token-access-changed';
export const ALLOWED_REGISTRATION_TOKEN =
  import.meta.env.VITE_ALLOWED_REGISTRATION_TOKEN?.trim() || 'usr_7f3a9c2d8e1b4a6f';
const PREVIEW_RUNTIME_TOKEN_STORAGE_KEY = 'work-app.preview-runtime.registered-token';
const PREVIEW_APP_ORIGIN = 'https://preview.sm-home.cloud';

let previewRuntimeTokenMemory = '';

function getRegisteredTokenStorage() {
  if (typeof window === 'undefined') {
    return null;
  }

  return window.sessionStorage;
}

function normalizeToken(value: string | null | undefined) {
  return value?.trim() ?? '';
}

function readStorageToken(storage: Storage | null, key: string) {
  try {
    return normalizeToken(storage?.getItem(key));
  } catch {
    return '';
  }
}

function writeStorageToken(storage: Storage | null, key: string, token: string) {
  try {
    if (token) {
      storage?.setItem(key, token);
    } else {
      storage?.removeItem(key);
    }
  } catch {
    // Ignore storage access errors in restricted preview runtimes.
  }
}

function bootstrapRegisteredAccessToken() {
  if (typeof window === 'undefined') {
    return;
  }

  const tokenFromUrl = readPreviewRuntimeTokenFromUrl();
  const storedToken = readStorageToken(getRegisteredTokenStorage(), TOKEN_ACCESS_STORAGE_KEY);

  if (isPreviewRuntime()) {
    if (!tokenFromUrl) {
      const storedPreviewToken = readStorageToken(window.sessionStorage, PREVIEW_RUNTIME_TOKEN_STORAGE_KEY);

      if (storedPreviewToken) {
        previewRuntimeTokenMemory = storedPreviewToken;
        return;
      }

      if (window.location.origin === PREVIEW_APP_ORIGIN) {
        previewRuntimeTokenMemory = ALLOWED_REGISTRATION_TOKEN;
        writeStorageToken(window.sessionStorage, PREVIEW_RUNTIME_TOKEN_STORAGE_KEY, ALLOWED_REGISTRATION_TOKEN);
      }
      return;
    }

    previewRuntimeTokenMemory = tokenFromUrl;
    writeStorageToken(window.sessionStorage, PREVIEW_RUNTIME_TOKEN_STORAGE_KEY, tokenFromUrl);
    clearPreviewRuntimeTokenFromUrl();
    return;
  }

  if (!tokenFromUrl) {
    if (window.location.origin === PREVIEW_APP_ORIGIN && storedToken !== ALLOWED_REGISTRATION_TOKEN) {
      writeStorageToken(getRegisteredTokenStorage(), TOKEN_ACCESS_STORAGE_KEY, ALLOWED_REGISTRATION_TOKEN);
    }
    return;
  }

  writeStorageToken(getRegisteredTokenStorage(), TOKEN_ACCESS_STORAGE_KEY, tokenFromUrl);
  clearPreviewRuntimeTokenFromUrl();
}

bootstrapRegisteredAccessToken();

export function isAllowedRegistrationToken(token: string | null | undefined) {
  return normalizeToken(token) === ALLOWED_REGISTRATION_TOKEN;
}

export function getRegisteredAccessToken() {
  if (typeof window === 'undefined') {
    return '';
  }

  if (isPreviewRuntime()) {
    const previewToken =
      readStorageToken(window.sessionStorage, PREVIEW_RUNTIME_TOKEN_STORAGE_KEY) || previewRuntimeTokenMemory;

    if (!previewToken && window.location.origin === PREVIEW_APP_ORIGIN) {
      previewRuntimeTokenMemory = ALLOWED_REGISTRATION_TOKEN;
      writeStorageToken(window.sessionStorage, PREVIEW_RUNTIME_TOKEN_STORAGE_KEY, ALLOWED_REGISTRATION_TOKEN);
      return ALLOWED_REGISTRATION_TOKEN;
    }

    return previewToken;
  }

  const storedToken = readStorageToken(getRegisteredTokenStorage(), TOKEN_ACCESS_STORAGE_KEY);

  if (window.location.origin === PREVIEW_APP_ORIGIN && storedToken !== ALLOWED_REGISTRATION_TOKEN) {
    writeStorageToken(getRegisteredTokenStorage(), TOKEN_ACCESS_STORAGE_KEY, ALLOWED_REGISTRATION_TOKEN);
    return ALLOWED_REGISTRATION_TOKEN;
  }

  return storedToken;
}

export function hasRegisteredAccessTokenAccess() {
  return isAllowedRegistrationToken(getRegisteredAccessToken());
}

export function setRegisteredAccessToken(token: string | null | undefined) {
  if (typeof window === 'undefined') {
    return;
  }

  const normalizedToken = normalizeToken(token);

  if (isPreviewRuntime()) {
    previewRuntimeTokenMemory = normalizedToken;
    writeStorageToken(window.sessionStorage, PREVIEW_RUNTIME_TOKEN_STORAGE_KEY, normalizedToken);
  } else {
    writeStorageToken(getRegisteredTokenStorage(), TOKEN_ACCESS_STORAGE_KEY, normalizedToken);
  }

  window.dispatchEvent(new CustomEvent(TOKEN_ACCESS_SYNC_EVENT));
}

export function useTokenAccess() {
  const [registeredToken, setRegisteredToken] = useState(() => getRegisteredAccessToken());

  useEffect(() => {
    if (typeof window === 'undefined') {
      return undefined;
    }

    const syncRegisteredToken = () => {
      setRegisteredToken(getRegisteredAccessToken());
    };

    window.addEventListener('storage', syncRegisteredToken);
    window.addEventListener(TOKEN_ACCESS_SYNC_EVENT, syncRegisteredToken);

    return () => {
      window.removeEventListener('storage', syncRegisteredToken);
      window.removeEventListener(TOKEN_ACCESS_SYNC_EVENT, syncRegisteredToken);
    };
  }, []);

  return {
    registeredToken,
    hasAccess: isAllowedRegistrationToken(registeredToken),
  };
}
