import {
  Injectable,
  NotFoundException,
  ConflictException,
  BadRequestException,
} from '@nestjs/common';
import { CrmPrismaService } from '../prisma/crm-prisma.service';
import { CreateTradeEventDto } from './dto/create-trade-event.dto';
import { UpdateTradeEventDto } from './dto/update-trade-event.dto';

@Injectable()
export class TradeEventsService {
  constructor(private readonly prisma: CrmPrismaService) {}

  async create(tenantId: string, userId: string, dto: CreateTradeEventDto) {
    // Datum-Validierung: endDate >= startDate
    const start = new Date(dto.startDate);
    const end = new Date(dto.endDate);
    if (end < start) {
      throw new BadRequestException(
        'Enddatum darf nicht vor dem Startdatum liegen',
      );
    }

    // Pruefen ob Name bereits existiert
    const existing = await this.prisma.tradeEvent.findUnique({
      where: { tenantId_name: { tenantId, name: dto.name } },
    });
    if (existing) {
      throw new ConflictException(
        `Event "${dto.name}" existiert bereits`,
      );
    }

    return this.prisma.tradeEvent.create({
      data: {
        tenantId,
        name: dto.name,
        description: dto.description,
        startDate: start,
        endDate: end,
        location: dto.location,
        boothInfo: dto.boothInfo,
        websiteUrl: dto.websiteUrl,
        isActive: dto.isActive ?? true,
        sortOrder: dto.sortOrder ?? 0,
        createdBy: userId,
      },
    });
  }

  async findAll(tenantId: string) {
    return this.prisma.tradeEvent.findMany({
      where: { tenantId },
      orderBy: [{ sortOrder: 'asc' }, { startDate: 'asc' }],
    });
  }

  async findActive(tenantId: string) {
    return this.prisma.tradeEvent.findMany({
      where: { tenantId, isActive: true },
      orderBy: [{ sortOrder: 'asc' }, { startDate: 'asc' }],
    });
  }

  async findOne(tenantId: string, id: string) {
    const event = await this.prisma.tradeEvent.findFirst({
      where: { id, tenantId },
    });

    if (!event) {
      throw new NotFoundException('Event nicht gefunden');
    }

    return event;
  }

  async update(
    tenantId: string,
    id: string,
    userId: string,
    dto: UpdateTradeEventDto,
  ) {
    const existing = await this.findOne(tenantId, id);

    // Datum-Validierung wenn Daten geaendert werden
    const start = dto.startDate
      ? new Date(dto.startDate)
      : existing.startDate;
    const end = dto.endDate ? new Date(dto.endDate) : existing.endDate;
    if (end < start) {
      throw new BadRequestException(
        'Enddatum darf nicht vor dem Startdatum liegen',
      );
    }

    // Name-Uniqueness pruefen falls Name geaendert wird
    if (dto.name && dto.name !== existing.name) {
      const duplicate = await this.prisma.tradeEvent.findFirst({
        where: { tenantId, name: dto.name, NOT: { id } },
      });
      if (duplicate) {
        throw new ConflictException(
          `Event "${dto.name}" existiert bereits`,
        );
      }
    }

    return this.prisma.tradeEvent.update({
      where: { id },
      data: {
        ...dto,
        startDate: dto.startDate ? new Date(dto.startDate) : undefined,
        endDate: dto.endDate ? new Date(dto.endDate) : undefined,
        updatedBy: userId,
      },
    });
  }

  async remove(tenantId: string, id: string) {
    await this.findOne(tenantId, id);
    return this.prisma.tradeEvent.delete({ where: { id } });
  }
}
