import { useEffect, useRef, useState } from "react";
import type { Editor as TiptapEditor } from "@tiptap/core";
import type { HocuspocusProvider } from "@hocuspocus/provider";
import { Cloud, CloudOff, Loader2 } from "lucide-react";
import { Tooltip } from "./Tooltip";

type SyncStatus = "connected" | "syncing" | "saved" | "disconnected";

interface Props {
  editorInstance: TiptapEditor | null;
  providerRef: { current: HocuspocusProvider | null };
}

/**
 * Tiny connection/saving indicator for the editor top bar. Listens to the
 * Hocuspocus provider (`connect` / `disconnect` / `synced`) and the TipTap
 * editor (`update`) to flip between "Saved", "Saving..." and "Offline".
 */
export function SyncIndicator({ editorInstance, providerRef }: Props) {
  const [status, setStatus] = useState<SyncStatus>("disconnected");
  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  useEffect(() => {
    const provider = providerRef.current;
    if (!provider) return;
    const onConnect = () => setStatus("saved");
    const onDisconnect = () => setStatus("disconnected");
    const onSynced = () => setStatus("saved");
    provider.on("connect", onConnect);
    provider.on("disconnect", onDisconnect);
    provider.on("synced", onSynced);
    const wsProvider = (provider as any).configuration?.websocketProvider;
    setStatus(wsProvider?.status === "connected" ? "saved" : "disconnected");
    return () => {
      provider.off("connect", onConnect);
      provider.off("disconnect", onDisconnect);
      provider.off("synced", onSynced);
    };
  }, [providerRef]);

  useEffect(() => {
    const editor = editorInstance;
    const provider = providerRef.current;
    if (!editor || !provider) return;
    const onUpdate = () => {
      setStatus("syncing");
      if (timerRef.current) clearTimeout(timerRef.current);
      timerRef.current = setTimeout(() => {
        const wsProvider = (provider as any).configuration?.websocketProvider;
        setStatus(wsProvider?.status === "connected" ? "saved" : "disconnected");
      }, 1500);
    };
    editor.on("update", onUpdate);
    return () => { editor.off("update", onUpdate); };
  }, [editorInstance, providerRef]);

  const label =
    status === "saved" ? "Saved" :
    status === "syncing" ? "Saving..." :
    status === "connected" ? "Connected" :
    "Offline";

  const tooltip =
    status === "saved" ? "All changes saved" :
    status === "syncing" ? "Saving..." :
    status === "connected" ? "Connected" :
    "Disconnected";

  return (
    <Tooltip title={tooltip}>
      <span className={`sync-indicator sync-indicator--${status}`}>
        {status === "syncing" && <Loader2 size={14} className="spin" />}
        {status === "saved" && <Cloud size={14} />}
        {status === "connected" && <Cloud size={14} />}
        {status === "disconnected" && <CloudOff size={14} />}
        <span className="sync-indicator__label">{label}</span>
      </span>
    </Tooltip>
  );
}
