"use client";

import Link from "next/link";
import { Suspense, useEffect, useState } from "react";
import type { SavedItem } from "@slackwsh/contracts";
import { AppShell, ScreenHeader, useWorkspaceIdParam } from "../../components/AppShell";
import { api } from "../../lib/api";
import { getSavedMessages, unsaveMessage as removeLegacySavedMessage } from "../../lib/saved-items";

function SavedView() {
  const workspaceId = useWorkspaceIdParam();
  const [items, setItems] = useState<SavedItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!workspaceId) return;
    let cancelled = false;
    let refreshing = false;
    const refresh = () => {
      if (refreshing) return;
      refreshing = true;
      setLoading(true);
      void (async () => {
        const legacy = getSavedMessages(workspaceId);
        await Promise.all(legacy.map(async (item) => {
          try {
            await api.saveItem(workspaceId, item.id);
            removeLegacySavedMessage(workspaceId, item.id);
          } catch {
            // Keep failed legacy entries for a later retry.
          }
        }));
        return api.savedItems(workspaceId);
      })().then((res) => {
        if (!cancelled) {
          setItems(res.items);
          setError(null);
        }
      }).catch(() => {
        if (!cancelled) setError("Could not load saved items.");
      }).finally(() => {
        refreshing = false;
        if (!cancelled) setLoading(false);
      });
    };
    const onUpdated = (event: Event) => {
      const changedWorkspaceId = (event as CustomEvent<{ workspaceId?: string | number }>).detail?.workspaceId;
      if (changedWorkspaceId == null || String(changedWorkspaceId) === workspaceId) refresh();
    };
    refresh();
    window.addEventListener("slackwsh:saved-updated", onUpdated);
    return () => {
      cancelled = true;
      window.removeEventListener("slackwsh:saved-updated", onUpdated);
    };
  }, [workspaceId]);

  async function remove(messageId: string | number) {
    if (!workspaceId) return;
    const previous = items;
    setItems((current) => current.filter((item) => String(item.id) !== String(messageId)));
    try {
      await api.unsaveItem(workspaceId, messageId);
    } catch {
      setItems(previous);
      setError("Could not remove the saved item.");
    }
  }

  return (
    <AppShell active="messages" title="Saved items" subtitle="Messages you saved for later">
      <ScreenHeader title="Saved items" subtitle={`${items.length} saved ${items.length === 1 ? "message" : "messages"}`} />
      <div className="screen-body">
        {error && <p className="error-text">{error}</p>}
        <div className="screen-list tall">
          {items.map((item) => (
            <div className="screen-thread" key={item.id}>
              <div className="screen-thread-main">
                <span className="screen-thread-meta">
                  {item.authorName} · {item.channelName ? `#${item.channelName}` : "conversation"} ·{" "}
                  {new Date(item.createdAt).toLocaleString()}
                </span>
                <span className="screen-thread-text">{item.text}</span>
                <div className="saved-actions">
                  <Link className="screen-btn" href={`/channel?workspaceId=${workspaceId}&channelId=${item.channelId}#msg-${item.id}`}>
                    Open
                  </Link>
                  <button className="screen-btn" type="button" onClick={() => remove(item.id)}>
                    Remove
                  </button>
                </div>
              </div>
            </div>
          ))}
          {loading && <div className="empty-state">Loading saved items...</div>}
          {!loading && items.length === 0 && <div className="empty-state">No saved messages yet.</div>}
        </div>
      </div>
    </AppShell>
  );
}

export default function SavedPage() {
  return (
    <Suspense fallback={<main className="page"><div className="empty-state">Loading saved items...</div></main>}>
      <SavedView />
    </Suspense>
  );
}
