'use client'

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  getEnterpriseClients,
  getEnterpriseClient,
  createEnterpriseClient,
  updateEnterpriseClient,
  deleteEnterpriseClient,
  getClientServers,
  getClientServer,
  addClientServer,
  updateClientServer,
  removeClientServer,
  testServerPortainerConnection,
  performServerAction,
  requestVerificationCode,
  getErrorRules,
  createErrorRule,
  updateErrorRule,
  deleteErrorRule,
  getDetectedErrors,
  acknowledgeError,
  getClientStats,
  getServerStats,
  collectServerStats,
  getServerContainers,
  getContainer,
  getContainerLogs,
  performContainerAction,
  removeContainer,
  getErrorDashboard,
  getContainerEvents,
  acknowledgeContainerEvents,
  getErrorSummary,
  getNotificationSettings,
  updateNotificationSettings,
} from '@/lib/api/admin'
import type { StatsRange, ContainerEventFilters, UpdateNotificationSettingsPayload } from '@/lib/api/admin'
import type {
  CreateEnterpriseClientPayload,
  UpdateEnterpriseClientPayload,
  AddServerPayload,
  UpdateServerPayload,
  ServerActionPayload,
  CreateErrorRulePayload,
  UpdateErrorRulePayload,
  ErrorFilters,
} from '@/types/api'

// ============================================================================
// Query Keys
// ============================================================================

export const enterpriseClientKeys = {
  all: ['enterprise-clients'] as const,
  lists: () => [...enterpriseClientKeys.all, 'list'] as const,
  list: () => [...enterpriseClientKeys.lists()] as const,
  details: () => [...enterpriseClientKeys.all, 'detail'] as const,
  detail: (id: string) => [...enterpriseClientKeys.details(), id] as const,
  servers: (clientId: string) => [...enterpriseClientKeys.detail(clientId), 'servers'] as const,
  server: (clientId: string, serverId: string) => [...enterpriseClientKeys.servers(clientId), serverId] as const,
  serverStats: (clientId: string, serverId: string, range: StatsRange) =>
    [...enterpriseClientKeys.server(clientId, serverId), 'stats', range] as const,
  clientStats: (clientId: string, range: StatsRange) =>
    [...enterpriseClientKeys.detail(clientId), 'stats', range] as const,
  errorRules: (clientId: string) => [...enterpriseClientKeys.detail(clientId), 'error-rules'] as const,
  errors: (clientId: string, filters?: ErrorFilters) => [...enterpriseClientKeys.detail(clientId), 'errors', filters] as const,
  containers: (clientId: string, serverId: string) =>
    [...enterpriseClientKeys.server(clientId, serverId), 'containers'] as const,
  container: (clientId: string, serverId: string, containerId: string) =>
    [...enterpriseClientKeys.containers(clientId, serverId), containerId] as const,
  containerLogs: (clientId: string, serverId: string, containerId: string, tail: number) =>
    [...enterpriseClientKeys.container(clientId, serverId, containerId), 'logs', tail] as const,
  // Error tracking keys
  errorDashboard: (clientId: string) => [...enterpriseClientKeys.detail(clientId), 'error-dashboard'] as const,
  containerEvents: (clientId: string, filters?: ContainerEventFilters) =>
    [...enterpriseClientKeys.detail(clientId), 'container-events', filters] as const,
  errorSummary: () => [...enterpriseClientKeys.all, 'error-summary'] as const,
  // Notification settings key
  notifications: (clientId: string) => [...enterpriseClientKeys.detail(clientId), 'notifications'] as const,
}

// ============================================================================
// Client Hooks
// ============================================================================

export function useEnterpriseClients() {
  return useQuery({
    queryKey: enterpriseClientKeys.list(),
    queryFn: getEnterpriseClients,
  })
}

export function useEnterpriseClient(id: string) {
  return useQuery({
    queryKey: enterpriseClientKeys.detail(id),
    queryFn: () => getEnterpriseClient(id),
    enabled: !!id,
  })
}

export function useCreateEnterpriseClient() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: (data: CreateEnterpriseClientPayload) => createEnterpriseClient(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.lists() })
    },
  })
}

export function useUpdateEnterpriseClient() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: UpdateEnterpriseClientPayload }) =>
      updateEnterpriseClient(id, data),
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.detail(id) })
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.lists() })
    },
  })
}

export function useDeleteEnterpriseClient() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: (id: string) => deleteEnterpriseClient(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.lists() })
    },
  })
}

// ============================================================================
// Server Hooks
// ============================================================================

export function useClientServers(clientId: string) {
  return useQuery({
    queryKey: enterpriseClientKeys.servers(clientId),
    queryFn: () => getClientServers(clientId),
    enabled: !!clientId,
  })
}

export function useClientServer(clientId: string, serverId: string) {
  return useQuery({
    queryKey: enterpriseClientKeys.server(clientId, serverId),
    queryFn: () => getClientServer(clientId, serverId),
    enabled: !!clientId && !!serverId,
  })
}

