import { Injectable, Logger } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { AdminRepository } from 'src/modules/admin/repositories/admin.repository';
import { onlinePaymentSucceedEvent, paymentSucceedEvent } from '../events/payment.events';
import { Permission } from 'src/common/enums/permission.enum';
import { NotifTitleEnum } from 'src/modules/notifications/interfaces/notification.interface';
import { NotificationService } from 'src/modules/notifications/services/notification.service';
import { ConfigService } from '@nestjs/config';
import { OrdersService } from 'src/modules/orders/providers/orders.service';

@Injectable()
export class PaymentListeners {
  private readonly logger = new Logger(PaymentListeners.name);
  private orderCreatedSmsTemplateId: string;
  private paymentSucceedSmsTemplateId: string;
  constructor(
    private readonly adminService: AdminRepository,
    private readonly notificationService: NotificationService,
    private readonly configService: ConfigService,
    private readonly orderService: OrdersService,
  ) {
    this.orderCreatedSmsTemplateId = this.configService.get<string>('SMS_PATTERN_ORDER_CREATED') ?? '123';
    this.paymentSucceedSmsTemplateId = this.configService.get<string>('SMS_PATTERN_ONLINE_PAYMENT_SUCCEED') ?? '123';
  }

  private getPaymentMethodFarsi(method: string): string {
    const methodMap: Record<string, string> = {
      Cash: 'نقدی',
      Wallet: 'کیف پول',
      Online: 'آنلاین',
    };
    return methodMap[method] || method;
  }

  @OnEvent(paymentSucceedEvent.name)
  async handlePaymentSucceed(event: paymentSucceedEvent) {
    try {
      this.logger.log(
        `Payment paid event received: ${event.orderId} for restaurant: ${event.restaurantId} and order number: ${event.orderNumber}`,
      );
      // get admnin os restuaraant that have order permissuins
      const admins = await this.adminService.findAdminsWithPermission(event.restaurantId, Permission.MANAGE_ORDERS);
      // const order=await 
      const recipients = admins.map(admin => ({
        adminId: admin.id,
      }));
      await this.notificationService.sendNotification({
        restaurantId: event.restaurantId,
        message: {
          title: NotifTitleEnum.PAYMENT_SUCCESS,
          content: `پرداخت سفارش شماره ${event.orderNumber} با روش ${this.getPaymentMethodFarsi(event.paymentMethod)} و مبلغ ${event.total} تومان با موفقیت انجام شد`,
          sms: {
            templateId: this.orderCreatedSmsTemplateId,
            parameters: {
              orderNumber: event.orderNumber,

            },
          },
          pushNotif: {
            title: `پرداخت موفق`,
            content: `پرداخت سفارش شماره ${event.orderNumber} با روش ${this.getPaymentMethodFarsi(event.paymentMethod)} و مبلغ ${event.total} تومان با موفقیت انجام شد`,
            icon: ``,
            action: {
              type: NotifTitleEnum.PAYMENT_SUCCESS,
              url: `/`,
            },
          },
        },
        recipients,
        metadata: {
          priority: 1,
        },
      });
    } catch (error) {
      this.logger.error(
        `Failed to send notification for order created event: ${event.restaurantId}`,
        error instanceof Error ? error.stack : String(error),
      );
    }
  }

  @OnEvent(onlinePaymentSucceedEvent.name)
  async handleOnlinePaymentSucceed(event: onlinePaymentSucceedEvent) {
    try {

      this.logger.log(
        `Online payment succeed event received: ${event.paymentId} for restaurant: ${event.restaurantId} and order number: ${event.orderNumber}`,
      );
      const admins = await this.adminService.findAdminsWithPermission(event.restaurantId, Permission.MANAGE_ORDERS);
      const recipients = admins.map(admin => ({
        adminId: admin.id,
      }));

      // admin notifs
      await this.notificationService.sendNotification({
        restaurantId: event.restaurantId,
        message: {
          title: NotifTitleEnum.ORDER_CREATED,
          content: `سفارش شماره ${event.orderNumber} با مبلغ ${event.total} تومان با موفقیت ایجاد شد`,
          sms: {
            templateId: this.orderCreatedSmsTemplateId,
            parameters: {
              orderNumber: event.orderNumber,
              total: event.total.toString(),
            },
          },
          pushNotif: {
            title: `سفارش جدید`,
            content: `سفارش شماره ${event.orderNumber} با مبلغ ${event.total} تومان با موفقیت ایجاد شد`,
            icon: `/`,
            action: {
              type: NotifTitleEnum.ORDER_CREATED,
              url: `/`,
            },
          },
        },
        recipients,
        metadata: {
          priority: 1,
        },
      });

      const order = await this.orderService.findOne(event.orderId, event.restaurantId);
      if (!order) {
        this.logger.error(
          `Order not found: ${event.orderId} for restaurant: ${event.restaurantId}`,
        );
        return;
      }
      const userRecipients = [
        {
          userId: order.user.id,
        },
      ];
      // user notif
      await this.notificationService.sendNotification({
        restaurantId: event.restaurantId,
        message: {
          title: NotifTitleEnum.PAYMENT_SUCCESS,
          content: `پرداخت سفارش شماره ${order.orderNumber} با روش ${this.getPaymentMethodFarsi(order.paymentMethod.method)} و مبلغ ${order.total} تومان با موفقیت انجام شد`,
          sms: {
            templateId: this.paymentSucceedSmsTemplateId,
            parameters: {
              orderNumber: event.orderNumber,
              total: event.total.toString(),
            },
          },
          pushNotif: {
            title: `پرداخت موفق`,
            content: `پرداخت سفارش شماره ${order.orderNumber} با روش ${this.getPaymentMethodFarsi(order.paymentMethod.method)} و مبلغ ${order.total} تومان با موفقیت انجام شد`,
            icon: `/`,
            action: {
              type: NotifTitleEnum.PAYMENT_SUCCESS,
              url: `/`,
            },
          },
        },
        recipients: userRecipients,
        metadata: {
          priority: 1,
        },
      });
    } catch (error) {
      this.logger.error(
        `Failed to send notification for online payment succeed event: ${event.restaurantId}`,
        error instanceof Error ? error.stack : String(error),
      );
    }
  }
}
