/**
 * useAgentSettings Hook
 * Unified hook for all agent settings including notifications and limits
 * OQI-007: LLM Strategy Agent - Settings Hook
 */

import { useCallback } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../../../lib/apiClient';

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

export interface NotificationSettings {
  emailNotifications: boolean;
  pushNotifications: boolean;
  signalAlerts: boolean;
  riskAlerts: boolean;
  dailyDigest: boolean;
  weeklyReport: boolean;
}

export interface OperationLimits {
  maxDailyTrades: number;
  maxPositionSize: number;
  maxDailyLoss: number;
  maxDrawdown: number;
  pauseOnLossStreak: number;
}

export interface CommunicationPreferences {
  responseStyle: 'concise' | 'detailed' | 'technical';
  language: 'es' | 'en';
  includeCharts: boolean;
  includeSignals: boolean;
  autoAnalyze: boolean;
}

export interface AgentSettings {
  notifications: NotificationSettings;
  limits: OperationLimits;
  communication: CommunicationPreferences;
  timezone: string;
  riskProfile: 'conservative' | 'moderate' | 'aggressive';
  preferredTimeframes: string[];
  preferredSymbols: string[];
}

interface UseAgentSettingsOptions {
  enabled?: boolean;
}

interface UseAgentSettingsReturn {
  settings: AgentSettings;
  isLoading: boolean;
  isSaving: boolean;
  isError: boolean;
  error: Error | null;
  // Notifications
  notifications: NotificationSettings;
  updateNotifications: (updates: Partial<NotificationSettings>) => Promise<void>;
  // Limits
  limits: OperationLimits;
  updateLimits: (updates: Partial<OperationLimits>) => Promise<void>;
  // Communication
  communication: CommunicationPreferences;
  updateCommunication: (updates: Partial<CommunicationPreferences>) => Promise<void>;
  // General
  updateSettings: (updates: Partial<AgentSettings>) => Promise<void>;
  resetSettings: () => Promise<void>;
  refresh: () => Promise<void>;
}

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

const settingsApi = {
  get: async (): Promise<AgentSettings> => {
    const response = await apiClient.get('/llm/agent/settings');
    return response.data;
  },

  update: async (updates: Partial<AgentSettings>): Promise<AgentSettings> => {
    const response = await apiClient.patch('/llm/agent/settings', updates);
    return response.data;
  },

  updateNotifications: async (updates: Partial<NotificationSettings>): Promise<AgentSettings> => {
    const response = await apiClient.patch('/llm/agent/settings/notifications', updates);
    return response.data;
  },

  updateLimits: async (updates: Partial<OperationLimits>): Promise<AgentSettings> => {
    const response = await apiClient.patch('/llm/agent/settings/limits', updates);
    return response.data;
  },

  updateCommunication: async (updates: Partial<CommunicationPreferences>): Promise<AgentSettings> => {
    const response = await apiClient.patch('/llm/agent/settings/communication', updates);
    return response.data;
  },

  reset: async (): Promise<AgentSettings> => {
    const response = await apiClient.post('/llm/agent/settings/reset');
    return response.data;
  },
};

// ============================================================================
// Default Settings
// ============================================================================

const DEFAULT_SETTINGS: AgentSettings = {
  notifications: {
    emailNotifications: true,
    pushNotifications: true,
    signalAlerts: true,
    riskAlerts: true,
    dailyDigest: false,
    weeklyReport: true,
  },
  limits: {
    maxDailyTrades: 10,
    maxPositionSize: 2,
    maxDailyLoss: 3,
    maxDrawdown: 10,
    pauseOnLossStreak: 3,
  },
  communication: {
    responseStyle: 'detailed',
    language: 'es',
    includeCharts: true,
    includeSignals: true,
    autoAnalyze: false,
  },
  timezone: 'America/Mexico_City',
  riskProfile: 'moderate',
  preferredTimeframes: ['H1', 'H4', 'D1'],
  preferredSymbols: ['XAUUSD', 'EURUSD', 'BTCUSD'],
};

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

