import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useCallback } from 'react';
import { useClient } from 'hooks/useClient';
import { useAuth } from 'hooks/useAuth';

const SESSIONS_KEY = 'CLAUDE_SESSIONS';

export type ClaudeSessionSummary = {
  id: string; // Claude session uuid (= transcript filename)
  title: string;
  cwd: string;
  createdAt: string;
  updatedAt: string;
  messageCount: number;
  harness?: 'claude' | 'opencode'; // which harness produced it (absent = claude)
};

// Display-ready message, matching the frontend ChatMessage union (rebuilt from Claude's transcript).
export type ClaudeSessionMessage =
  | { role: 'user'; text: string }
  | { role: 'assistant'; id: string; text: string }
  | {
      role: 'tool';
      toolName: string;
      toolInput: Record<string, unknown>;
      toolCallId: string;
      output?: string;
      isError?: boolean;
    };

export type ClaudeSessionDetail = { id: string; model: string; cwd: string; messages: ClaudeSessionMessage[] };

export type ClaudePwd = { cwd: string; sessionCount: number; updatedAt: string; isDefault: boolean };

// Query string for the selected working directory (null/undefined = the default general_chat_sessions dir).
const cwdQuery = (cwd?: string | null) => (cwd ? `?cwd=${encodeURIComponent(cwd)}` : '');

/** The default /chat dir plus every directory that already has Claude sessions. */
export function useChatPwds() {
  const client = useClient();
  const { isAuthenticated } = useAuth();
  const { data } = useQuery<{ pwds: ClaudePwd[]; default: string }>({
    queryKey: ['CHAT_PWDS'],
    enabled: isAuthenticated,
    queryFn: () => client.get<{ pwds: ClaudePwd[]; default: string }>('/chat/pwds'),
    staleTime: 30 * 1000,
  });
  return { pwds: data?.pwds ?? [], defaultCwd: data?.default ?? null };
}

/** Sessions for a working directory, read from Claude's own transcript store (source of truth). */
export function useClaudeSessions(cwd?: string | null) {
  const client = useClient();
  const queryClient = useQueryClient();
  const { isAuthenticated } = useAuth();
  const q = cwdQuery(cwd);

  const { data, isLoading, refetch } = useQuery<{ sessions: ClaudeSessionSummary[] }>({
    queryKey: [SESSIONS_KEY, cwd ?? 'default'],
    enabled: isAuthenticated,
    queryFn: () => client.get<{ sessions: ClaudeSessionSummary[] }>(`/chat/sessions${q}`),
    staleTime: 30 * 1000,
  });

  const loadSession = (id: string) => client.get<ClaudeSessionDetail>(`/chat/sessions/${id}${q}`);

  // Invalidate every cwd's list (also refreshes pwd counts) — cheap and avoids stale lists.
  const invalidate = useCallback(() => {
    queryClient.invalidateQueries({ queryKey: [SESSIONS_KEY] });
    queryClient.invalidateQueries({ queryKey: ['CHAT_PWDS'] });
  }, [queryClient]);

  const deleteSession = useCallback(
    async (id: string) => {
      await client.delete(`/chat/sessions/${id}${q}`);
      invalidate();
    },
    [client, q, invalidate],
  );

  const renameSession = useCallback(
    async (id: string, title: string) => {
      await client.patch(`/chat/sessions/${id}/title${q}`, { title });
      invalidate();
    },
    [client, q, invalidate],
  );

  return { sessions: data?.sessions ?? [], isLoading, refetch, loadSession, deleteSession, renameSession, invalidate };
}
