import { useCallback, useEffect, useState } from "react";
import { LoadTimeline } from "../../wailsjs/go/main/MatrixService";
import { EventsOn } from "../../wailsjs/runtime/runtime";
import type { MatrixEvent, SyncEventView } from "../types";

/**
 * useMatrixTimeline loads the last `limit` events of a room (newest at the
 * bottom) and appends live events from the sync stream. Re-fetches whenever
 * roomID changes.
 */
export function useMatrixTimeline(roomID: string | null, limit = 50) {
  const [events, setEvents] = useState<MatrixEvent[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const refresh = useCallback(async () => {
    if (!roomID) {
      setEvents([]);
      return;
    }
    setLoading(true);
    try {
      const list = await LoadTimeline(roomID, limit);
      // Mautrix Messages with DirectionBackward returns newest-first; flip to
      // oldest-first so React renders top-to-bottom chronologically.
      const ordered = [...(list || [])].reverse();
      setEvents(ordered);
      setError(null);
    } catch (e: any) {
      setError(String(e?.message ?? e));
    } finally {
      setLoading(false);
    }
  }, [roomID, limit]);

  useEffect(() => {
    refresh();
  }, [refresh]);

  useEffect(() => {
    if (!roomID) return;
    const off = EventsOn("matrix:event", (ev: SyncEventView) => {
      if (ev?.room_id !== roomID) return;
      if (ev?.type !== "message" && ev?.type !== "encrypted") return;
      setEvents((prev) => {
        // Dedupe by event_id (sync may replay).
        if (prev.some((p) => p.event_id === ev.event_id)) return prev;
        const next: MatrixEvent = {
          event_id: ev.event_id,
          room_id: ev.room_id,
          sender: ev.sender,
          type: ev.type === "encrypted" ? "m.room.encrypted" : "m.room.message",
          ts: ev.ts,
          body: ev.body ?? "",
          encrypted_raw: ev.type === "encrypted",
        };
        return [...prev, next];
      });
    });
    return () => {
      if (typeof off === "function") off();
    };
  }, [roomID]);

  return { events, loading, error, refresh };
}
