/* eslint-disable @typescript-eslint/brace-style */
/* eslint-disable @typescript-eslint/indent */
import { Op } from 'sequelize';
import { translate } from '../../../locales';
import { PaymentMethod, Refund } from '../../../store/models';
import { Invoice } from '../../../store/models/invoice';
import { PaymentCurrency } from '../../../store/models/payment-currency';
import { getSubscriptionStakeCancellation } from '../../subscription';
import { formatTime } from '../../time';
import { formatCurrencyInfo } from '../../util';
import { BaseSubscriptionEmailTemplate, BaseEmailTemplateType } from './base';

export interface SubscriptionCanceledEmailTemplateOptions {
  subscriptionId: string;
}

interface SubscriptionCanceledEmailTemplateContext {
  locale: string;
  productName: string;
  at: string;
  chainHost: string | undefined;
  userDid: string;
  paymentInfo: string;
  currentPeriodStart: string;
  currentPeriodEnd: string;
  duration: string;
  cancellationReason: string;
  viewSubscriptionLink: string;
  customActions: any[];
  isCreditSubscription: boolean;
}

export class SubscriptionCanceledEmailTemplate extends BaseSubscriptionEmailTemplate<SubscriptionCanceledEmailTemplateContext> {
  options: SubscriptionCanceledEmailTemplateOptions;

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

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

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

    // 获取发票和支付信息
    let invoice = null;

    let paymentMethod = await PaymentMethod.findByPk(subscription.default_payment_method_id);
    if (!paymentMethod) {
      throw new Error(`PaymentMethod not found for subscription: ${subscription.id}`);
    }

    if (!isCreditSubscription && subscription.latest_invoice_id) {
      invoice = await Invoice.findOne({
        where: { id: subscription.latest_invoice_id },
        include: [{ model: PaymentCurrency, as: 'paymentCurrency' }],
      });
      if (!invoice) {
        throw new Error(`Invoice(${subscription.latest_invoice_id}) not found`);
      }
      if (invoice.default_payment_method_id !== paymentMethod.id) {
        paymentMethod = await PaymentMethod.findByPk(invoice.default_payment_method_id);
      }
    }

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

    const at = formatTime(subscription.canceled_at * 1000);

    const periodInfo = isCreditSubscription
      ? this.formatSubscriptionPeriod(subscription.current_period_start, subscription.current_period_end, locale)
      : this.formatSubscriptionPeriod(invoice!.period_start, invoice!.period_end, locale);

    const paymentInfo = isCreditSubscription ? '' : formatCurrencyInfo(invoice!.total, paymentCurrency, paymentMethod);

    const cancellationReason = await this.getCancellationReason(subscription, paymentMethod!, paymentCurrency, locale);

    // @ts-expect-error
    const chainHost = paymentMethod?.settings?.[paymentMethod.type]?.api_host;

    return {
      locale,
      productName,
      at,
      userDid,
      chainHost,
      paymentInfo,
      currentPeriodStart: periodInfo.currentPeriodStart,
      currentPeriodEnd: periodInfo.currentPeriodEnd,
      duration: periodInfo.duration,
      cancellationReason,
      viewSubscriptionLink: links.viewSubscriptionLink,
      customActions: links.customActions,
      isCreditSubscription,
    };
  }

  private async getCancellationReason(
    subscription: any,
    paymentMethod: PaymentMethod,
    paymentCurrency: any,
    locale: string
  ): Promise<string> {
    const customerCancelRequest = subscription.cancelation_details?.reason === 'cancellation_requested';

    // 特殊取消原因处理
    if (subscription.cancelation_details?.reason === 'payment_failed') {
      return translate('notification.subscriptionCanceled.paymentFailed', locale);
    }

    if (subscription.cancelation_details?.reason === 'stake_revoked') {
      return translate('notification.subscriptionCanceled.stakeRevoked', locale);
    }

    const { stakeEnough, stakeReturn, stakeSlash, hasStake } = await getSubscriptionStakeCancellation(
      subscription,
      paymentMethod,
      paymentCurrency
    );

    if (customerCancelRequest) {
      // 客户主动取消
      if (stakeReturn && hasStake && stakeEnough) {
        return translate('notification.subscriptionCanceled.customerCanceledAndStakeReturned', locale);
      }
      return translate('notification.subscriptionCanceled.customerCanceled', locale);
    }

    // 管理员取消 - 检查退款情况
    const refund = await Refund.findOne({
      where: {
        subscription_id: subscription.id,
        type: 'refund',
        status: { [Op.not]: 'canceled' },
      },
    });

    const conditions = [
      {
        condition: refund && stakeSlash,
        key: 'notification.subscriptionCanceled.adminCanceledAndRefundedAndStakeSlashed',
      },
      {
        condition: refund && stakeReturn,
        key: 'notification.subscriptionCanceled.adminCanceledAndRefundedAndStakeReturned',
      },
      { condition: refund, key: 'notification.subscriptionCanceled.adminCanceledAndRefunded' },
      { condition: stakeReturn, key: 'notification.subscriptionCanceled.adminCanceledAndStakeReturned' },
    ];

    const matchedCondition = conditions.find((item) => item.condition);
    return matchedCondition
      ? translate(matchedCondition.key, locale)
      : translate('notification.subscriptionCanceled.adminCanceled', locale);
  }

  async getTemplate(): Promise<BaseEmailTemplateType> {
    const context = await this.getContext();
    const {
      locale,
      productName,
      at,
      userDid,
      paymentInfo,
      currentPeriodStart,
      currentPeriodEnd,
      duration,
      cancellationReason,
      viewSubscriptionLink,
      customActions,
      isCreditSubscription,
    } = context;

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

    // 支付金额字段
    const paymentAmountFields = isCreditSubscription
      ? []
      : [
          {
            type: 'text',
            data: {
              type: 'plain',
              color: '#9397A1',
              text: translate('notification.common.paymentAmount', locale),
            },
          },
          {
            type: 'text',
            data: {
              type: 'plain',
              text: paymentInfo,
            },
          },
        ];

    // 有效期字段
    const validityPeriodFields = isCreditSubscription
      ? []
      : [
          {
            type: 'text',
            data: {
              type: 'plain',
              color: '#9397A1',
              text: translate('notification.common.validityPeriod', locale),
            },
          },
          {
            type: 'text',
            data: {
              type: 'plain',
              text: `${currentPeriodStart} ~ ${currentPeriodEnd}(${duration})`,
            },
          },
        ];

    // 取消原因字段
    const cancellationReasonFields = [
      {
        type: 'text',
        data: {
          type: 'plain',
          color: '#9397A1',
          text: translate('notification.common.cancellationReason', locale),
        },
      },
      {
        type: 'text',
        data: {
          type: 'plain',
          text: cancellationReason,
        },
      },
    ];

    // 构建操作按钮
    const actions = [
      viewSubscriptionLink && {
        name: translate('notification.common.viewSubscription', locale),
        title: translate('notification.common.viewSubscription', locale),
        link: viewSubscriptionLink,
      },
      ...customActions,
    ].filter(Boolean);

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

    return template;
  }
}
