/**
 * Communication Credits Hooks
 * For managing business SMS/calling credits and auto-reload settings
 */

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

export interface CommunicationCredits {
  id: number;
  balance_cents: number;
  auto_reload_enabled: boolean;
  auto_reload_threshold_cents: number;
  auto_reload_amount_cents: number;
  low_balance_warning_cents: number;
  low_balance_warning_sent: boolean;
  stripe_payment_method_id: string;
  last_twilio_sync_at: string | null;
  total_loaded_cents: number;
  total_spent_cents: number;
  created_at: string;
  updated_at: string;
}

export interface CreditTransaction {
  id: number;
  amount_cents: number;
  balance_after_cents: number;
  transaction_type: 'manual' | 'auto_reload' | 'usage' | 'refund' | 'adjustment' | 'promo';
  description: string;
  reference_type: string;
  reference_id: string;
  stripe_charge_id: string;
  created_at: string;
}

export interface UpdateCreditsSettings {
  auto_reload_enabled?: boolean;
  auto_reload_threshold_cents?: number;
  auto_reload_amount_cents?: number;
  low_balance_warning_cents?: number;
  stripe_payment_method_id?: string;
}

export interface AddCreditsRequest {
  amount_cents: number;
  payment_method_id?: string;
}

/**
 * Hook to get communication credits for current business
 */
export const useCommunicationCredits = () => {
  return useQuery<CommunicationCredits>({
    queryKey: ['communicationCredits'],
    queryFn: async () => {
      const { data } = await apiClient.get('/communication-credits/');
      return data;
    },
    staleTime: 30 * 1000, // 30 seconds
  });
};

/**
 * Hook to get credit transaction history
 */
export const useCreditTransactions = (page = 1, limit = 20) => {
  return useQuery<{ results: CreditTransaction[]; count: number; next: string | null; previous: string | null }>({
    queryKey: ['creditTransactions', page, limit],
    queryFn: async () => {
      const { data } = await apiClient.get('/communication-credits/transactions/', {
        params: { page, limit },
      });
      return data;
    },
    staleTime: 30 * 1000,
  });
};

/**
 * Hook to update credit settings (auto-reload, thresholds, etc.)
 */
export const useUpdateCreditsSettings = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (settings: UpdateCreditsSettings) => {
      const { data } = await apiClient.patch('/communication-credits/settings/', settings);
      return data;
    },
    onSuccess: (data) => {
      queryClient.setQueryData(['communicationCredits'], data);
    },
  });
};

/**
 * Hook to add credits (manual top-up)
 */
export const useAddCredits = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (request: AddCreditsRequest) => {
      const { data } = await apiClient.post('/communication-credits/add/', request);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['communicationCredits'] });
      queryClient.invalidateQueries({ queryKey: ['creditTransactions'] });
    },
  });
};

/**
 * Hook to create a payment intent for credit purchase
 */
export const useCreatePaymentIntent = () => {
  return useMutation({
    mutationFn: async (amount_cents: number) => {
      const { data } = await apiClient.post('/communication-credits/create-payment-intent/', {
        amount_cents,
      });
      return data as { client_secret: string; payment_intent_id: string };
    },
  });
};

/**
 * Hook to confirm a payment after client-side processing
 */
export const useConfirmPayment = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (params: { payment_intent_id: string; save_payment_method?: boolean }) => {
      const { data } = await apiClient.post('/communication-credits/confirm-payment/', params);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['communicationCredits'] });
      queryClient.invalidateQueries({ queryKey: ['creditTransactions'] });
    },
  });
};

/**
 * Hook to set up Stripe payment method for auto-reload
 */
export const useSetupPaymentMethod = () => {
  return useMutation({
    mutationFn: async () => {
      const { data } = await apiClient.post('/communication-credits/setup-payment-method/');
      return data as { client_secret: string };
    },
  });
};

/**
 * Hook to save a payment method after setup
 */
