<script lang="ts">
  import { ExternalLink, Power } from "@lucide/svelte";
  import Api from "./api";

  const {
    name,
    mac,
    ip,
    url,
  }: {
    name: string;
    mac: string;
    ip: string | null;
    url: string | null;
  } = $props();

  let online: boolean | undefined = $state(undefined);
  const checkStatus: () => Promise<void> = async () => {
    if (!ip) return;
    const active = await Api.ping({ ip }).catch(() => false);
    online = active;
    // check every 30s if online, or every 5 seconds if offline
    setTimeout(checkStatus, (active ? 30 : 5) * 1000);
  };
  checkStatus();

  // try clean up the url but dont lose sleep
  function cleanUrl(url: string): string {
    const REGEX =
      /(?<=^(?:[a-z]*:\/\/)?)(?:[a-z]+(?:\.[a-z]+)+|localhost)(?::\d{1,5})?(?:\/+[^\/]+)*/gm;
    const res = url.match(REGEX);
    if (res && res[0]) return res[0];
    return url;
  }
</script>

<section>
  <button
    class="power"
    onclick={() =>
      Api.wake({ mac }).then((res) => alert(`Wake: ${mac} (${ip}) ${res}`))}
    aria-label="power"
  >
    <Power />
  </button>

  <div class="name">
    {name}
    {#if ip}<span class="status" data-status={online}></span>{/if}
    {#if url}<a href={url} class="url" title={url}>
        <span class="url-text">{cleanUrl(url)}</span>
        <ExternalLink />
      </a>{/if}
  </div>
  <div class="mac">{mac}</div>
  {#if ip}
    <div class="at">@</div>
    <div class="ip">{ip}</div>
  {/if}
</section>

<style>
  .status {
    display: inline-block;
    width: 0.5em;
    height: 0.5em;
    border-radius: 100%;
    transition: background 500ms ease-in-out;

    &[data-status="true"] {
      background: var(--theme-accent-success);
    }
    &[data-status="false"] {
      background: var(--theme-accent-fail);
    }
  }

  section {
    border-radius: 10px;
    background-color: var(--theme-background-server);

    box-sizing: border-box;
    padding: 0.5rem;
    display: grid;
    grid-template:
      "power name name name" 1lh
      "power mac at ip" 1lh
      / auto auto min-content auto;
    justify-content: start;
    align-items: center;
    gap: 0 5px;

    .name {
      grid-area: name;
      .url {
        text-decoration: none;
        .url-text {
          text-decoration: underline;
          &:hover {
            text-decoration-style: dotted;
          }

          &:active {
            text-decoration: none;
          }
        }
      }
    }

    .mac {
      grid-area: mac;
      color: var(--theme-text-secondary);
    }

    .at {
      grid-area: at;
      color: var(--theme-text-secondary);
    }

    .ip {
      grid-area: ip;
      color: var(--theme-text-secondary);
    }
  }

  @property --power-overlay {
    syntax: "<color>";
    inherits: false;
    initial-value: transparent;
  }

  .power {
    color: inherit;
    grid-area: power;
    aspect-ratio: 1;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;

    border-radius: 100%;
    border: 0px;
    background: linear-gradient(var(--power-overlay), var(--power-overlay)),
      linear-gradient(
        var(--theme-background-button),
        var(--theme-background-button)
      );

    transition:
      scale 10ms,
      --power-overlay 100ms;

    &:hover {
      --power-overlay: rgb(
        from var(--theme-highlight) r g b / var(--theme-highlight-opacity)
      );
    }

    &:active {
      scale: 0.9;
    }
  }

  :global {
    .lucide-external-link {
      width: 1em;
      height: 1em;
    }
  }
</style>
