/* eslint-disable @typescript-eslint/brace-style */
/* eslint-disable @typescript-eslint/indent */
import { fromUnitToToken, toDid } from '@ocap/util';
import logger from '../../logger';
import { translate } from '../../../locales';
import { CheckoutSession, NFTMintChainType, Invoice, NftMintItem, PaymentIntent } from '../../../store/models';
import { PaymentCurrency } from '../../../store/models/payment-currency';
import { formatTime } from '../../time';
import { formatCurrencyInfo, getExplorerLink } from '../../util';
import { BaseSubscriptionEmailTemplate, BaseEmailTemplateType } from './base';

export interface SubscriptionRenewedEmailTemplateOptions {
  subscriptionId: string;
  invoiceId?: string;
}

interface SubscriptionRenewedEmailTemplateContext {
  locale: string;
  productName: string;
  at: string;
  nftMintItem: NftMintItem | undefined;
  userDid: string;
  paymentInfo: string;
  amountPaid: number;
  currentPeriodStart: string;
  currentPeriodEnd: string;
  duration: string;
  viewSubscriptionLink: string;
  viewInvoiceLink: string;
  viewTxHashLink: string | undefined;
  invoice: Invoice;
  customActions: any[];
  isCreditSubscription: boolean;
}

export class SubscriptionRenewedEmailTemplate extends BaseSubscriptionEmailTemplate<SubscriptionRenewedEmailTemplateContext> {
  options: SubscriptionRenewedEmailTemplateOptions;

  constructor(options: SubscriptionRenewedEmailTemplateOptions) {
    super();
    this.options = options;
  }

  async getContext(): Promise<SubscriptionRenewedEmailTemplateContext> {
    // 获取基础订阅数据
    const basicData = await this.getSubscriptionBasicData(this.options.subscriptionId);
    const { subscription, userDid, locale, productName, isCreditSubscription } = basicData;

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

    // 获取发票信息
    const invoice = (
      this.options.invoiceId
        ? await Invoice.findByPk(this.options.invoiceId)
        : await Invoice.findByPk(subscription.latest_invoice_id)
    ) as Invoice;

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

    // 获取支付信息
    const paymentInfoResult = await this.getPaymentInfo(
      subscription,
      paymentCurrency,
      isCreditSubscription,
      invoice?.id
    );

    // 获取链接
    const links = this.generateSubscriptionLinks(
      subscription,
      locale,
      userDid,
      'customer.subscription.renewed',
      invoice?.id,
      isCreditSubscription
    );

    // 获取 NFT 信息
    const nftInfo = await this.getNftMintInfo(subscription.id);

    // 计算支付金额
    const amountPaid = +fromUnitToToken(invoice.total, paymentCurrency.decimal);
    const formattedPaymentInfo = formatCurrencyInfo(invoice.total, paymentCurrency, paymentInfoResult.paymentMethod);

    // 格式化时间信息
    const periodInfo = this.formatSubscriptionPeriod(invoice.period_start, invoice.period_end, locale);

    // 获取交易哈希链接
    const checkoutSession = await CheckoutSession.findBySubscriptionId(subscription.id);
    const paymentIntent = await PaymentIntent.findByPk(invoice.payment_intent_id);
    const txHash: string | undefined =
      paymentIntent?.payment_details?.[checkoutSession?.nft_mint_details?.type as NFTMintChainType]?.tx_hash;

    const chainHost: string | undefined =
      paymentInfoResult.paymentMethod?.settings?.[checkoutSession?.nft_mint_details?.type as NFTMintChainType]
        ?.api_host;

    const viewTxHashLink: string | undefined =
      nftInfo.hasNft && txHash ? getExplorerLink({ type: 'tx', did: txHash, chainHost }) : undefined;

    return {
      locale,
      productName,
      at: formatTime((invoice?.status_transitions?.paid_at ?? Math.floor(Date.now() / 1000)) * 1000),
      nftMintItem: nftInfo.nftMintItem,
      userDid,
      paymentInfo: formattedPaymentInfo,
      amountPaid,
      currentPeriodStart: periodInfo.currentPeriodStart,
      currentPeriodEnd: periodInfo.currentPeriodEnd,
      duration: periodInfo.duration,
      viewSubscriptionLink: links.viewSubscriptionLink,
      viewInvoiceLink: links.viewInvoiceLink!,
      viewTxHashLink,
      invoice,
      customActions: links.customActions,
      isCreditSubscription,
    };
  }

  async getTemplate(): Promise<BaseEmailTemplateType | null> {
    const context = await this.getContext();
    const {
      locale,
      productName,
      at,
      nftMintItem,
      userDid,
      paymentInfo,
      amountPaid,
      currentPeriodStart,
      currentPeriodEnd,
      duration,
      viewSubscriptionLink,
      viewInvoiceLink,
      viewTxHashLink,
      invoice,
      customActions,
      isCreditSubscription,
    } = context;

    if (invoice.total === '0') {
      logger.info('Invoice amount is 0, skipping renewed notification');
      return null;
    }

    // 构建基础字段
    const commonFields = this.buildCommonFields(userDid, productName, locale);

    // 构建支付金额字段（包含特殊处理）
    const paymentFields = isCreditSubscription
      ? []
      : [
          {
            type: 'text',
            data: {
              type: 'plain',
              color: '#9397A1',
              text: translate('notification.common.paymentAmount', locale),
            },
          },
          {
            type: 'text',
            data: {
              type: 'plain',
              text: `${paymentInfo}${
                amountPaid === 0 ? ` (${translate('notification.subscriptionRenewed.noExpenseIncurred', locale)})` : ''
              }`,
            },
          },
        ];

    const periodFields = this.buildPeriodField(
      currentPeriodStart,
      currentPeriodEnd,
      duration,
      locale,
      isCreditSubscription
    );

    // NFT 地址字段
    const nftFields = nftMintItem
      ? [
          {
            type: 'text',
            data: {
              type: 'plain',
              color: '#9397A1',
              text: translate('notification.common.nftAddress', locale),
            },
          },
          {
            type: 'text',
            data: {
              type: 'plain',
              text: toDid(nftMintItem.address),
            },
          },
        ]
      : [];

    // 构建操作按钮
    const actions = this.buildCommonActions(viewSubscriptionLink, viewInvoiceLink, locale, isCreditSubscription, [
      viewTxHashLink && {
        name: translate('notification.common.viewTxHash', locale),
        title: translate('notification.common.viewTxHash', locale),
        link: viewTxHashLink as string,
      },
      ...customActions,
    ]);

    const template: BaseEmailTemplateType = {
      title: translate('notification.subscriptionRenewed.title', locale, { productName }),
      body: translate('notification.subscriptionRenewed.body', locale, { at, productName }),
      // @ts-expect-error
      attachments: [
        {
          type: 'section',
          fields: [...commonFields, ...paymentFields, ...periodFields, ...nftFields].filter(Boolean),
        },
      ].filter(Boolean),
      // @ts-ignore
      actions: actions.filter(Boolean),
    };

    return template;
  }
}
