/* eslint-disable @typescript-eslint/brace-style */
import prettyMsI18n from 'pretty-ms-i18n';

import { getUserLocale } from '../../../integrations/blocklet/notification';
import { translate } from '../../../locales';
import { Customer, Subscription } from '../../../store/models';
import { getMainProductName } from '../../product';
import { getCustomerSubscriptionPageUrl } from '../../subscription';
import { formatTime, getPrettyMsI18nLocale } from '../../time';
import { getSubscriptionNotificationCustomActions } from '../../util';
import type { BaseEmailTemplate, BaseEmailTemplateType } from './base';

export interface SubscriptionSlippageWarningEmailTemplateOptions {
  subscriptionId: string;
  currentRate: string;
  minAcceptableRate: string;
  renewalTime: number; // Unix timestamp in seconds
}

interface SubscriptionSlippageWarningEmailTemplateContext {
  locale: string;
  productName: string;
  userDid: string;
  currentRate: string;
  minAcceptableRate: string;
  renewalTime: string;
  timeUntilRenewal: string;
  viewSubscriptionLink: string;
  customActions: any[];
}

export class SubscriptionSlippageWarningEmailTemplate implements BaseEmailTemplate<SubscriptionSlippageWarningEmailTemplateContext> {
  options: SubscriptionSlippageWarningEmailTemplateOptions;

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

  async getContext(): Promise<SubscriptionSlippageWarningEmailTemplateContext> {
    const subscription = await Subscription.findByPk(this.options.subscriptionId);
    if (!subscription) {
      throw new Error(`Subscription not found: ${this.options.subscriptionId}`);
    }

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

    const userDid = customer.did;
    const locale = await getUserLocale(userDid);
    const productName = await getMainProductName(subscription.id);

    const renewalTimeMs = this.options.renewalTime * 1000;
    const renewalTime = formatTime(renewalTimeMs);
    const timeUntilRenewal = prettyMsI18n(renewalTimeMs - Date.now(), {
      locale: getPrettyMsI18nLocale(locale),
    });

    const viewSubscriptionLink = getCustomerSubscriptionPageUrl({
      subscriptionId: subscription.id,
      locale,
      userDid,
    });

    const customActions = getSubscriptionNotificationCustomActions(
      subscription,
      'subscription.slippage_warning',
      locale
    );

    return {
      locale,
      productName,
      userDid,
      currentRate: this.options.currentRate,
      minAcceptableRate: this.options.minAcceptableRate,
      renewalTime,
      timeUntilRenewal,
      viewSubscriptionLink,
      customActions,
    };
  }

  async getTemplate(): Promise<BaseEmailTemplateType> {
    const {
      locale,
      productName,
      userDid,
      currentRate,
      minAcceptableRate,
      renewalTime,
      timeUntilRenewal,
      viewSubscriptionLink,
      customActions,
    } = await this.getContext();

    const template: BaseEmailTemplateType = {
      title: translate('notification.subscriptionSlippageWarning.title', locale, {
        productName,
      }),
      body: translate('notification.subscriptionSlippageWarning.body', locale, {
        productName,
        currentRate,
        minAcceptableRate,
        timeUntilRenewal,
      }),
      // @ts-ignore
      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.subscriptionSlippageWarning.renewalTime', locale),
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                text: renewalTime,
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                color: '#9397A1',
                text: translate('notification.subscriptionSlippageWarning.currentRate', locale),
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                color: '#FF6600',
                text: currentRate,
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                color: '#9397A1',
                text: translate('notification.subscriptionSlippageWarning.minAcceptableRate', locale),
              },
            },
            {
              type: 'text',
              data: {
                type: 'plain',
                text: minAcceptableRate,
              },
            },
          ],
        },
      ],
      // @ts-ignore
      actions: [
        {
          name: translate('notification.common.viewSubscription', locale),
          title: translate('notification.common.viewSubscription', locale),
          link: viewSubscriptionLink,
        },
        {
          name: translate('notification.subscriptionSlippageWarning.adjustSlippage', locale),
          title: translate('notification.subscriptionSlippageWarning.adjustSlippage', locale),
          link: viewSubscriptionLink,
        },
        ...customActions,
      ].filter(Boolean),
    };

    return template;
  }
}
