<script lang="ts">
  import { onMount } from 'svelte';
  import { browser } from '$app/environment';
  import { helpText, findCommand } from '$lib/data/commands';
  import { visibleApps } from '$lib/data/apps';
  import AppIcon from '$lib/components/os/AppIcon.svelte';
  import BootScreen from '$lib/components/os/BootScreen.svelte';
  import CommandPalette from '$lib/components/os/CommandPalette.svelte';
  import StatusWidget from '$lib/components/os/StatusWidget.svelte';
  import Taskbar from '$lib/components/os/Taskbar.svelte';
  import Window from '$lib/components/os/Window.svelte';
  import { preferences } from '$lib/stores/preferencesStore';
  import { windowStore } from '$lib/stores/windowStore';

  let bootVisible = true;
  let paletteOpen = false;
  let currentTime = '';

  const desktopApps = visibleApps;

  function updateClock() {
    currentTime = new Intl.DateTimeFormat('en-GB', {
      weekday: 'short',
      hour: '2-digit',
      minute: '2-digit'
    }).format(new Date());
  }

  function openApp(id: string) {
    windowStore.openWindow(id);
  }

  function restoreApp(id: string) {
    windowStore.restoreWindow(id);
  }

  function replayBoot() {
    preferences.resetBoot();
    bootVisible = true;
  }

  function finishBoot() {
    bootVisible = false;
    windowStore.openWindow('readme');
  }

  function runCommand(commandInput: string, source: 'terminal' | 'palette' = 'palette') {
    const command = findCommand(commandInput);

    if (!command) {
      return `Command not found: ${commandInput}\nType help for available commands.`;
    }

    if (command.name === 'help') return helpText;

    if (command.appId) {
      openApp(command.appId);
      return `[open] ${command.appId}`;
    }

    if (command.name === 'simple') {
      if (browser) window.location.href = '/simple';
      return 'Opening Simple Mode.';
    }

    if (command.name === 'boot') {
      replayBoot();
      return 'Replaying boot sequence.';
    }

    if (command.name === 'verify') {
      openApp('evidence');
      return 'Verification route opened. Trust comes from what can be checked.';
    }

    if (command.name === 'responsibility') {
      openApp('everwished');
      return 'Responsibility by Design: care about consequences before the invoice has cooled.';
    }

    if (command.name === 'no-beige') {
      return [
        'NO BEIGE DECLARATION',
        '',
        'This system rejects:',
        '- unnecessary jargon',
        '- dead-eyed compliance theatre',
        '- vendor fog',
        '- fake transformation',
        '- fragile spreadsheets with delusions of platformhood',
        '- "just circle back" as a substitute for action',
        '',
        'Proceed with useful work.'
      ].join('\n');
    }

    if (command.name === 'gyp') {
      return 'GypBops subsystem detected.\nStatus: hypnotic\nRisk level: squeaky\nBusiness justification: none, which is sometimes the purest kind.';
    }

    if (command.name === 'duck') {
      return 'Duck mode enabled.\nNo strategic value detected.\nMorale impact: suspiciously high.';
    }

    if (source === 'palette') return `${command.name} acknowledged.`;
    return undefined;
  }

  function keydown(event: KeyboardEvent) {
    const target = event.target as HTMLElement;
    const isTyping = ['INPUT', 'TEXTAREA'].includes(target.tagName);

    if ((event.ctrlKey && event.key.toLowerCase() === 'k') || (!isTyping && event.key === '/')) {
      event.preventDefault();
      paletteOpen = true;
    }

    if (event.key === 'Escape') {
      paletteOpen = false;
    }
  }

  $: if (browser) {
    document.documentElement.dataset.theme = $preferences.theme;
  }

  onMount(() => {
    preferences.initialise();
    bootVisible = !$preferences.hasSeenBoot && localStorage.getItem('hasSeenBoot') !== 'true';
    updateClock();
    const clockTimer = window.setInterval(updateClock, 30000);
    window.addEventListener('keydown', keydown);

    if (!bootVisible) {
      window.setTimeout(() => openApp('readme'), 50);
    }

    return () => {
      window.clearInterval(clockTimer);
      window.removeEventListener('keydown', keydown);
    };
  });
</script>

<svelte:head>
  <title>Ian Barrs - IT, Security, Operations, Training and Useful Systems</title>
  <meta
    name="description"
    content="Ian Barrs is an IT, security, compliance, operations and training specialist, founder of everwished ltd, and builder of practical systems for small organisations, charities, community projects and people doing difficult work."
  />
  <meta property="og:title" content="Ian Barrs - useful systems, useful mischief" />
  <meta
    property="og:description"
    content="Useful systems, useful mischief. The interactive public CV of Ian Barrs: IT, security, compliance, operations, training, everwished, charIT, River & Bean, Happy Coo and more."
  />
</svelte:head>

<main class="desktop-shell" aria-label="ianOS desktop">
  {#if bootVisible}
    <BootScreen on:done={finishBoot} />
  {/if}

  <div class="desktop-topbar" aria-label="System status">
    <span>ianOS</span>
    <span>{currentTime}</span>
    <button type="button" on:click={() => (paletteOpen = true)}>Ctrl+K</button>
  </div>

  <section class="desktop" aria-label="Desktop apps">
    <div class="desktop-icons">
      {#each desktopApps as app}
        <AppIcon {app} openApp={openApp} />
      {/each}
    </div>

    <StatusWidget />

    {#each $windowStore as item (item.id)}
      <Window {item} runCommand={runCommand} replayBoot={replayBoot} />
    {/each}
  </section>

  <Taskbar windows={$windowStore} openApp={openApp} restoreApp={restoreApp} openPalette={() => (paletteOpen = true)} />
  <CommandPalette bind:open={paletteOpen} runCommand={runCommand} />
</main>
