import type { TNotification, TNotificationInput } from '@blocklet/sdk/lib/types/notification';
import prettyMsI18n from 'pretty-ms-i18n';
import { getUserLocale } from '../../../integrations/blocklet/notification';
import { translate } from '../../../locales';
import {
  Customer,
  PaymentMethod,
  Subscription,
  PaymentCurrency,
  Invoice,
  CheckoutSession,
  NFTMintChainType,
  NftMintItem,
} from '../../../store/models';
import { getMainProductName } from '../../product';
import { getCustomerSubscriptionPageUrl } from '../../subscription';
import { getCustomerInvoicePageUrl } from '../../invoice';
import { formatTime, getPrettyMsI18nLocale } from '../../time';
import { formatCurrencyInfo, getSubscriptionNotificationCustomActions } from '../../util';

export type BaseEmailTemplateType = TNotificationInput | TNotification;

export type BaseEmailTemplateContext = {
  userDid: string;
};

export interface BaseEmailTemplate<C = BaseEmailTemplateContext> {
  getTemplate(): Promise<BaseEmailTemplateType | null>;
  getContext(): Promise<C>;
  options: Record<string, any>;
}

// 基础订阅数据接口
export interface BaseSubscriptionData {
  subscription: Subscription;
  customer: Customer;
  userDid: string;
  locale: string;
  productName: string;
  paymentCurrency: PaymentCurrency;
  isCreditSubscription: boolean;
}

// 链接生成结果接口
export interface SubscriptionLinks {
  viewSubscriptionLink: string;
  viewInvoiceLink?: string;
  viewTxHashLink?: string;
  customActions: any[];
}

// NFT 信息接口
export interface NftInfo {
  hasNft: boolean;
  nftMintItem?: NftMintItem;
  chainHost?: string;
}

// 支付信息接口
export interface PaymentInfo {
  paymentMethod?: PaymentMethod;
  paymentInfo: string;
  invoice?: Invoice;
}