export function useAddServerToClient() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({ clientId, data }: { clientId: string; data: AddServerPayload }) =>
      addClientServer(clientId, data),
    onSuccess: (_, { clientId }) => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.servers(clientId) })
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.detail(clientId) })
    },
  })
}

export function useUpdateClientServer() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({
      clientId,
      serverId,
      data,
    }: {
      clientId: string
      serverId: string
      data: UpdateServerPayload
    }) => updateClientServer(clientId, serverId, data),
    onSuccess: (_, { clientId, serverId }) => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.server(clientId, serverId) })
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.servers(clientId) })
    },
  })
}

export function useRemoveServerFromClient() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({ clientId, serverId }: { clientId: string; serverId: string }) =>
      removeClientServer(clientId, serverId),
    onSuccess: (_, { clientId }) => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.servers(clientId) })
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.detail(clientId) })
    },
  })
}

export function useTestPortainerConnection() {
  return useMutation({
    mutationFn: ({
      clientId,
      serverId,
      credentials,
    }: {
      clientId: string
      serverId: string
      credentials: { portainerUrl: string; portainerUsername: string; portainerPassword: string }
    }) => testServerPortainerConnection(clientId, serverId, credentials),
  })
}

// ============================================================================
// Server Action Hooks
// ============================================================================

export function useServerAction() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({
      clientId,
      serverId,
      action,
    }: {
      clientId: string
      serverId: string
      action: ServerActionPayload
    }) => performServerAction(clientId, serverId, action),
    onSuccess: (_, { clientId, serverId }) => {
      // Refresh server status after action
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.server(clientId, serverId) })
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.servers(clientId) })
    },
  })
}

export function useRequestVerificationCode() {
  return useMutation({
    mutationFn: ({
      clientId,
      serverId,
      action,
    }: {
      clientId: string
      serverId: string
      action: 'WIPE' | 'REINSTALL'
    }) => requestVerificationCode(clientId, serverId, action),
  })
}

// ============================================================================
// Error Rule Hooks
// ============================================================================

export function useErrorRules(clientId: string) {
  return useQuery({
    queryKey: enterpriseClientKeys.errorRules(clientId),
    queryFn: () => getErrorRules(clientId),
    enabled: !!clientId,
  })
}

export function useCreateErrorRule() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({ clientId, data }: { clientId: string; data: CreateErrorRulePayload }) =>
      createErrorRule(clientId, data),
    onSuccess: (_, { clientId }) => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.errorRules(clientId) })
    },
  })
}

export function useUpdateErrorRule() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({
      clientId,
      ruleId,
      data,
    }: {
      clientId: string
      ruleId: string
      data: UpdateErrorRulePayload
    }) => updateErrorRule(clientId, ruleId, data),
    onSuccess: (_, { clientId }) => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.errorRules(clientId) })
    },
  })
}

export function useDeleteErrorRule() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({ clientId, ruleId }: { clientId: string; ruleId: string }) =>
      deleteErrorRule(clientId, ruleId),
    onSuccess: (_, { clientId }) => {
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.errorRules(clientId) })
    },
  })
}

// ============================================================================
// Detected Error Hooks
// ============================================================================

export function useDetectedErrors(clientId: string, filters?: ErrorFilters) {
  return useQuery({
    queryKey: enterpriseClientKeys.errors(clientId, filters),
    queryFn: () => getDetectedErrors(clientId, filters),
    enabled: !!clientId,
  })
}

export function useAcknowledgeError() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({ clientId, errorId }: { clientId: string; errorId: string }) =>
      acknowledgeError(clientId, errorId),
    onSuccess: (_, { clientId }) => {
      // Invalidate all error queries for this client
      queryClient.invalidateQueries({
        queryKey: enterpriseClientKeys.detail(clientId),
        predicate: (query) => {
          const key = query.queryKey
          return Array.isArray(key) && key.includes('errors')
        },
      })
      // Also refresh the client detail to update error count
      queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.detail(clientId) })
    },
  })
}

// ============================================================================
// Stats Hooks
// ============================================================================

export function useClientStatsOverview(clientId: string, range: StatsRange = '24h') {
  return useQuery({
    queryKey: enterpriseClientKeys.clientStats(clientId, range),
    queryFn: () => getClientStats(clientId, range),
    enabled: !!clientId,
    refetchInterval: 60000, // Refresh every minute
  })
}

export function useServerStatsHistory(
  clientId: string,
  serverId: string,
  range: StatsRange = '24h'
) {
  return useQuery({
    queryKey: enterpriseClientKeys.serverStats(clientId, serverId, range),
    queryFn: () => getServerStats(clientId, serverId, range),
    enabled: !!clientId && !!serverId,
    refetchInterval: 30000, // Refresh every 30 seconds
  })
}

