/**
 * useConversations Hook
 * Enhanced conversation management with filtering and search
 * OQI-007: LLM Strategy Agent - Conversations Hook
 */

import { useState, useCallback, useMemo } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { isWithinInterval, startOfDay, endOfDay, subDays } from 'date-fns';
import { apiClient } from '../../../lib/apiClient';
import type { ChatSession } from '../../../types/chat.types';

// ============================================================================
// Types
// ============================================================================

type DateFilter = 'all' | 'today' | 'week' | 'month' | 'custom';

interface DateRange {
  start: Date;
  end: Date;
}

interface UseConversationsOptions {
  enabled?: boolean;
  autoRefresh?: boolean;
  refreshInterval?: number;
}

interface UseConversationsReturn {
  sessions: ChatSession[];
  filteredSessions: ChatSession[];
  currentSessionId: string | null;
  isLoading: boolean;
  isError: boolean;
  error: Error | null;
  // Filters
  searchQuery: string;
  dateFilter: DateFilter;
  customDateRange: DateRange | null;
  setSearchQuery: (query: string) => void;
  setDateFilter: (filter: DateFilter) => void;
  setCustomDateRange: (range: DateRange | null) => void;
  clearFilters: () => void;
  // Actions
  selectSession: (sessionId: string) => void;
  createSession: () => Promise<string>;
  deleteSession: (sessionId: string) => Promise<void>;
  archiveSession: (sessionId: string) => Promise<void>;
  exportSession: (sessionId: string) => Promise<Blob>;
  refresh: () => Promise<void>;
  // Stats
  totalMessages: number;
  sessionCount: number;
}

// ============================================================================
// API Functions
// ============================================================================

const conversationsApi = {
  getAll: async (): Promise<ChatSession[]> => {
    const response = await apiClient.get('/llm/sessions');
    return response.data;
  },

  create: async (): Promise<{ sessionId: string }> => {
    const response = await apiClient.post('/llm/sessions');
    return response.data;
  },

  delete: async (sessionId: string): Promise<void> => {
    await apiClient.delete(`/llm/sessions/${sessionId}`);
  },

  archive: async (sessionId: string): Promise<void> => {
    await apiClient.patch(`/llm/sessions/${sessionId}/archive`);
  },

  export: async (sessionId: string): Promise<Blob> => {
    const response = await apiClient.get(`/llm/sessions/${sessionId}/export`, {
      responseType: 'blob',
    });
    return response.data;
  },
};

// ============================================================================
// Helper Functions
// ============================================================================

const getDateRange = (filter: DateFilter, customRange?: DateRange | null): DateRange | null => {
  const now = new Date();
  switch (filter) {
    case 'today':
      return { start: startOfDay(now), end: endOfDay(now) };
    case 'week':
      return { start: startOfDay(subDays(now, 7)), end: endOfDay(now) };
    case 'month':
      return { start: startOfDay(subDays(now, 30)), end: endOfDay(now) };
    case 'custom':
      return customRange || null;
    default:
      return null;
  }
};

// ============================================================================
// Hook Implementation
// ============================================================================

export function useConversations(options: UseConversationsOptions = {}): UseConversationsReturn {
  const { enabled = true, autoRefresh = false, refreshInterval = 30000 } = options;
  const queryClient = useQueryClient();

  // Local state
  const [currentSessionId, setCurrentSessionId] = useState<string | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [dateFilter, setDateFilter] = useState<DateFilter>('all');
  const [customDateRange, setCustomDateRange] = useState<DateRange | null>(null);

  // Query for sessions
  const {
    data: sessions = [],
    isLoading,
    isError,
    error,
    refetch,
  } = useQuery({
    queryKey: ['conversations'],
    queryFn: conversationsApi.getAll,
    enabled,
    refetchInterval: autoRefresh ? refreshInterval : false,
    staleTime: 15000, // 15 seconds
  });

  // Create mutation
  const createMutation = useMutation({
    mutationFn: conversationsApi.create,
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: ['conversations'] });
      setCurrentSessionId(data.sessionId);
    },
  });

  // Delete mutation
  const deleteMutation = useMutation({
    mutationFn: conversationsApi.delete,
    onMutate: async (sessionId) => {
      await queryClient.cancelQueries({ queryKey: ['conversations'] });
      const previousSessions = queryClient.getQueryData<ChatSession[]>(['conversations']);
      queryClient.setQueryData<ChatSession[]>(['conversations'], (old) =>
        old?.filter((s) => s.id !== sessionId)
      );
      return { previousSessions };
    },
    onError: (_err, _vars, context) => {
      if (context?.previousSessions) {
        queryClient.setQueryData(['conversations'], context.previousSessions);
      }
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['conversations'] });
    },
  });

  // Archive mutation
  const archiveMutation = useMutation({
    mutationFn: conversationsApi.archive,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['conversations'] });
    },
  });

  // Filtered sessions
  const filteredSessions = useMemo(() => {
    let filtered = [...sessions];

    // Search filter
    if (searchQuery.trim()) {
      const query = searchQuery.toLowerCase();
      filtered = filtered.filter((session) => {
        // Search in messages
        const hasMatch = session.messages.some((m) =>
          m.content.toLowerCase().includes(query)
        );
        // Search in first message (title)
        const firstUserMsg = session.messages.find((m) => m.role === 'user');
        const titleMatch = firstUserMsg?.content.toLowerCase().includes(query);
        return hasMatch || titleMatch;
      });
    }

    // Date filter
    const range = getDateRange(dateFilter, customDateRange);
    if (range) {
      filtered = filtered.filter((session) => {
        const date = new Date(session.updatedAt);
        return isWithinInterval(date, { start: range.start, end: range.end });
      });
    }

    // Sort by most recent
    return filtered.sort((a, b) =>
      new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
    );
  }, [sessions, searchQuery, dateFilter, customDateRange]);

  // Stats
  const totalMessages = useMemo(() =>
    sessions.reduce((acc, s) => acc + s.messages.length, 0),
    [sessions]
  );

  // Handlers
  const selectSession = useCallback((sessionId: string) => {
    setCurrentSessionId(sessionId);
    localStorage.setItem('currentChatSessionId', sessionId);
  }, []);

  const createSession = useCallback(async (): Promise<string> => {
    const result = await createMutation.mutateAsync();
    return result.sessionId;
  }, [createMutation]);

  const deleteSession = useCallback(async (sessionId: string) => {
    await deleteMutation.mutateAsync(sessionId);
    if (currentSessionId === sessionId) {
      setCurrentSessionId(null);
      localStorage.removeItem('currentChatSessionId');
    }
  }, [deleteMutation, currentSessionId]);

  const archiveSession = useCallback(async (sessionId: string) => {
    await archiveMutation.mutateAsync(sessionId);
  }, [archiveMutation]);

  const exportSession = useCallback(async (sessionId: string): Promise<Blob> => {
    return await conversationsApi.export(sessionId);
  }, []);

  const clearFilters = useCallback(() => {
    setSearchQuery('');
    setDateFilter('all');
    setCustomDateRange(null);
  }, []);

  const refresh = useCallback(async () => {
    await refetch();
  }, [refetch]);

  return {
    sessions,
    filteredSessions,
    currentSessionId,
    isLoading,
    isError,
    error: error as Error | null,
    searchQuery,
    dateFilter,
    customDateRange,
    setSearchQuery,
    setDateFilter,
    setCustomDateRange,
    clearFilters,
    selectSession,
    createSession,
    deleteSession,
    archiveSession,
    exportSession,
    refresh,
    totalMessages,
    sessionCount: sessions.length,
  };
}

export default useConversations;