export function useAgentSettings(options: UseAgentSettingsOptions = {}): UseAgentSettingsReturn {
  const { enabled = true } = options;
  const queryClient = useQueryClient();

  // Query for settings
  const {
    data: settings = DEFAULT_SETTINGS,
    isLoading,
    isError,
    error,
    refetch,
  } = useQuery({
    queryKey: ['agent-settings'],
    queryFn: settingsApi.get,
    enabled,
    staleTime: 60000, // 1 minute
  });

  // Generic update mutation
  const updateMutation = useMutation({
    mutationFn: settingsApi.update,
    onMutate: async (updates) => {
      await queryClient.cancelQueries({ queryKey: ['agent-settings'] });
      const previousSettings = queryClient.getQueryData<AgentSettings>(['agent-settings']);
      queryClient.setQueryData<AgentSettings>(['agent-settings'], (old) =>
        old ? { ...old, ...updates } : undefined
      );
      return { previousSettings };
    },
    onError: (_err, _vars, context) => {
      if (context?.previousSettings) {
        queryClient.setQueryData(['agent-settings'], context.previousSettings);
      }
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['agent-settings'] });
    },
  });

  // Notifications mutation
  const updateNotificationsMutation = useMutation({
    mutationFn: settingsApi.updateNotifications,
    onMutate: async (updates) => {
      await queryClient.cancelQueries({ queryKey: ['agent-settings'] });
      const previousSettings = queryClient.getQueryData<AgentSettings>(['agent-settings']);
      queryClient.setQueryData<AgentSettings>(['agent-settings'], (old) =>
        old ? { ...old, notifications: { ...old.notifications, ...updates } } : undefined
      );
      return { previousSettings };
    },
    onError: (_err, _vars, context) => {
      if (context?.previousSettings) {
        queryClient.setQueryData(['agent-settings'], context.previousSettings);
      }
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['agent-settings'] });
    },
  });

  // Limits mutation
  const updateLimitsMutation = useMutation({
    mutationFn: settingsApi.updateLimits,
    onMutate: async (updates) => {
      await queryClient.cancelQueries({ queryKey: ['agent-settings'] });
      const previousSettings = queryClient.getQueryData<AgentSettings>(['agent-settings']);
      queryClient.setQueryData<AgentSettings>(['agent-settings'], (old) =>
        old ? { ...old, limits: { ...old.limits, ...updates } } : undefined
      );
      return { previousSettings };
    },
    onError: (_err, _vars, context) => {
      if (context?.previousSettings) {
        queryClient.setQueryData(['agent-settings'], context.previousSettings);
      }
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['agent-settings'] });
    },
  });

  // Communication mutation
  const updateCommunicationMutation = useMutation({
    mutationFn: settingsApi.updateCommunication,
    onMutate: async (updates) => {
      await queryClient.cancelQueries({ queryKey: ['agent-settings'] });
      const previousSettings = queryClient.getQueryData<AgentSettings>(['agent-settings']);
      queryClient.setQueryData<AgentSettings>(['agent-settings'], (old) =>
        old ? { ...old, communication: { ...old.communication, ...updates } } : undefined
      );
      return { previousSettings };
    },
    onError: (_err, _vars, context) => {
      if (context?.previousSettings) {
        queryClient.setQueryData(['agent-settings'], context.previousSettings);
      }
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['agent-settings'] });
    },
  });

  // Reset mutation
  const resetMutation = useMutation({
    mutationFn: settingsApi.reset,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['agent-settings'] });
    },
  });

  // Handlers
  const updateSettings = useCallback(async (updates: Partial<AgentSettings>) => {
    await updateMutation.mutateAsync(updates);
  }, [updateMutation]);

  const updateNotifications = useCallback(async (updates: Partial<NotificationSettings>) => {
    await updateNotificationsMutation.mutateAsync(updates);
  }, [updateNotificationsMutation]);

  const updateLimits = useCallback(async (updates: Partial<OperationLimits>) => {
    await updateLimitsMutation.mutateAsync(updates);
  }, [updateLimitsMutation]);

  const updateCommunication = useCallback(async (updates: Partial<CommunicationPreferences>) => {
    await updateCommunicationMutation.mutateAsync(updates);
  }, [updateCommunicationMutation]);

  const resetSettings = useCallback(async () => {
    await resetMutation.mutateAsync();
  }, [resetMutation]);

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

  return {
    settings,
    isLoading,
    isSaving: updateMutation.isPending || updateNotificationsMutation.isPending ||
              updateLimitsMutation.isPending || updateCommunicationMutation.isPending,
    isError,
    error: error as Error | null,
    notifications: settings.notifications,
    updateNotifications,
    limits: settings.limits,
    updateLimits,
    communication: settings.communication,
    updateCommunication,
    updateSettings,
    resetSettings,
    refresh,
  };
}

export default useAgentSettings;
