/* eslint-disable no-await-in-loop */

import { env } from '@blocklet/sdk/lib/env';

import Stripe from 'stripe';
import logger from '../../libs/logger';
import { STRIPE_API_VERSION, STRIPE_ENDPOINT, STRIPE_EVENTS } from '../../libs/util';
import { PaymentMethod } from '../../store/models';

// register stripe webhooks on start/create if there are any stripe payment methods
export async function ensureWebhookRegistered() {
  const stripeMethods = await PaymentMethod.findAll({ where: { type: 'stripe' } });
  for (const method of stripeMethods) {
    const settings = PaymentMethod.decryptSettings(method.settings);
    if (!settings.stripe) {
      // eslint-disable-next-line no-continue
      continue;
    }

    const stripe = method.getStripeClient();
    const { data } = await stripe.webhookEndpoints.list({ limit: 100 });

    const exist = data.find((webhook) => webhook.metadata?.appPid === env.appPid);
    if (exist) {
      await stripe.webhookEndpoints.update(exist.id, {
        url: STRIPE_ENDPOINT,
        description: env.appName,
        enabled_events: STRIPE_EVENTS,
        disabled: false,
      });
      logger.info('stripe webhook updated');
    } else {
      const result = await stripe.webhookEndpoints.create({
        url: STRIPE_ENDPOINT,
        description: env.appName,
        enabled_events: STRIPE_EVENTS,
        api_version: STRIPE_API_VERSION,
        metadata: {
          appPid: env.appPid,
        },
      });
      logger.info('stripe webhook created');

      if (result.secret) {
        settings.stripe.webhook_signing_secret = result.secret;
        await method.update({ settings: PaymentMethod.encryptSettings(settings) });
        logger.info('stripe webhook signing secret updated');
      }
    }
  }
}

// validate stripe keys
export async function validateStripeKeys(secretKey: string) {
  try {
    const stripe = new Stripe(secretKey, { apiVersion: STRIPE_API_VERSION });
    await stripe.accounts.retrieve();
    return true;
  } catch (error) {
    logger.error('Invalid Stripe API keys:', error);
    return false;
  }
}

// cleanup old stripe webhook
export async function cleanupStripeWebhook(stripe: Stripe) {
  try {
    const { data } = await stripe.webhookEndpoints.list({ limit: 100 });
    const existingWebhook = data.find((webhook) => webhook.metadata?.appPid === env.appPid);
    if (existingWebhook) {
      await stripe.webhookEndpoints.del(existingWebhook.id);
      logger.info('stripe webhook deleted', { id: existingWebhook.id });
    }
  } catch (err) {
    logger.error('Failed to clean old webhook:', err);
  }
}
