<script lang="ts">
  import { MatrixAvatar } from "$lib/components/ui";
  import { getReadReceiptsForEvent } from "$lib/matrix";
  import type { Message } from "$lib/matrix/types";
  import { formatTime } from "./utils";
  import {
    MessageContent,
    MessageMedia,
    MessageReactions,
    MessageActions,
    MessageReadReceipts,
  } from "./parts";

  interface ReplyPreview {
    senderName: string;
    content: string;
    senderAvatar: string | null;
    hasAttachment: boolean;
  }

  interface Props {
    message: Message;
    isGrouped?: boolean;
    isOwnMessage?: boolean;
    isPinned?: boolean;
    currentUserId?: string;
    replyPreview?: ReplyPreview | null;
    onReact?: (emoji: string) => void;
    onToggleReaction?: (emoji: string, reactionEventId: string | null) => void;
    onEdit?: () => void;
    onDelete?: () => void;
    onReply?: () => void;
    onPin?: () => void;
    onScrollToMessage?: (eventId: string) => void;
  }

  let {
    message,
    isGrouped = false,
    isOwnMessage = false,
    isPinned = false,
    currentUserId = "",
    replyPreview = null,
    onReact,
    onToggleReaction,
    onEdit,
    onDelete,
    onReply,
    onPin,
    onScrollToMessage,
  }: Props = $props();

  let showActions = $state(false);

  // Get read receipts for own messages
  const readReceipts = $derived(
    isOwnMessage
      ? getReadReceiptsForEvent(message.roomId, message.eventId)
      : [],
  );

  // Check if message has media
  const hasMedia = $derived(
    ["image", "video", "audio", "file"].includes(message.type) && message.media,
  );
</script>

<div
  class="group relative px-5 py-0.5 hover:bg-light/[0.02] transition-colors {message.isPending
    ? 'opacity-40'
    : ''}"
  onmouseenter={() => (showActions = true)}
  onmouseleave={() => (showActions = false)}
  role="article"
  id="message-{message.eventId}"
>
  <!-- Reply preview -->
  {#if replyPreview && message.replyTo}
    <button
      class="flex items-center gap-1.5 ml-12 mt-1 mb-0.5 text-[11px] hover:opacity-80 transition-opacity cursor-pointer"
      onclick={() => onScrollToMessage?.(message.replyTo!)}
    >
      <div class="w-0.5 h-3 bg-primary/40 rounded-full shrink-0"></div>
      <MatrixAvatar
        mxcUrl={replyPreview.senderAvatar}
        name={replyPreview.senderName}
        size="xs"
      />
      <span class="text-light/50 font-body">{replyPreview.senderName}</span>
      <span class="text-light/30 truncate max-w-xs">
        {#if replyPreview.hasAttachment}
          <span
            class="material-symbols-rounded align-middle mr-0.5"
            style="font-size: 12px;">image</span
          >
        {/if}
        {replyPreview.content}
      </span>
    </button>
  {/if}

  {#if isGrouped}
    <!-- Grouped message -->
    <div class="flex gap-3">
      <div class="w-9 shrink-0 flex items-center justify-center">
        <span
          class="text-[10px] text-light/20 opacity-0 group-hover:opacity-100 transition-opacity select-none"
        >
          {formatTime(message.timestamp)}
        </span>
      </div>
      <div class="flex-1 min-w-0">
        {#if hasMedia && message.media}
          <MessageMedia
            type={message.type as "image" | "video" | "audio" | "file"}
            media={message.media}
            altText={message.content}
          />
        {:else}
          <MessageContent
            content={message.content}
            isEdited={message.isEdited}
            isRedacted={message.isRedacted}
          />
        {/if}
      </div>
    </div>
  {:else}
    <!-- Full message with avatar -->
    <div class="flex gap-3 mt-3 first:mt-0">
      <div class="w-9 shrink-0 pt-0.5">
        <MatrixAvatar
          mxcUrl={message.senderAvatar}
          name={message.senderName}
          size="sm"
        />
      </div>
      <div class="flex-1 min-w-0">
        <div class="flex items-baseline gap-2 mb-px">
          <span
            class="text-[13px] font-heading text-white hover:underline cursor-pointer"
          >
            {message.senderName}
          </span>
          <span class="text-[10px] text-light/25 select-none">
            {formatTime(message.timestamp)}
          </span>
        </div>
        {#if hasMedia && message.media}
          <MessageMedia
            type={message.type as "image" | "video" | "audio" | "file"}
            media={message.media}
            altText={message.content}
          />
        {:else}
          <MessageContent
            content={message.content}
            isEdited={message.isEdited}
            isRedacted={message.isRedacted}
          />
        {/if}
      </div>
    </div>
  {/if}

  <!-- Reactions -->
  <MessageReactions
    reactions={message.reactions}
    {currentUserId}
    isRedacted={message.isRedacted}
    {onReact}
    {onToggleReaction}
  />

  <!-- Read receipts (own messages only) -->
  {#if isOwnMessage}
    <MessageReadReceipts receipts={readReceipts} />
  {/if}

  <!-- Action buttons (show on hover) -->
  {#if showActions && !message.isRedacted}
    <MessageActions
      {isOwnMessage}
      {isPinned}
      messageContent={message.content}
      messageEventId={message.eventId}
      {onReact}
      {onReply}
      {onEdit}
      {onDelete}
      {onPin}
    />
  {/if}
</div>
