import { emailService } from '../../services/email.service';
import { siteSettingsService } from '../settings/settings.service';
import { env } from '../../config/env';
import { logger } from '../../utils/logger';

export const paymentEmailService = {
  /** Send donation receipt after successful checkout */
  async sendDonationReceipt(order: {
    id: string;
    buyerEmail: string;
    buyerName: string | null;
    amountCAD: number;
    donorMessage: string | null;
    isAnonymous: boolean;
    completedAt: Date | null;
  }): Promise<void> {
    try {
      const orgName = await this.getOrgName();
      const vars: Record<string, string> = {
        RECIPIENT_NAME: order.buyerName || 'Supporter',
        AMOUNT: `$${(order.amountCAD / 100).toFixed(2)}`,
        ORDER_ID: order.id,
        DONATION_DATE: (order.completedAt || new Date()).toLocaleDateString('en-CA', {
          year: 'numeric', month: 'long', day: 'numeric',
        }),
        DONOR_MESSAGE: order.donorMessage || '',
        IS_ANONYMOUS: order.isAnonymous ? 'true' : '',
        ORGANIZATION_NAME: orgName,
      };

      const dbTemplate = await emailService['loadTemplateFromDatabase']('donation-receipt');

      let html: string, text: string, subject: string;
      if (dbTemplate) {
        html = await emailService.processTemplate(dbTemplate.html, vars);
        text = await emailService.processTextTemplate(dbTemplate.text, vars);
        subject = emailService.processSubject(dbTemplate.subject, vars);
      } else {
        const htmlTemplate = emailService.loadTemplate('donation-receipt', 'html');
        const txtTemplate = emailService.loadTemplate('donation-receipt', 'txt');
        html = await emailService.processTemplate(htmlTemplate, vars);
        text = await emailService.processTextTemplate(txtTemplate, vars);
        subject = `Donation Receipt — ${orgName}`;
      }

      await emailService.sendEmail({ to: order.buyerEmail, subject, html, text });
      logger.info(`Donation receipt sent to ${order.buyerEmail} for order ${order.id}`);
    } catch (err) {
      logger.error('Failed to send donation receipt email:', err);
    }
  },

  /** Send product purchase receipt after successful checkout */
  async sendProductReceipt(order: {
    id: string;
    buyerEmail: string;
    buyerName: string | null;
    amountCAD: number;
    completedAt: Date | null;
    product: { title: string; type: string } | null;
  }): Promise<void> {
    try {
      const orgName = await this.getOrgName();
      const vars: Record<string, string> = {
        RECIPIENT_NAME: order.buyerName || 'Customer',
        AMOUNT: `$${(order.amountCAD / 100).toFixed(2)}`,
        ORDER_ID: order.id,
        PRODUCT_TITLE: order.product?.title || 'Product',
        PRODUCT_TYPE: order.product?.type || 'DIGITAL',
        PURCHASE_DATE: (order.completedAt || new Date()).toLocaleDateString('en-CA', {
          year: 'numeric', month: 'long', day: 'numeric',
        }),
        ORGANIZATION_NAME: orgName,
      };

      const dbTemplate = await emailService['loadTemplateFromDatabase']('product-receipt');

      let html: string, text: string, subject: string;
      if (dbTemplate) {
        html = await emailService.processTemplate(dbTemplate.html, vars);
        text = await emailService.processTextTemplate(dbTemplate.text, vars);
        subject = emailService.processSubject(dbTemplate.subject, vars);
      } else {
        const htmlTemplate = emailService.loadTemplate('product-receipt', 'html');
        const txtTemplate = emailService.loadTemplate('product-receipt', 'txt');
        html = await emailService.processTemplate(htmlTemplate, vars);
        text = await emailService.processTextTemplate(txtTemplate, vars);
        subject = `Purchase Receipt — ${orgName}`;
      }

      await emailService.sendEmail({ to: order.buyerEmail, subject, html, text });
      logger.info(`Product receipt sent to ${order.buyerEmail} for order ${order.id}`);
    } catch (err) {
      logger.error('Failed to send product receipt email:', err);
    }
  },

  /** Send subscription welcome email after checkout */
  async sendSubscriptionWelcome(opts: {
    userId: string;
    planId: number;
    stripeSubscriptionId: string;
    currentPeriodEnd: Date;
  }): Promise<void> {
    try {
      const { prisma } = await import('../../config/database');
      const [user, plan] = await Promise.all([
        prisma.user.findUnique({ where: { id: opts.userId } }),
        prisma.subscriptionPlan.findUnique({ where: { id: opts.planId } }),
      ]);

      if (!user || !plan) {
        logger.warn('Cannot send subscription welcome: user or plan not found', {
          userId: opts.userId, planId: opts.planId,
        });
        return;
      }

      const orgName = await this.getOrgName();
      const loginUrl = `${env.ADMIN_URL || 'http://localhost:3000'}/login`;
      const frequency = plan.yearlyPriceCAD && plan.yearlyPriceCAD > 0
        ? 'per month or per year'
        : 'per month';

      const vars: Record<string, string> = {
        RECIPIENT_NAME: user.name || user.email,
        PLAN_NAME: plan.name,
        AMOUNT: `$${(plan.priceCAD / 100).toFixed(2)}`,
        FREQUENCY: frequency,
        RENEWAL_DATE: opts.currentPeriodEnd.toLocaleDateString('en-CA', {
          year: 'numeric', month: 'long', day: 'numeric',
        }),
        SUBSCRIPTION_ID: opts.stripeSubscriptionId,
        LOGIN_URL: loginUrl,
        ORGANIZATION_NAME: orgName,
      };

      const dbTemplate = await emailService['loadTemplateFromDatabase']('subscription-welcome');

      let html: string, text: string, subject: string;
      if (dbTemplate) {
        html = await emailService.processTemplate(dbTemplate.html, vars);
        text = await emailService.processTextTemplate(dbTemplate.text, vars);
        subject = emailService.processSubject(dbTemplate.subject, vars);
      } else {
        const htmlTemplate = emailService.loadTemplate('subscription-welcome', 'html');
        const txtTemplate = emailService.loadTemplate('subscription-welcome', 'txt');
        html = await emailService.processTemplate(htmlTemplate, vars);
        text = await emailService.processTextTemplate(txtTemplate, vars);
        subject = `Welcome to ${plan.name} — ${orgName}`;
      }

      await emailService.sendEmail({ to: user.email, subject, html, text });
      logger.info(`Subscription welcome sent to ${user.email} for plan ${plan.name}`);
    } catch (err) {
      logger.error('Failed to send subscription welcome email:', err);
    }
  },

  async getOrgName(): Promise<string> {
    try {
      const settings = await siteSettingsService.get();
      return settings.organizationName || 'Changemaker Lite';
    } catch {
      return 'Changemaker Lite';
    }
  },
};
