import { Injectable, Logger } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { AdminRepository } from 'src/modules/admin/repositories/admin.repository';
import { OrderCreatedEvent, OrderStatusChangedEvent } from '../events/order.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 { OrderRepository } from '../repositories/order.repository';
import { OrderStatus } from '../interface/order.interface';
import { PaymentMethodEnum } from 'src/modules/payments/interface/payment';
import { UserService } from 'src/modules/users/providers/user.service';
import { WalletTransactionReason, WalletTransactionType } from 'src/modules/users/interface/wallet';

@Injectable()
export class OrderListeners {
  private readonly logger = new Logger(OrderListeners.name);
  private orderCreatedSmsTemplateId: string;
  private orderStatusChangedSmsTemplateId: string;
  // private orderCompletedSmsTemplateId: string;
  constructor(
    private readonly adminService: AdminRepository,
    private readonly OrderRepository: OrderRepository,
    private readonly notificationService: NotificationService,
    private readonly configService: ConfigService,
    private readonly userService: UserService,
  ) {
    this.orderCreatedSmsTemplateId = this.configService.get<string>('SMS_PATTERN_ORDER_CREATED') ?? '123';
    this.orderStatusChangedSmsTemplateId = this.configService.get<string>('SMS_PATTERN_ORDER_STATUS_CHANGE') ?? '123';
    // this.orderCompletedSmsTemplateId = this.configService.get<string>('SMS_PATTERN_ORDER_STATUS_COMPLETED') ?? '123';
  }

  private getStatusFarsi(status: OrderStatus): string {
    const statusMap: Record<OrderStatus, string> = {
      [OrderStatus.PENDING_PAYMENT]: 'در انتظار پرداخت',
      [OrderStatus.PAID]: 'پرداخت شده',
      [OrderStatus.PREPARING]: 'در حال آماده‌سازی',
      [OrderStatus.DELIVERED_TO_RECEPTIONIST]: 'تحویل به پذیرش',
      [OrderStatus.DELIVERED_TO_WAITER]: 'تحویل به گارسون',
      [OrderStatus.SHIPPED]: 'ارسال شده',
      [OrderStatus.COMPLETED]: 'تکمیل شده',
      [OrderStatus.CANCELED]: 'لغو شده',
    };
    return statusMap[status] || status;
  }

  @OnEvent(OrderCreatedEvent.name)
  async handleOrderCreated(event: OrderCreatedEvent) {
    try {
      this.logger.log(
        `Order created event received: ${event.orderId} for restaurant: ${event.restaurantId} and order number: ${event.orderNumber}`,
      );

      const order = await this.OrderRepository.findOne(event.orderId);
      if (order?.paymentMethod.method === PaymentMethodEnum.Online) {
        return;
      }


      // get admnin os restuaraant that have order permissuins
      const admins = await this.adminService.findAdminsWithPermission(event.restaurantId, Permission.NEW_ORDER_NOTIFICATION);
      const recipients = admins.map(admin => ({
        adminId: admin.id,
      }));

      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,
        },
      });
    } catch (error) {
      this.logger.error(
        `Failed to send notification for order created event: ${event.restaurantId}`,
        error instanceof Error ? error.stack : String(error),
      );
    }
  }

  @OnEvent(OrderStatusChangedEvent.name)
  async handleOrderStatusChanged(event: OrderStatusChangedEvent) {
    try {
      this.logger.log(
        `Order status changed event received: ${event.orderId} for restaurant: ${event.restaurantId} and order number: ${event.orderNumber}`,
      );
      //TODO : REFACTOR to use queue or other way to handle this
      const recipients = [
        {
          userId: event.userId,
        },
      ];
      if (event.newStatus === OrderStatus.COMPLETED) {

        if (!event?.userId) {
          this.logger.log(
            `User not found for order: ${event.orderId} for restaurant: ${event.restaurantId} and order number: ${event.orderNumber}`,
          );
        }

        await this.notificationService.sendNotification({
          restaurantId: event.restaurantId,
          message: {
            title: NotifTitleEnum.ORDER_STATUS_CHANGED,
            content: `لطفابرای ثبت نظر سفارش ${event.orderNumber} به اپ مراجعه کنید`,
            sms: {
              templateId: this.orderCreatedSmsTemplateId,
              parameters: {
                orderNumber: event.orderNumber,
              },
            },
            pushNotif: {
              title: `تغییر وضعیت سفارش`,
              content: `لطفا برای ثبت نظر سفارش ${event.orderNumber} به اپ مراجعه کنید`,
              icon: `/`,
              action: {
                type: NotifTitleEnum.ORDER_STATUS_CHANGED,
                url: ``,
              },
            },
          },
          recipients,
          metadata: {
            priority: 1,
          },
        });
      } else {
        await this.notificationService.sendNotification({
          restaurantId: event.restaurantId,
          message: {
            title: NotifTitleEnum.ORDER_STATUS_CHANGED,
            content: `وضعیت سفارش شماره ${event.orderNumber} به ${this.getStatusFarsi(event.newStatus)} تغییر کرد`,
            sms: {
              templateId: this.orderStatusChangedSmsTemplateId,
              parameters: {
                orderNumber: event.orderNumber,
                status: this.getStatusFarsi(event.newStatus),
              },
            },
            pushNotif: {
              title: `تغییر وضعیت سفارش`,
              content: `وضعیت سفارش شماره ${event.orderNumber} به ${this.getStatusFarsi(event.newStatus)} تغییر کرد`,
              icon: `/`,
              action: {
                type: NotifTitleEnum.ORDER_STATUS_CHANGED,
                url: ``,
              },
            },
          },
          recipients,
          metadata: {
            priority: 1,
          },
        });
      }
    } catch (error) {
      this.logger.error(
        `Failed to send notification for order status changed event: ${event.restaurantId}`,
        error instanceof Error ? error.stack : String(error),
      );
    }
  }

}
