import { get, writable } from 'svelte/store';
import { appsById } from '$lib/data/apps';

export type WindowState = {
  id: string;
  x: number;
  y: number;
  width: number;
  height: number;
  z: number;
  minimised: boolean;
  maximised: boolean;
};

let zCounter = 20;

function defaultPosition(index: number) {
  return {
    x: 120 + (index % 5) * 34,
    y: 86 + (index % 5) * 30
  };
}

function createWindowStore() {
  const { subscribe, update } = writable<WindowState[]>([]);

  function focusWindow(id: string) {
    update((windows) =>
      windows.map((item) => (item.id === id ? { ...item, z: ++zCounter, minimised: false } : item))
    );
  }

  return {
    subscribe,
    openWindow(id: string) {
      const app = appsById.get(id);
      if (!app) return;

      const existing = get({ subscribe }).find((item) => item.id === id);
      if (existing) {
        focusWindow(id);
        return;
      }

      update((windows) => {
        const position = defaultPosition(windows.length);
        return [
          ...windows,
          {
            id,
            x: position.x,
            y: position.y,
            width: app.defaultSize.width,
            height: app.defaultSize.height,
            z: ++zCounter,
            minimised: false,
            maximised: false
          }
        ];
      });
    },
    closeWindow(id: string) {
      update((windows) => windows.filter((item) => item.id !== id));
    },
    minimiseWindow(id: string) {
      update((windows) =>
        windows.map((item) => (item.id === id ? { ...item, minimised: true } : item))
      );
    },
    restoreWindow(id: string) {
      focusWindow(id);
    },
    focusWindow,
    toggleMaximise(id: string) {
      update((windows) =>
        windows.map((item) =>
          item.id === id ? { ...item, maximised: !item.maximised, minimised: false, z: ++zCounter } : item
        )
      );
    },
    moveWindow(id: string, x: number, y: number) {
      update((windows) => windows.map((item) => (item.id === id ? { ...item, x, y } : item)));
    },
    resizeWindow(id: string, width: number, height: number) {
      update((windows) =>
        windows.map((item) => (item.id === id ? { ...item, width, height } : item))
      );
    }
  };
}

export const windowStore = createWindowStore();
