/* eslint-disable prettier/prettier */
import { getUserLocale } from '../../../integrations/blocklet/notification';
import { translate } from '../../../locales';
import { Customer, PaymentIntent, PaymentMethod, Subscription } from '../../../store/models';
import { Invoice } from '../../../store/models/invoice';
import { PaymentCurrency } from '../../../store/models/payment-currency';
import { getMainProductName } from '../../product';
import { getCustomerSubscriptionPageUrl } from '../../subscription';
import { formatTime } from '../../time';
import { formatCurrencyInfo, getExplorerLink, getSubscriptionNotificationCustomActions } from '../../util';
import type { BaseEmailTemplate, BaseEmailTemplateType } from './base';

export interface SubscriptionStakeSlashSucceededEmailTemplateOptions {
  paymentIntentId: string;
  subscriptionId: string;
  invoiceId: string;
}

interface SubscriptionStakeSlashSucceededEmailTemplateContext {
  locale: string;
  productName: string;
  at: string;

  userDid: string;
  slashInfo: string;
  slashReason: string;

  viewSubscriptionLink: string;
  viewTxHashLink: string | undefined;
  customActions: any[];
}

export class SubscriptionStakeSlashSucceededEmailTemplate
  implements BaseEmailTemplate<SubscriptionStakeSlashSucceededEmailTemplateContext> {
  options: SubscriptionStakeSlashSucceededEmailTemplateOptions;

  constructor(options: SubscriptionStakeSlashSucceededEmailTemplateOptions) {
    this.options = options;
  }

  async getContext(): Promise<SubscriptionStakeSlashSucceededEmailTemplateContext> {
    const invoice = await Invoice.findByPk(this.options.invoiceId);
    if (!invoice) {
      throw new Error(`Invoice not found: ${this.options.invoiceId}`);
    }
    if (invoice?.billing_reason !== 'slash_stake') {
      throw new Error(`Invoice billing_reason not slash_stake: ${this.options.invoiceId}`);
    }
    const paymentIntent = await PaymentIntent.findByPk(this.options.paymentIntentId);

    if (!paymentIntent) {
      throw new Error(`PaymentIntent not found: ${this.options.paymentIntentId}`);
    }
    if (paymentIntent.status !== 'succeeded') {
      throw new Error(`SlashStake not succeeded: ${this.options.paymentIntentId}`);
    }

    const subscription = await Subscription.findByPk(this.options.subscriptionId);

    if (!subscription) {
      throw new Error(`Subscription not found: ${this.options.subscriptionId}`);
    }

    if (subscription.status !== 'canceled') {
      throw new Error(`Subscription status not cancelled: ${this.options.subscriptionId}`);
    }

    const customer = await Customer.findByPk(subscription.customer_id);
    if (!customer) {
      throw new Error(`Customer not found: ${subscription.customer_id}`);
    }

    const paymentCurrency = (await PaymentCurrency.findOne({
      where: {
        id: subscription.currency_id,
      },
    })) as PaymentCurrency;

    const userDid: string = customer.did;
    const locale = await getUserLocale(userDid);
    const productName = await getMainProductName(this.options.subscriptionId);
    const at: string = formatTime(paymentIntent.created_at);

    const paymentMethod: PaymentMethod | null = await PaymentMethod.findByPk(paymentIntent.payment_method_id);

    const slashInfo: string = formatCurrencyInfo(paymentIntent?.amount_received || '0', paymentCurrency, paymentMethod);

    // @ts-expect-error
    const chainHost: string | undefined = paymentMethod?.settings?.[paymentMethod.type]?.api_host;
    const viewSubscriptionLink = getCustomerSubscriptionPageUrl({
      subscriptionId: this.options.subscriptionId,
      locale,
      userDid,
    });

    // @ts-expect-error
    const txHash: string | undefined = paymentIntent?.payment_details?.[paymentMethod.type]?.tx_hash;
    const viewTxHashLink: string | undefined =
      txHash &&
      getExplorerLink({
        type: 'tx',
        did: txHash,
        chainHost,
      });

    const slashReason = subscription?.cancelation_details?.slash_reason || 'admin slash';

    const customActions = getSubscriptionNotificationCustomActions(
      subscription,
      'subscription.stake.slash.succeeded',
      locale
    );

    return {
      locale,
      productName,
      at,

      userDid,
      slashInfo,
      slashReason,
      viewSubscriptionLink,
      viewTxHashLink,
      customActions,
    };
  }

  async getTemplate(): Promise<BaseEmailTemplateType> {
    const {
      locale,
      productName,
      at,

      userDid,
      slashInfo,
      slashReason,
      viewSubscriptionLink,
      viewTxHashLink,
      customActions,
    } = await this.getContext();

    const template: BaseEmailTemplateType = {
      title: `${translate('notification.subscriptionStakeSlashSucceeded.title', locale, {
        productName,
      })}`,
      body: `${translate('notification.subscriptionStakeSlashSucceeded.body', locale, {
        at,
        productName,
        slashInfo,
      })}`,
      attachments: [
        {
          type: 'section',
          fields: [
            {
              type: 'text',
              data: {
                type: 'plain',
                color: '#9397A1',
                text: translate('notification.common.account', locale),
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                text: userDid,
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                color: '#9397A1',
                text: translate('notification.common.product', locale),
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                text: productName,
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                color: '#9397A1',
                text: translate('notification.common.slashAmount', locale),
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                text: slashInfo,
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                color: '#9397A1',
                text: translate('notification.common.slashReason', locale),
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                text: slashReason,
              },
            },
          ],
        },
      ],
      // @ts-ignore
      actions: [
        {
          name: translate('notification.common.viewSubscription', locale),
          title: translate('notification.common.viewSubscription', locale),
          link: viewSubscriptionLink,
        },
        viewTxHashLink && {
          name: translate('notification.common.viewTxHash', locale),
          title: translate('notification.common.viewTxHash', locale),
          link: viewTxHashLink as string,
        },
        ...customActions,
      ].filter(Boolean),
    };

    return template;
  }
}
