import { useState, useEffect, useRef, useCallback } from 'react';

export interface ConversationSummary {
  id: string;
  title: string | null;
  archived: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface UseConversationsOptions {
  gatewayUrl: string;
  sessionCookie?: string;
}

export interface UseConversationsReturn {
  conversations: ConversationSummary[];
  loading: boolean;
  error: string | null;
  refresh: () => Promise<void>;
  createConversation: (title?: string) => Promise<ConversationSummary | null>;
  deleteConversation: (id: string) => Promise<boolean>;
  renameConversation: (id: string, title: string) => Promise<boolean>;
}

export function useConversations(opts: UseConversationsOptions): UseConversationsReturn {
  const { gatewayUrl, sessionCookie } = opts;

  const [conversations, setConversations] = useState<ConversationSummary[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const mountedRef = useRef(true);

  const headers = useCallback(
    (includeContentType = true): Record<string, string> => {
      const h: Record<string, string> = { Origin: gatewayUrl };
      if (includeContentType) h['Content-Type'] = 'application/json';
      if (sessionCookie) h['Cookie'] = sessionCookie;
      return h;
    },
    [gatewayUrl, sessionCookie],
  );

  const refresh = useCallback(async () => {
    if (!mountedRef.current) return;
    setLoading(true);
    setError(null);
    try {
      const res = await fetch(`${gatewayUrl}/api/conversations`, { headers: headers(false) });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = (await res.json()) as ConversationSummary[];
      if (mountedRef.current) {
        setConversations(data);
      }
    } catch (err) {
      if (mountedRef.current) {
        setError(err instanceof Error ? err.message : 'Unknown error');
      }
    } finally {
      if (mountedRef.current) {
        setLoading(false);
      }
    }
  }, [gatewayUrl, headers]);

  useEffect(() => {
    mountedRef.current = true;
    void refresh();
    return () => {
      mountedRef.current = false;
    };
  }, [refresh]);

  const createConversation = useCallback(
    async (title?: string): Promise<ConversationSummary | null> => {
      try {
        const res = await fetch(`${gatewayUrl}/api/conversations`, {
          method: 'POST',
          headers: headers(),
          body: JSON.stringify({ title: title ?? null }),
        });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = (await res.json()) as ConversationSummary;
        if (mountedRef.current) {
          setConversations((prev) => [data, ...prev]);
        }
        return data;
      } catch {
        return null;
      }
    },
    [gatewayUrl, headers],
  );

  const deleteConversation = useCallback(
    async (id: string): Promise<boolean> => {
      try {
        const res = await fetch(`${gatewayUrl}/api/conversations/${id}`, {
          method: 'DELETE',
          headers: headers(false),
        });
        if (!res.ok) return false;
        if (mountedRef.current) {
          setConversations((prev) => prev.filter((c) => c.id !== id));
        }
        return true;
      } catch {
        return false;
      }
    },
    [gatewayUrl, headers],
  );

  const renameConversation = useCallback(
    async (id: string, title: string): Promise<boolean> => {
      try {
        const res = await fetch(`${gatewayUrl}/api/conversations/${id}`, {
          method: 'PATCH',
          headers: headers(),
          body: JSON.stringify({ title }),
        });
        if (!res.ok) return false;
        if (mountedRef.current) {
          setConversations((prev) => prev.map((c) => (c.id === id ? { ...c, title } : c)));
        }
        return true;
      } catch {
        return false;
      }
    },
    [gatewayUrl, headers],
  );

  return {
    conversations,
    loading,
    error,
    refresh,
    createConversation,
    deleteConversation,
    renameConversation,
  };
}