// 抽象基类
export abstract class BaseSubscriptionEmailTemplate<C extends BaseEmailTemplateContext = BaseEmailTemplateContext>
  // eslint-disable-next-line prettier/prettier
  implements BaseEmailTemplate<C> {
  abstract options: Record<string, any>;

  abstract getContext(): Promise<C>;
  abstract getTemplate(): Promise<BaseEmailTemplateType | null>;

  // 1. 基础数据获取逻辑
  protected async getSubscriptionBasicData(subscriptionId: string): Promise<BaseSubscriptionData> {
    const subscription = await this.validateSubscriptionExists(subscriptionId);
    const customer = await this.validateCustomerExists(subscription.customer_id);

    const userDid = customer.did;
    const locale = await getUserLocale(userDid);
    const productName = await getMainProductName(subscription.id);
    const paymentCurrency = (await PaymentCurrency.findOne({
      where: { id: subscription.currency_id },
    })) as PaymentCurrency;

    const isCreditSubscription = await this.isCreditSubscription(subscription, paymentCurrency);

    return {
      subscription,
      customer,
      userDid,
      locale,
      productName,
      paymentCurrency,
      isCreditSubscription,
    };
  }

  // 2. Credit 订阅检测
  protected async isCreditSubscription(
    subscription: Subscription,
    paymentCurrency?: PaymentCurrency
  ): Promise<boolean> {
    let currency = paymentCurrency;
    if (!currency) {
      currency = (await PaymentCurrency.findOne({
        where: { id: subscription.currency_id },
      })) as PaymentCurrency;
    }

    const isConsumesCredit = await subscription.isConsumesCredit();
    return isConsumesCredit && currency.type === 'credit';
  }

  // 3. 支付信息处理（根据 Credit 订阅条件处理）
  protected async getPaymentInfo(
    subscription: Subscription,
    paymentCurrency: PaymentCurrency,
    isCreditSubscription: boolean,
    invoiceId?: string
  ): Promise<PaymentInfo> {
    const paymentMethod = (await PaymentMethod.findByPk(paymentCurrency.payment_method_id)) as PaymentMethod;
    if (isCreditSubscription) {
      // Credit 订阅不需要显示支付信息
      return {
        paymentInfo: '',
        paymentMethod,
        invoice: undefined,
      };
    }

    // 非 Credit 订阅需要获取发票和支付信息
    const invoice = invoiceId
      ? await Invoice.findByPk(invoiceId)
      : await Invoice.findByPk(subscription.latest_invoice_id);

    if (!invoice) {
      throw new Error(`Invoice not found for subscription: ${subscription.id}`);
    }

    const paymentInfo = formatCurrencyInfo(invoice.total, paymentCurrency, paymentMethod);

    return {
      paymentMethod,
      paymentInfo,
      invoice,
    };
  }

  // 4. 链接生成逻辑
  protected generateSubscriptionLinks(
    subscription: Subscription,
    locale: string,
    userDid: string,
    actionType: string,
    invoiceId?: string,
    isCreditSubscription: boolean = false
  ): SubscriptionLinks {
    const viewSubscriptionLink = getCustomerSubscriptionPageUrl({
      subscriptionId: subscription.id,
      locale,
      userDid,
    });

    // Credit 订阅不显示发票链接
    const viewInvoiceLink =
      !isCreditSubscription && invoiceId
        ? getCustomerInvoicePageUrl({
            invoiceId,
            userDid,
            locale,
          })
        : undefined;

    const customActions = getSubscriptionNotificationCustomActions(subscription, actionType, locale);

    return {
      viewSubscriptionLink,
      viewInvoiceLink,
      customActions,
    };
  }

  // 5. NFT 信息获取
  protected async getNftMintInfo(subscriptionId: string): Promise<NftInfo> {
    const checkoutSession = await CheckoutSession.findBySubscriptionId(subscriptionId);
    const hasNft = checkoutSession?.nft_mint_status === 'minted';

    const nftMintItem = hasNft
      ? checkoutSession?.nft_mint_details?.[checkoutSession?.nft_mint_details?.type as NFTMintChainType]
      : undefined;

    return {
      hasNft,
      nftMintItem,
    };
  }

  // 6. 时间和持续时间处理
  protected formatSubscriptionPeriod(
    startTime: number,
    endTime: number,
    locale: string
  ): {
    currentPeriodStart: string;
    currentPeriodEnd: string;
    duration: string;
  } {
    const currentPeriodStart = formatTime(startTime * 1000);
    const currentPeriodEnd = formatTime(endTime * 1000);
    const duration = prettyMsI18n(new Date(currentPeriodEnd).getTime() - new Date(currentPeriodStart).getTime(), {
      locale: getPrettyMsI18nLocale(locale),
    });

    return {
      currentPeriodStart,
      currentPeriodEnd,
      duration,
    };
  }

  // 7. 模板字段构建 - 基础字段
  protected buildCommonFields(userDid: string, productName: string, locale: string): any[] {
    return [
      {
        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,
        },
      },
    ];
  }

  // 支付金额字段（Credit 订阅时不显示）
  protected buildPaymentField(paymentInfo: string, locale: string, isCreditSubscription: boolean): any[] {
    if (isCreditSubscription) {
      return [];
    }

    return [
      {
        type: 'text',
        data: {
          type: 'plain',
          color: '#9397A1',
          text: translate('notification.common.paymentAmount', locale),
        },
      },
      {
        type: 'text',
        data: {
          type: 'plain',
          text: paymentInfo,
        },
      },
    ];
  }

  // 有效期字段（Credit 订阅时不显示）
  protected buildPeriodField(
    currentPeriodStart: string,
    currentPeriodEnd: string,
    duration: string,
    locale: string,
    isCreditSubscription: boolean
  ): any[] {
    if (isCreditSubscription) {
      return [];
    }

    return [
      {
        type: 'text',
        data: {
          type: 'plain',
          color: '#9397A1',
          text: translate('notification.common.validityPeriod', locale),
        },
      },
      {
        type: 'text',
        data: {
          type: 'plain',
          text: `${currentPeriodStart} ~ ${currentPeriodEnd}(${duration})`,
        },
      },
    ];
  }

  // 8. 模板操作按钮构建
  protected buildCommonActions(
    viewSubscriptionLink: string,
    viewInvoiceLink: string | undefined,
    locale: string,
    isCreditSubscription: boolean,
    customActions: any[] = []
  ): any[] {
    const actions = [
      {
        name: translate('notification.common.viewSubscription', locale),
        title: translate('notification.common.viewSubscription', locale),
        link: viewSubscriptionLink,
      },
    ];

    // Credit 订阅不显示发票链接
    if (!isCreditSubscription && viewInvoiceLink) {
      actions.push({
        name: translate('notification.common.viewInvoice', locale),
        title: translate('notification.common.viewInvoice', locale),
        link: viewInvoiceLink,
      });
    }

    return [...actions, ...customActions].filter(Boolean);
  }

  // 9. 错误处理方法
  protected async validateSubscriptionExists(subscriptionId: string): Promise<Subscription> {
    const subscription = await Subscription.findByPk(subscriptionId);
    if (!subscription) {
      throw new Error(`Subscription not found: ${subscriptionId}`);
    }
    return subscription;
  }

  protected async validateCustomerExists(customerId: string): Promise<Customer> {
    const customer = await Customer.findByPk(customerId);
    if (!customer) {
      throw new Error(`Customer not found: ${customerId}`);
    }
    return customer;
  }

  // 10. Credit 订阅条件判断辅助方法
  protected shouldShowPaymentAmount(isCreditSubscription: boolean): boolean {
    return !isCreditSubscription;
  }

  protected shouldShowPeriod(isCreditSubscription: boolean): boolean {
    return !isCreditSubscription;
  }

  protected shouldShowInvoiceLink(isCreditSubscription: boolean): boolean {
    return !isCreditSubscription;
  }

  // 11. 字段和操作过滤方法
  protected filterFieldsForCredit(fields: any[], isCreditSubscription: boolean): any[] {
    if (!isCreditSubscription) {
      return fields;
    }

    // 移除支付相关字段
    return fields.filter((field) => {
      const text = field?.data?.text;
      return (
        !text ||
        (!text.includes('notification.common.paymentAmount') && !text.includes('notification.common.validityPeriod'))
      );
    });
  }

  protected filterActionsForCredit(actions: any[], isCreditSubscription: boolean): any[] {
    if (!isCreditSubscription) {
      return actions;
    }

    // 移除发票相关操作
    return actions.filter((action) => {
      const name = action?.name;
      return !name || !name.includes('notification.common.viewInvoice');
    });
  }
}
