import { Injectable } from '@nestjs/common';
import { MikroORM } from '@mikro-orm/core';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { Gift, GiftContribution } from '../entities/gift.entity';
import { CreateGiftDto } from '../api/dto/create-gift.dto';
import { CreateContributionDto } from '../api/dto/create-contribution.dto';

@Injectable()
export class GiftService {
  constructor(
    private readonly orm: MikroORM,
    private readonly eventEmitter: EventEmitter2,
  ) {}

  private get em() {
    return this.orm.em.fork();
  }

  async createGift(tenantId: string, dto: CreateGiftDto): Promise<Gift> {
    const gift = this.em.create(Gift, {
      tenantId,
      ...dto,
    } as any);
    this.em.persist(gift);
    await this.em.flush();
    this.eventEmitter.emit('gift.created', { gift });
    return gift;
  }

  async createContribution(tenantId: string, dto: CreateContributionDto): Promise<GiftContribution> {
    const contribution = this.em.create(GiftContribution, {
      tenantId,
      ...dto,
    } as any);
    this.em.persist(contribution);
    await this.em.flush();
    this.eventEmitter.emit('gift.contribution', { contribution });
    return contribution;
  }

  async listGifts(tenantId: string): Promise<Gift[]> {
    return this.em.find(Gift, { tenantId });
  }

  async getGiftById(
    tenantId: string,
    id: string,
    requesterId?: string,
  ): Promise<Gift | null> {
    const gift = await this.em.findOne(Gift, { tenantId, id });
    if (!gift) return null;
    if (requesterId && gift.ownerId && gift.ownerId !== requesterId) {
      return null;
    }
    return gift;
  }

  async listContributions(
    tenantId: string,
    giftId: string,
    requesterId?: string,
  ): Promise<GiftContribution[]> {
    const gift = await this.getGiftById(tenantId, giftId, requesterId);
    if (!gift) return [];
    return this.em.find(GiftContribution, { tenantId, giftId });
  }
}