export function useCollectServerStats() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({ clientId, serverId }: { clientId: string; serverId: string }) =>
      collectServerStats(clientId, serverId),
    onSuccess: (_, { clientId, serverId }) => {
      // Invalidate all stats queries for this server
      queryClient.invalidateQueries({
        queryKey: enterpriseClientKeys.server(clientId, serverId),
      })
    },
  })
}

// ============================================================================
// Container Hooks
// ============================================================================

export function useServerContainers(clientId: string, serverId: string, all: boolean = true) {
  return useQuery({
    queryKey: enterpriseClientKeys.containers(clientId, serverId),
    queryFn: () => getServerContainers(clientId, serverId, all),
    enabled: !!clientId && !!serverId,
    refetchInterval: 10000, // Refresh every 10 seconds
  })
}

export function useContainer(clientId: string, serverId: string, containerId: string) {
  return useQuery({
    queryKey: enterpriseClientKeys.container(clientId, serverId, containerId),
    queryFn: () => getContainer(clientId, serverId, containerId),
    enabled: !!clientId && !!serverId && !!containerId,
  })
}

export function useContainerLogs(
  clientId: string,
  serverId: string,
  containerId: string,
  tail: number = 500
) {
  return useQuery({
    queryKey: enterpriseClientKeys.containerLogs(clientId, serverId, containerId, tail),
    queryFn: () => getContainerLogs(clientId, serverId, containerId, tail),
    enabled: !!clientId && !!serverId && !!containerId,
  })
}

export function useContainerAction() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({
      clientId,
      serverId,
      containerId,
      action,
    }: {
      clientId: string
      serverId: string
      containerId: string
      action: 'start' | 'stop' | 'restart'
    }) => performContainerAction(clientId, serverId, containerId, action),
    onSuccess: (_, { clientId, serverId }) => {
      // Invalidate container list to refresh status
      queryClient.invalidateQueries({
        queryKey: enterpriseClientKeys.containers(clientId, serverId),
      })
    },
  })
}

export function useRemoveContainer() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({
      clientId,
      serverId,
      containerId,
      force,
    }: {
      clientId: string
      serverId: string
      containerId: string
      force?: boolean
    }) => removeContainer(clientId, serverId, containerId, force),
    onSuccess: (_, { clientId, serverId }) => {
      // Invalidate container list
      queryClient.invalidateQueries({
        queryKey: enterpriseClientKeys.containers(clientId, serverId),
      })
    },
  })
}

// ============================================================================
// Error Dashboard Hooks
// ============================================================================

export function useErrorDashboard(clientId: string) {
  return useQuery({
    queryKey: enterpriseClientKeys.errorDashboard(clientId),
    queryFn: () => getErrorDashboard(clientId),
    enabled: !!clientId,
    refetchInterval: 60000, // Refresh every minute
  })
}

// ============================================================================
// Container Events Hooks
// ============================================================================

export function useContainerEvents(clientId: string, filters?: ContainerEventFilters) {
  return useQuery({
    queryKey: enterpriseClientKeys.containerEvents(clientId, filters),
    queryFn: () => getContainerEvents(clientId, filters),
    enabled: !!clientId,
    refetchInterval: 30000, // Refresh every 30 seconds
  })
}

export function useAcknowledgeContainerEvents() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({ clientId, eventIds }: { clientId: string; eventIds: string[] }) =>
      acknowledgeContainerEvents(clientId, eventIds),
    onSuccess: (_, { clientId }) => {
      // Invalidate container events queries for this client
      queryClient.invalidateQueries({
        queryKey: enterpriseClientKeys.detail(clientId),
        predicate: (query) => {
          const key = query.queryKey
          return Array.isArray(key) && key.includes('container-events')
        },
      })
      // Also refresh the error dashboard
      queryClient.invalidateQueries({
        queryKey: enterpriseClientKeys.errorDashboard(clientId),
      })
      // Also refresh the global error summary
      queryClient.invalidateQueries({
        queryKey: enterpriseClientKeys.errorSummary(),
      })
    },
  })
}

// ============================================================================
// All Clients Error Summary Hooks
// ============================================================================

export function useAllClientsErrorSummary() {
  return useQuery({
    queryKey: enterpriseClientKeys.errorSummary(),
    queryFn: getErrorSummary,
    refetchInterval: 60000, // Refresh every minute
  })
}

// ============================================================================
// Notification Settings Hooks
// ============================================================================

export function useNotificationSettings(clientId: string) {
  return useQuery({
    queryKey: enterpriseClientKeys.notifications(clientId),
    queryFn: () => getNotificationSettings(clientId),
    enabled: !!clientId,
  })
}

export function useUpdateNotificationSettings() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: ({
      clientId,
      data,
    }: {
      clientId: string
      data: UpdateNotificationSettingsPayload
    }) => updateNotificationSettings(clientId, data),
    onSuccess: (_, { clientId }) => {
      queryClient.invalidateQueries({
        queryKey: enterpriseClientKeys.notifications(clientId),
      })
    },
  })
}
