/* eslint-disable @typescript-eslint/brace-style */
/* eslint-disable @typescript-eslint/indent */
import { BN } from '@ocap/util';
import { withQuery } from 'ufo';
import { getUserLocale } from '../../../integrations/blocklet/notification';
import { translate } from '../../../locales';
import { Customer, PaymentCurrency, Subscription } from '../../../store/models';
import { getMainProductName } from '../../product';
import { getCustomerSubscriptionPageUrl } from '../../subscription';
import { formatTime } from '../../time';
import type { BaseEmailTemplate, BaseEmailTemplateType } from './base';
import { formatCreditAmount, formatTokenAmount, getConnectQueryParam, getCustomerIndexUrl } from '../../util';
import { getRechargePaymentUrl } from '../../currency';

export interface CustomerCreditInsufficientEmailTemplateOptions {
  customerId: string;
  currencyId: string;
  meterName: string;
  meterEventName: string;
  requiredAmount: string;
  availableAmount: string;
  pendingAmount: string;
  subscriptionId?: string;
}

interface CustomerCreditInsufficientEmailTemplateContext {
  locale: string;
  userDid: string;
  currencySymbol: string;
  meterEventName: string;
  meterName: string;
  pendingAmount: string;
  hasPendingAmount: boolean;
  productName?: string;
  viewSubscriptionLink?: string;
  rechargeUrl: string | null;
  at: string;
}

export class CustomerCreditInsufficientEmailTemplate implements BaseEmailTemplate<CustomerCreditInsufficientEmailTemplateContext> {
  options: CustomerCreditInsufficientEmailTemplateOptions;

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

  async getContext(): Promise<CustomerCreditInsufficientEmailTemplateContext> {
    const customer = await Customer.findByPk(this.options.customerId);
    if (!customer) {
      throw new Error(`Customer not found: ${this.options.customerId}`);
    }

    const paymentCurrency = await PaymentCurrency.scope('withRechargeConfig').findByPk(this.options.currencyId);
    if (!paymentCurrency) {
      throw new Error(`PaymentCurrency not found: ${this.options.currencyId}`);
    }

    const userDid = customer.did;
    const locale = await getUserLocale(userDid);
    const currencySymbol = paymentCurrency.symbol;
    const at = formatTime(Date.now());

    // 如果有订阅ID，获取订阅信息
    let productName: string | undefined;
    let viewSubscriptionLink: string | undefined;

    if (this.options.subscriptionId) {
      const subscription = await Subscription.findByPk(this.options.subscriptionId);
      if (subscription) {
        productName = await getMainProductName(subscription.id);
        viewSubscriptionLink = getCustomerSubscriptionPageUrl({
          subscriptionId: subscription.id,
          locale,
          userDid,
        });
      }
    }

    let rechargeUrl: string | null = await getRechargePaymentUrl(paymentCurrency);
    if (rechargeUrl) {
      rechargeUrl = withQuery(rechargeUrl, { ...getConnectQueryParam({ userDid }) });
    }

    const pendingAmountValue = this.options.pendingAmount || '0';
    const pendingAmountBN = new BN(pendingAmountValue);
    const formattedPending = formatTokenAmount(pendingAmountValue, paymentCurrency.decimal) || '0';

    return {
      locale,
      userDid,
      currencySymbol,
      meterName: this.options.meterName,
      meterEventName: this.options.meterEventName,
      pendingAmount: formatCreditAmount(formattedPending, currencySymbol),
      hasPendingAmount: pendingAmountBN.gt(new BN(0)),
      productName,
      viewSubscriptionLink,
      rechargeUrl,
      at,
    };
  }

  async getTemplate(): Promise<BaseEmailTemplateType> {
    const context = await this.getContext();
    const {
      locale,
      userDid,
      meterName,
      pendingAmount,
      hasPendingAmount,
      productName,
      viewSubscriptionLink,
      rechargeUrl,
    } = context;

    // 构建基础字段
    const baseFields = [
      {
        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: locale === 'zh' ? '服务项目' : 'Service',
        },
      },
      {
        type: 'text',
        data: {
          type: 'plain',
          text: meterName,
        },
      },
    ];

    // 产品信息字段（如果有订阅）
    const productFields = productName
      ? [
          {
            type: 'text',
            data: {
              type: 'plain',
              color: '#9397A1',
              text: translate('notification.common.product', locale),
            },
          },
          {
            type: 'text',
            data: {
              type: 'plain',
              text: productName,
            },
          },
        ]
      : [];

    const pendingFields = hasPendingAmount
      ? [
          {
            type: 'text',
            data: {
              type: 'plain',
              color: '#9397A1',
              text: translate('notification.creditInsufficient.pendingAmount', locale),
            },
          },
          {
            type: 'text',
            data: {
              type: 'plain',
              color: '#FF0000',
              text: `${pendingAmount}`,
            },
          },
        ]
      : [];

    // 构建操作按钮
    const customerIndexUrl = getCustomerIndexUrl({
      locale,
      userDid,
    });

    const actions = [
      rechargeUrl && {
        name: translate('notification.common.reloadCredits', locale),
        title: translate('notification.common.reloadCredits', locale),
        link: rechargeUrl,
      },
      viewSubscriptionLink && {
        name: translate('notification.common.viewSubscription', locale),
        title: translate('notification.common.viewSubscription', locale),
        link: viewSubscriptionLink,
      },
      {
        name: translate('notification.common.manageCredit', locale),
        title: translate('notification.common.manageCredit', locale),
        link: customerIndexUrl,
      },
    ].filter(Boolean);

    // 构建标题和正文
    let body: string;

    const title = translate('notification.creditInsufficient.exhaustedTitle', locale);
    if (productName) {
      body = translate('notification.creditInsufficient.exhaustedBodyWithSubscription', locale, {
        subscriptionName: productName,
      });
    } else {
      body = translate('notification.creditInsufficient.exhaustedBodyWithoutSubscription', locale);
    }

    const template: BaseEmailTemplateType = {
      title,
      body,
      attachments: [
        {
          type: 'section',
          fields: [...baseFields, ...productFields, ...pendingFields].filter(Boolean),
        },
      ],
      // @ts-ignore
      actions,
    };

    return template;
  }
}
