<script lang="ts">
  import { goto } from "$app/navigation";
  import {
    enqueueBackfill,
    getCurrentPresence,
    getPeer,
  } from "$lib/api/endpoints";
  import type { PeerView, PresenceSample } from "$lib/api/types";
  import Avatar from "$lib/components/ui/Avatar.svelte";
  import Button from "$lib/components/ui/Button.svelte";
  import ContextMenu from "$lib/components/ui/ContextMenu.svelte";
  import ContextMenuItem from "$lib/components/ui/ContextMenuItem.svelte";
  import Icon from "$lib/components/ui/Icon.svelte";
  import { peerName } from "$lib/format/peer";
  import { formatPresence } from "$lib/format/presence";
  import { accounts } from "$lib/stores/accounts.svelte";
  import { chats } from "$lib/stores/chats.svelte";
  import { discover } from "$lib/stores/discover.svelte";
  import { events } from "$lib/stores/events.svelte";
  import { toasts } from "$lib/stores/toasts.svelte";
  import { ui } from "$lib/stores/ui.svelte";

  interface Props {
    chatId: number;
  }

  let { chatId }: Props = $props();

  const isDm = $derived(chatId > 0);
  const chat = $derived(chats.byId(chatId));
  const discovered = $derived(discover.get(chatId));
  let peer = $state<PeerView | null>(null);
  let presence = $state<PresenceSample | null>(null);
  let backfilling = $state(false);

  async function backfill() {
    if (backfilling) {
      return;
    }
    backfilling = true;
    try {
      await enqueueBackfill(chatId, true);
      toasts.success("Бэкфилл запущен");
    } catch {
      toasts.error("Не удалось запустить бэкфилл");
    } finally {
      backfilling = false;
    }
  }

  $effect(() => {
    if (accounts.selectedId === null) {
      return;
    }
    discover.ensure(chatId).catch(() => undefined);
  });

  $effect(() => {
    if (accounts.selectedId === null || !isDm) {
      peer = null;
      return;
    }
    let active = true;
    peer = null;
    getPeer(chatId)
      .then((result) => {
        if (active) {
          peer = result;
        }
      })
      .catch(() => {
        if (active) {
          peer = null;
        }
      });
    return () => {
      active = false;
    };
  });

  $effect(() => {
    if (accounts.selectedId === null || !isDm) {
      presence = null;
      return;
    }
    let active = true;
    presence = null;
    getCurrentPresence(chatId)
      .then((result) => {
        if (active) {
          presence = result;
        }
      })
      .catch(() => {
        if (active) {
          presence = null;
        }
      });
    const unsub = events.subscribe((event) => {
      if (
        event.type === "presence" &&
        event.peer_id === chatId &&
        event.sample
      ) {
        presence = event.sample;
      }
    });
    return () => {
      active = false;
      unsub();
    };
  });

  const fallbackTitle = $derived(
    chat?.title ??
      discovered?.title ??
      (isDm ? "Удалённый аккаунт" : `Chat ${chatId}`)
  );
  const title = $derived(isDm && peer ? peerName(peer) : fallbackTitle);
  const subtitle = $derived.by(() => {
    if (isDm) {
      if (presence) {
        return formatPresence(presence);
      }
      if (peer?.username) {
        return `@${peer.username}`;
      }
      return peer?.phone ?? `ID ${chatId}`;
    }
    const count = chat?.message_count ?? discovered?.message_count ?? 0;
    if (count > 0) {
      return `${count} messages`;
    }
    return discovered?.kind === "channel" ? "channel" : "group";
  });
  const avatarKind = $derived(isDm ? "peer" : "chat");
  const hasAvatar = $derived(
    chat?.has_avatar ?? Boolean(peer?.has_avatar || discovered?.has_avatar)
  );
</script>

<header class="chat-header">
  <div class="back">
    <Button
      variant="translucent"
      round
      smaller
      onclick={() => goto("/app")}
      aria-label="Назад"
    >
      <Icon name="arrow-left" />
    </Button>
  </div>
  <ContextMenu>
    {#snippet children({ props })}
      <button
        {...props}
        type="button"
        class="peek"
        onclick={() => ui.openPanel("profile")}
        aria-label="Открыть профиль"
      >
        <Avatar
          name={title}
          colorKey={chatId}
          size={2.5}
          avatar={{ kind: avatarKind, id: chatId }}
          {hasAvatar}
          deleted={peer?.is_deleted_account ?? false}
        />
        <div class="info">
          <h2 class="title">{title}</h2>
          <span
            class="subtitle"
            class:online={isDm && presence?.status === "online"}
          >
            {subtitle}
          </span>
        </div>
      </button>
    {/snippet}
    {#snippet menu()}
      <ContextMenuItem icon="info" onselect={() => ui.openPanel("profile")}
        >Открыть профиль</ContextMenuItem
      >
      <ContextMenuItem
        icon="play-story"
        onselect={() => ui.openPanel("stories")}
        >Сторис</ContextMenuItem
      >
    {/snippet}
  </ContextMenu>
  <div class="actions">
    <Button
      variant="translucent"
      round
      smaller
      onclick={() => ui.openPanel("search")}
      aria-label="Поиск в чате"
    >
      <Icon name="search" />
    </Button>
    <Button
      variant="translucent"
      round
      smaller
      onclick={() => ui.openPanel("presence")}
      aria-label="Аналитика"
    >
      <Icon name="stats" />
    </Button>
    <Button
      variant="translucent"
      round
      smaller
      loading={backfilling}
      onclick={backfill}
      aria-label="Скачать историю"
    >
      <Icon name="cloud-download" />
    </Button>
  </div>
</header>

<style lang="scss">
  .chat-header {
    display: flex;
    align-items: center;
    gap: 0.625rem;

    height: var(--header-height);
    padding: 0 1rem;
    border-bottom: 1px solid var(--color-borders);

    background-color: var(--color-background);
  }

  .back {
    display: none;
    margin-left: -0.25rem;

    @media (max-width: 600px) {
      display: block;
    }
  }

  .peek {
    display: flex;
    flex: 1;
    align-items: center;
    gap: 0.625rem;

    min-width: 0;
    padding: 0;
    border: 0;

    text-align: left;
    cursor: pointer;
    background: transparent;
  }

  .info {
    overflow: hidden;
    min-width: 0;
  }

  .actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: auto;
  }

  .title {
    overflow: hidden;
    margin: 0;
    font-size: 1rem;
    font-weight: var(--font-weight-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .subtitle {
    font-size: 0.8125rem;
    color: var(--color-text-secondary);

    &.online {
      color: var(--color-primary);
    }
  }
</style>
