import { Injectable, NotFoundException, ForbiddenException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CreateClientDto } from './dto/create-client.dto';
import { UpdateClientDto } from './dto/update-client.dto';
import { QueryClientDto } from './dto/query-client.dto';

@Injectable()
export class ClientsService {
  constructor(private prisma: PrismaService) {}

  async create(tenantId: string, dto: CreateClientDto) {
    await this.checkPlanLimit(tenantId);
    return this.prisma.client.create({ data: { ...dto, tenantId } });
  }

  async findAll(tenantId: string, query: QueryClientDto) {
    const { search, type, page = 1, limit = 20 } = query;
    const skip = (page - 1) * limit;

    const where: any = { tenantId, isActive: true };
    if (search) {
      where.OR = [
        { name: { contains: search, mode: 'insensitive' } },
        { phone: { contains: search } },
        { email: { contains: search, mode: 'insensitive' } },
      ];
    }
    if (type) where.type = type;

    const [data, total] = await Promise.all([
      this.prisma.client.findMany({
        where,
        skip,
        take: limit,
        orderBy: { name: 'asc' },
        include: {
          _count: { select: { orders: true, reminders: true } },
          reminders: {
            where: { status: { in: ['PENDING', 'OVERDUE'] } },
            orderBy: { nextMaintenanceDate: 'asc' },
            take: 1,
          },
        },
      }),
      this.prisma.client.count({ where }),
    ]);

    return { data, total, page, limit, pages: Math.ceil(total / limit) };
  }

  async findOne(tenantId: string, id: string) {
    const client = await this.prisma.client.findFirst({
      where: { id, tenantId },
      include: {
        orders: {
          orderBy: { createdAt: 'desc' },
          take: 10,
          include: { technician: { select: { name: true } } },
        },
        reminders: { orderBy: { nextMaintenanceDate: 'asc' } },
      },
    });
    if (!client) throw new NotFoundException('Cliente não encontrado');
    return client;
  }

  async update(tenantId: string, id: string, dto: UpdateClientDto) {
    await this.findOne(tenantId, id);
    return this.prisma.client.update({ where: { id }, data: dto });
  }

  async remove(tenantId: string, id: string) {
    await this.findOne(tenantId, id);
    return this.prisma.client.update({ where: { id }, data: { isActive: false } });
  }

  async getWhatsappLink(tenantId: string, id: string) {
    const client = await this.findOne(tenantId, id);
    const phone = (client.whatsapp || client.phone).replace(/\D/g, '');
    const message = encodeURIComponent(
      `Olá ${client.name}, identificamos que sua manutenção está próxima ou atrasada. Deseja agendar?`,
    );
    return { url: `https://wa.me/${phone}?text=${message}` };
  }

  private async checkPlanLimit(tenantId: string) {
    const tenant = await this.prisma.tenant.findUnique({ where: { id: tenantId } });
    const count = await this.prisma.client.count({ where: { tenantId, isActive: true } });
    if (count >= (tenant?.maxClients ?? 50)) {
      throw new ForbiddenException(
        `Limite de ${tenant?.maxClients} clientes atingido. Faça upgrade do plano.`,
      );
    }
  }
}
