import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
import { TransactionChangeStatusEvent } from 'src/modules/transaction/transaction/domain/entities/event/transaction-change-status.event';
import { CouchService } from '../../data/services/couch.service';
// import { STATUS } from 'src/core/strings/constants/base.constants';
import { mappingTransaction } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper';
import { TransactionDeletedEvent } from 'src/modules/transaction/transaction/domain/entities/event/transaction-deleted.event';
import { TransactionUpdatedEvent } from 'src/modules/transaction/transaction/domain/entities/event/transaction-updated.event';

@EventsHandler(TransactionDeletedEvent)
export class BookingDeletedEvent
  implements IEventHandler<TransactionDeletedEvent>
{
  constructor(private couchService: CouchService) {}

  async handle(event: TransactionDeletedEvent) {
    await this.couchService.deleteDoc(
      {
        _id: event.data.id,
        ...event.data.data,
      },
      'booking',
    );
  }
}

// @EventsHandler(TransactionChangeStatusEvent, TransactionUpdatedEvent)
// export class BookingHandler
//   implements IEventHandler<TransactionChangeStatusEvent>
// {
//   constructor(
//     private bookingService: TransactionDataService,
//     private couchService: CouchService,
//   ) {}

//   async handle(event: TransactionChangeStatusEvent) {
//     const old_data = event.data.old;
//     const data = event.data.data;

//     if (
//       data.payment_type == TransactionPaymentType.COUNTER ||
//       ([STATUS.ACTIVE, STATUS.SETTLED].includes(data.status) &&
//         data.payment_type != TransactionPaymentType.COUNTER)
//     ) {
//       const booking = await this.bookingService.getOneByOptions({
//         where: {
//           id: data.id,
//         },
//         relations: ['items'],
//       });

//       mappingTransaction(booking);

//       if (
//         (old_data?.status != data.status ||
//           data.payment_type != TransactionPaymentType.COUNTER) &&
//         [STATUS.PENDING, STATUS.ACTIVE, STATUS.SETTLED].includes(data.status)
//       ) {
//         await this.couchService.createDoc(
//           {
//             _id: booking.id,
//             ...booking,
//           },
//           'booking',
//         );
//       } else {
//         await this.couchService.updateDoc(
//           {
//             _id: booking.id,
//             ...booking,
//           },
//           'booking',
//         );
//       }
//     }
//   }
// }

@EventsHandler(TransactionChangeStatusEvent)
export class ChangeStatusBookingHandler
  implements IEventHandler<TransactionChangeStatusEvent>
{
  constructor(
    private bookingService: TransactionDataService,
    private couchService: CouchService,
  ) {}

  async handle(event: TransactionChangeStatusEvent) {
    const data = event.data.data;
    const dataID = data?.id ?? data?.order_id;

    const couchData = await this.couchService.getDoc(dataID, 'booking');

    const booking = await this.bookingService.getOneByOptions({
      where: {
        id: dataID,
      },
      relations: ['items', 'items.bundling_items'],
    });
    mappingTransaction(booking);

    if (!couchData) {
      console.log('save data to couch');
      await this.couchService.createDoc(
        {
          _id: booking.id,
          ...booking,
        },
        'booking',
      );
    } else {
      console.log('update data to couch');
      await this.couchService.updateDoc(
        {
          _id: booking.id,
          ...booking,
        },
        'booking',
      );
    }
  }
}

@EventsHandler(TransactionUpdatedEvent)
export class BookingUpdateHandler
  implements IEventHandler<TransactionUpdatedEvent>
{
  constructor(
    private bookingService: TransactionDataService,
    private couchService: CouchService,
  ) {}

  async handle(event: TransactionUpdatedEvent) {
    const data = event.data.data;
    const dataID = data?.id ?? data?.order_id;

    const couchData = await this.couchService.getDoc(dataID, 'booking');
    console.log('update', { dataID, couchData });
    if (couchData) {
      const booking = await this.bookingService.getOneByOptions({
        where: {
          id: dataID,
        },
        relations: ['items'],
      });
      console.log({ booking });
      mappingTransaction(booking);
      await this.couchService.updateDoc(
        {
          _id: booking.id,
          ...booking,
        },
        'booking',
      );
    }
  }
}
