import { getSupabaseServerClient } from '@kit/supabase/server-client';

import type { AccountBalanceEntry } from '../../types/account-balance-entry';

export type AccountBalanceSummary = {
  totalBalance: number;
  expiringSoon: number;
  recentEntries: AccountBalanceEntry[];
};

export class AccountBalanceService {
  private supabase: ReturnType<typeof getSupabaseServerClient>;

  constructor() {
    this.supabase = getSupabaseServerClient();
  }

  /**
   * Get the current balance for a specific account
   */
  async getAccountBalance(accountId: string): Promise<number> {
    const { data, error } = await this.supabase
      .schema('medreport')
      .rpc('get_account_balance', {
        p_account_id: accountId,
      });

    if (error) {
      console.error('Error getting account balance:', error);
      throw new Error('Failed to get account balance');
    }

    return data || 0;
  }

  /**
   * Get balance entries for an account with pagination
   */
  async getAccountBalanceEntries(
    accountId: string,
    options: {
      limit?: number;
      offset?: number;
      entryType?: string;
      includeInactive?: boolean;
    } = {},
  ): Promise<{
    entries: AccountBalanceEntry[];
    total: number;
  }> {
    const {
      limit = 50,
      offset = 0,
      entryType,
      includeInactive = false,
    } = options;

    let query = this.supabase
      .schema('medreport')
      .from('account_balance_entries')
      .select('*', { count: 'exact' })
      .eq('account_id', accountId)
      .order('created_at', { ascending: false })
      .range(offset, offset + limit - 1);

    if (!includeInactive) {
      query = query.eq('is_active', true);
    }

    if (entryType) {
      query = query.eq('entry_type', entryType);
    }

    const { data, error, count } = await query;

    if (error) {
      console.error('Error getting account balance entries:', error);
      throw new Error('Failed to get account balance entries');
    }

    return {
      entries: data || [],
      total: count || 0,
    };
  }

  /**
   * Get balance summary for dashboard display
   */
  async getBalanceSummary(accountId: string): Promise<AccountBalanceSummary> {
    const [balance, entries] = await Promise.all([
      this.getAccountBalance(accountId),
      this.getAccountBalanceEntries(accountId, { limit: 5 }),
    ]);

    // Calculate expiring balance (next 30 days)
    const thirtyDaysFromNow = new Date();
    thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);

    const { data: expiringData, error: expiringError } = await this.supabase
      .schema('medreport')
      .from('account_balance_entries')
      .select('amount')
      .eq('account_id', accountId)
      .eq('is_active', true)
      .not('expires_at', 'is', null)
      .lte('expires_at', thirtyDaysFromNow.toISOString());

    if (expiringError) {
      console.error('Error getting expiring balance:', expiringError);
    }

    const expiringSoon =
      expiringData?.reduce((sum, entry) => sum + (entry.amount || 0), 0) || 0;

    return {
      totalBalance: balance,
      expiringSoon,
      recentEntries: entries.entries,
    };
  }

  async processPeriodicBenefitDistributions(): Promise<void> {
    console.info('Processing periodic benefit distributions...');
    const { error } = await this.supabase
      .schema('medreport')
      .rpc('process_periodic_benefit_distributions');
    if (error) {
      console.error('Error processing periodic benefit distributions:', error);
      throw new Error('Failed to process periodic benefit distributions');
    }
    console.info('Periodic benefit distributions processed successfully');
  }
}
