/**
 * StreamMessage — single message card in the stream
 */

import { Component, Show, createMemo } from "solid-js";
import type { StreamMessage as StreamMessageType } from "./registry";
import { getMessageType } from "./registry";
import {
  revertLatest,
  canRevert,
  useJournalStream,
} from "../stores/journalStream";

export const StreamMessageCard: Component<{
  message: StreamMessageType;
}> = (props) => {
  const stream = useJournalStream();
  const def = createMemo(() => getMessageType(props.message.type));
  const rendered = createMemo(() =>
    def()?.render?.(props.message.payload, props.message as any),
  );

  const time = createMemo(() => {
    const d = new Date(props.message.timestamp);
    return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
  });

  const isMine = () => props.message.sender === stream.myName;
  const latestSeq = () => stream.senderSeq[stream.myName] ?? 0;
  const canRevertThis = () =>
    isMine() && props.message.seq === latestSeq() && !props.message.reverted;

  const senderClass = () =>
    props.message.sender === "gm"
      ? "text-purple-600 font-semibold"
      : "text-blue-600 font-semibold";

  return (
    <Show
      when={!props.message.reverted}
      fallback={<RevealedCard msg={props.message} />}
    >
      <div class="bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden">
        {/* Header */}
        <div class="flex items-center gap-1.5 px-2.5 py-1 bg-gray-50 border-b border-gray-100">
          <span class={`text-xs ${senderClass()}`}>{props.message.sender}</span>
          <span class="text-xs text-gray-400">{time()}</span>
          <Show when={canRevertThis()}>
            <button
              onClick={() => revertLatest()}
              class="text-xs text-gray-300 hover:text-red-500 ml-auto px-0.5 leading-none"
              title="Revert this message"
            >
              ×
            </button>
          </Show>
          <span
            class="text-xs text-gray-300 bg-gray-100 px-1 rounded"
            classList={{ "ml-auto": !canRevertThis() }}
          >
            {props.message.type}
          </span>
        </div>

        {/* Body */}
        <div class="px-2.5 py-1.5 text-sm text-gray-800">
          <Show
            when={rendered()}
            fallback={<JsonBody payload={props.message.payload} />}
          >
            {rendered()}
          </Show>
        </div>
      </div>
    </Show>
  );
};

/** Fallback: render payload as formatted JSON */
const JsonBody: Component<{ payload: unknown }> = (props) => {
  const text = () => JSON.stringify(props.payload, null, 2);
  return (
    <pre class="text-xs text-gray-600 whitespace-pre-wrap font-mono">
      {text()}
    </pre>
  );
};

/** Reverted card: struck-through, grey */
const RevealedCard: Component<{ msg: StreamMessageType }> = (props) => {
  return (
    <div class="bg-gray-100 rounded-lg border border-gray-200 opacity-50 px-2.5 py-1.5">
      <span class="text-xs text-gray-400 line-through">
        {props.msg.sender} — reverted
      </span>
    </div>
  );
};
