import { sendToRelay } from '@blocklet/sdk/service/notification';
import { publish } from '@blocklet/sdk/service/eventbus';
import type {
  CheckoutSession,
  Invoice,
  PaymentIntent,
  Subscription,
  Refund,
  CreditGrant,
  Customer,
} from '../store/models';
import { events } from './event';

export function broadcast(eventName: string, data: any, extraParams?: Record<string, any>) {
  sendToRelay('events', eventName, data).catch((err: any) => {
    console.error(`Failed to broadcast event via relay: ${eventName}`, err);
  });

  publish(eventName, {
    id: data.id,
    time: new Date().toISOString(),
    data: {
      object: data,
      extraParams,
    },
  }).catch((err: any) => {
    console.error(`Failed to publish event via EventBus: ${eventName}`, err);
  });
}

export function initEventBroadcast() {
  // Checkout Events
  events.on('checkout.session.completed', (data: CheckoutSession, extraParams?: Record<string, any>) => {
    broadcast('checkout.session.completed', data, extraParams);
  });
  events.on('checkout.session.nft_minted', (data: CheckoutSession, extraParams?: Record<string, any>) => {
    broadcast('checkout.session.nft_minted', data, extraParams);
  });

  // Payment Events
  events.on('payment_intent.succeeded', (data: PaymentIntent, extraParams?: Record<string, any>) => {
    broadcast('payment_intent.succeeded', data, extraParams);
  });
  events.on('payment_intent.payment_failed', (data: PaymentIntent, extraParams?: Record<string, any>) => {
    broadcast('payment_intent.payment_failed', data, extraParams);
  });
  events.on('invoice.paid', (data: Invoice, extraParams?: Record<string, any>) => {
    broadcast('invoice.paid', data, extraParams);
  });
  events.on('refund.succeeded', (data: Refund, extraParams?: Record<string, any>) => {
    broadcast('refund.succeeded', data, extraParams);
  });

  // Subscription Events
  events.on('customer.subscription.created', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.created', data, extraParams);
  });
  events.on('customer.subscription.started', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.started', data, extraParams);
  });
  events.on('customer.subscription.renewed', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.renewed', data, extraParams);
  });
  events.on('customer.subscription.upgraded', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.upgraded', data, extraParams);
  });
  events.on('customer.subscription.updated', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.updated', data, extraParams);
  });
  events.on('customer.subscription.deleted', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.deleted', data, extraParams);
  });
  events.on('customer.subscription.paused', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.paused', data, extraParams);
  });
  events.on('customer.subscription.resumed', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.resumed', data, extraParams);
  });
  events.on('customer.subscription.past_due', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.past_due', data, extraParams);
  });
  events.on('customer.subscription.recovered', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.recovered', data, extraParams);
  });
  events.on('customer.subscription.renew_failed', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.renew_failed', data, extraParams);
  });

  // Trial Events
  events.on('customer.subscription.trial_start', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.trial_start', data, extraParams);
  });
  events.on('customer.subscription.trial_will_end', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.trial_will_end', data, extraParams);
  });
  events.on('customer.subscription.trial_end', (data: Subscription, extraParams?: Record<string, any>) => {
    broadcast('customer.subscription.trial_end', data, extraParams);
  });

  // notification events
  events.on('manual.notification', (data: Record<string, any>) => {
    broadcast('manual.notification', data);
  });

  // credit
  events.on('customer.credit_grant.granted', (data: CreditGrant, extraParams?: Record<string, any>) => {
    broadcast('customer.credit_grant.granted', data, extraParams);
  });

  events.on('customer.credit.low_balance', (data: Customer, extraParams?: Record<string, any>) => {
    broadcast('customer.credit.low_balance', data, extraParams);
  });
  events.on('customer.credit_grant.depleted', (data: CreditGrant, extraParams?: Record<string, any>) => {
    broadcast('customer.credit_grant.depleted', data, extraParams);
  });
  events.on('customer.credit.insufficient', (data: Customer, extraParams?: Record<string, any>) => {
    broadcast('customer.credit.insufficient', data, extraParams);
  });
}
