import { emptyState } from "../data";
import type { AppState } from "../types";

const storageKey = "craftlaunch-studio-extension-state-v1";
const desktopStorageKey = "craftlaunch-studio-desktop-state-v1";
const windowsStorageKey = "craftlaunch-studio-windows-state-v1";

function withFreshSaveTime(state: AppState): AppState {
  return {
    ...state,
    lastSavedAt: new Date().toISOString()
  };
}

function hasChromeStorage(): boolean {
  return typeof chrome !== "undefined" && Boolean(chrome.storage?.local);
}

function storageGet(keys: string[]): Promise<Record<string, AppState | undefined>> {
  return new Promise((resolve) => {
    chrome.storage.local.get(keys, (items) => {
      resolve(items as Record<string, AppState | undefined>);
    });
  });
}

function storageSet(state: AppState): Promise<void> {
  return new Promise((resolve, reject) => {
    chrome.storage.local.set({ [storageKey]: state }, () => {
      const error = chrome.runtime.lastError;
      if (error) {
        reject(new Error(error.message));
        return;
      }

      resolve();
    });
  });
}

function storageRemove(keys: string[]): Promise<void> {
  return new Promise((resolve) => {
    chrome.storage.local.remove(keys, () => resolve());
  });
}

export async function loadState(): Promise<AppState> {
  if (hasChromeStorage()) {
    const items = await storageGet([storageKey, desktopStorageKey, windowsStorageKey]);
    return items[storageKey] ?? items[desktopStorageKey] ?? items[windowsStorageKey] ?? emptyState;
  }

  const payload =
    window.localStorage.getItem(storageKey) ??
    window.localStorage.getItem(desktopStorageKey) ??
    window.localStorage.getItem(windowsStorageKey);

  if (payload) {
    return JSON.parse(payload) as AppState;
  }

  return emptyState;
}

export async function saveState(state: AppState): Promise<AppState> {
  const nextState = withFreshSaveTime(state);

  if (hasChromeStorage()) {
    await storageSet(nextState);
    return nextState;
  }

  window.localStorage.setItem(storageKey, JSON.stringify(nextState));
  return nextState;
}

export function resetState(): AppState {
  if (hasChromeStorage()) {
    void storageRemove([storageKey, desktopStorageKey, windowsStorageKey]);
  }

  window.localStorage.removeItem(storageKey);
  window.localStorage.removeItem(desktopStorageKey);
  window.localStorage.removeItem(windowsStorageKey);
  return emptyState;
}
