import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
import { EntityManager } from '@mikro-orm/postgresql';
import { PaymentMethod } from '../entities/payment-method.entity';
import { PaymentMethodRepository } from '../repositories/payment-method.repository';
import { CreatePaymentMethodDto } from '../dto/create-payment-method.dto';
import { UpdatePaymentMethodDto } from '../dto/update-payment-method.dto';
import { RequiredEntityData } from '@mikro-orm/core';
import { PaymentMessage } from 'src/common/enums/message.enum';
import { RestaurantsService } from 'src/modules/restaurants/providers/restaurants.service';

@Injectable()
export class PaymentMethodService {
  constructor(
    private readonly paymentMethodRepository: PaymentMethodRepository,
    private readonly restaurantsService: RestaurantsService,
    private readonly em: EntityManager,
  ) { }

  async create(restId: string, createPaymentMethodDto: CreatePaymentMethodDto): Promise<PaymentMethod> {
    // Check if restaurant exists
    const restaurant = await this.restaurantsService.findOneOrFail(restId)

    const paymentMethod = this.paymentMethodRepository.create({
      restaurant,
      ...createPaymentMethodDto,
    } as unknown as RequiredEntityData<PaymentMethod>);
    await this.em.persistAndFlush(paymentMethod);
    return paymentMethod;
  }

  async findOneOrFail(id: string): Promise<PaymentMethod> {
    const paymentMethod = await this.paymentMethodRepository.findOne({ id }, { populate: ['restaurant'] });
    if (!paymentMethod) {
      throw new NotFoundException(PaymentMessage.PAYMENT_METHOD_NOT_FOUND);
    }
    return paymentMethod;
  }

  async findByRestaurant(restaurantId: string): Promise<PaymentMethod[]> {
    return this.paymentMethodRepository.find({ restaurant: { id: restaurantId } }, { populate: ['restaurant'] });
  }

  async update(id: string, updatePaymentMethodDto: UpdatePaymentMethodDto): Promise<PaymentMethod> {
    const paymentMethod = await this.findOneOrFail(id);
    this.em.assign(paymentMethod, updatePaymentMethodDto);
    await this.em.flush();
    return paymentMethod;
  }

  async remove(id: string): Promise<PaymentMethod> {
    const paymentMethod = await this.findOneOrFail(id);
    await this.em.removeAndFlush(paymentMethod);
    return paymentMethod;
  }


}