export const useSavePaymentMethod = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (payment_method_id: string) => {
      const { data } = await apiClient.post('/communication-credits/save-payment-method/', {
        payment_method_id,
      });
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['communicationCredits'] });
    },
  });
};

/**
 * Hook to get communication usage stats
 */
export const useCommunicationUsageStats = () => {
  return useQuery<{
    sms_sent_this_month: number;
    voice_minutes_this_month: number;
    proxy_numbers_active: number;
    estimated_cost_cents: number;
  }>({
    queryKey: ['communicationUsageStats'],
    queryFn: async () => {
      const { data } = await apiClient.get('/communication-credits/usage-stats/');
      return data;
    },
    staleTime: 60 * 1000, // 1 minute
  });
};

// =============================================================================
// Phone Number Management Hooks
// =============================================================================

export interface ProxyPhoneNumber {
  id: number;
  phone_number: string;
  friendly_name: string;
  status: 'available' | 'assigned' | 'reserved' | 'inactive';
  monthly_fee_cents: number;
  capabilities: {
    voice: boolean;
    sms: boolean;
    mms: boolean;
  };
  assigned_at: string | null;
  last_billed_at: string | null;
}

export interface AvailablePhoneNumber {
  phone_number: string;
  friendly_name: string;
  locality: string;
  region: string;
  postal_code: string;
  capabilities: {
    voice: boolean;
    sms: boolean;
    mms: boolean;
  };
  monthly_cost_cents: number;
}

/**
 * Hook to list phone numbers assigned to the tenant
 */
export const usePhoneNumbers = () => {
  return useQuery<{ numbers: ProxyPhoneNumber[]; count: number }>({
    queryKey: ['phoneNumbers'],
    queryFn: async () => {
      const { data } = await apiClient.get('/communication-credits/phone-numbers/');
      return data;
    },
    staleTime: 30 * 1000,
  });
};

/**
 * Hook to search for available phone numbers from Twilio
 */
export const useSearchPhoneNumbers = () => {
  return useMutation({
    mutationFn: async (params: {
      area_code?: string;
      contains?: string;
      country?: string;
      limit?: number;
    }) => {
      const { data } = await apiClient.get('/communication-credits/phone-numbers/search/', {
        params,
      });
      return data as { numbers: AvailablePhoneNumber[]; count: number };
    },
  });
};

/**
 * Hook to purchase a phone number
 */
export const usePurchasePhoneNumber = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (params: { phone_number: string; friendly_name?: string }) => {
      const { data } = await apiClient.post('/communication-credits/phone-numbers/purchase/', params);
      return data as {
        success: boolean;
        phone_number: ProxyPhoneNumber;
        balance_cents: number;
      };
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['phoneNumbers'] });
      queryClient.invalidateQueries({ queryKey: ['communicationCredits'] });
      queryClient.invalidateQueries({ queryKey: ['creditTransactions'] });
    },
  });
};

/**
 * Hook to release (delete) a phone number
 */
export const useReleasePhoneNumber = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (numberId: number) => {
      const { data } = await apiClient.delete(`/communication-credits/phone-numbers/${numberId}/`);
      return data as { success: boolean; message: string };
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['phoneNumbers'] });
      queryClient.invalidateQueries({ queryKey: ['communicationUsageStats'] });
    },
  });
};

/**
 * Hook to change a phone number to a different one
 */
export const useChangePhoneNumber = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (params: { numberId: number; new_phone_number: string; friendly_name?: string }) => {
      const { numberId, ...body } = params;
      const { data } = await apiClient.post(`/communication-credits/phone-numbers/${numberId}/change/`, body);
      return data as {
        success: boolean;
        phone_number: ProxyPhoneNumber;
        balance_cents: number;
      };
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['phoneNumbers'] });
      queryClient.invalidateQueries({ queryKey: ['communicationCredits'] });
      queryClient.invalidateQueries({ queryKey: ['creditTransactions'] });
    },
  });
};
