import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { PrismaService } from '../../../prisma/prisma.service';
import { BookingEventsService } from '../core/booking-events.service';
import { CreateMembershipTypeDto, UpdateMembershipTypeDto } from '../dto/membership.dto';

const TYPE_INCLUDE = {
  _count: { select: { memberships: true } },
};

@Injectable()
export class MembershipsService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly events: BookingEventsService,
  ) {}

  // ─── List types ────────────────────────────────────────

  async findAll(clubId: string, activeOnly = false) {
    return this.prisma.bookingMembershipType.findMany({
      where: {
        clubId,
        ...(activeOnly ? { isActive: true } : {}),
      },
      include: TYPE_INCLUDE,
      orderBy: { createdAt: 'desc' },
    });
  }

  // ─── Get by ID ─────────────────────────────────────────

  async findById(id: string) {
    const type = await this.prisma.bookingMembershipType.findUnique({
      where: { id },
      include: TYPE_INCLUDE,
    });
    if (!type) throw new NotFoundException(`Membership type ${id} not found`);
    return type;
  }

  // ─── Create ────────────────────────────────────────────

  async create(clubId: string, dto: CreateMembershipTypeDto) {
    this.validateKind(dto);

    return this.prisma.bookingMembershipType.create({
      data: {
        clubId,
        name: dto.name,
        kind: dto.kind,
        totalVisits: dto.totalVisits ?? null,
        totalHours: dto.totalHours ?? null,
        validityDays: dto.validityDays,
        price: dto.price,
        serviceIds: dto.serviceIds ?? [],
        autoActivate: dto.autoActivate ?? true,
      },
      include: TYPE_INCLUDE,
    });
  }

  // ─── Update ────────────────────────────────────────────

  async update(id: string, dto: UpdateMembershipTypeDto) {
    await this.findById(id);

    return this.prisma.bookingMembershipType.update({
      where: { id },
      data: {
        ...(dto.name !== undefined ? { name: dto.name } : {}),
        ...(dto.totalVisits !== undefined ? { totalVisits: dto.totalVisits } : {}),
        ...(dto.totalHours !== undefined ? { totalHours: dto.totalHours } : {}),
        ...(dto.validityDays !== undefined ? { validityDays: dto.validityDays } : {}),
        ...(dto.price !== undefined ? { price: dto.price } : {}),
        ...(dto.serviceIds !== undefined ? { serviceIds: dto.serviceIds } : {}),
        ...(dto.autoActivate !== undefined ? { autoActivate: dto.autoActivate } : {}),
        ...(dto.isActive !== undefined ? { isActive: dto.isActive } : {}),
      },
      include: TYPE_INCLUDE,
    });
  }

  // ─── Delete ────────────────────────────────────────────

  async delete(id: string) {
    const type = await this.prisma.bookingMembershipType.findUnique({
      where: { id },
      include: { _count: { select: { memberships: true } } },
    });
    if (!type) throw new NotFoundException(`Membership type ${id} not found`);

    if (type._count.memberships > 0) {
      throw new BadRequestException(
        `Cannot delete: ${type._count.memberships} active memberships exist. Deactivate instead.`,
      );
    }

    await this.prisma.bookingMembershipType.delete({ where: { id } });
    return { success: true };
  }

  // ─── Validation ────────────────────────────────────────

  private validateKind(dto: CreateMembershipTypeDto) {
    const { kind } = dto;

    if (kind === 'VISIT_BASED' && !dto.totalVisits) {
      throw new BadRequestException('VISIT_BASED membership requires totalVisits');
    }
    if (kind === 'HOUR_BASED' && !dto.totalHours) {
      throw new BadRequestException('HOUR_BASED membership requires totalHours');
    }
    if (kind === 'MIXED' && !dto.totalVisits && !dto.totalHours) {
      throw new BadRequestException('MIXED membership requires totalVisits or totalHours');
    }
  }
}
