import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
import { PersonasService } from 'src/personas/personas.service';
import { PrismaService } from 'src/prisma/prisma.service';
import { CreateChoferDto } from './dto/create-chofer.dto';
import { UpdateChoferDto } from './dto/update-chofer.dto';

const include = {
  personas: {
    include: {
      tipo_documento_identidad: true,
      naturaleza_receptor: true,
      ciudades: { include: { distritos: { include: { departamentos: true } } } },
    },
  },
};

@Injectable()
export class ChofereService {
  constructor(
    private prisma: PrismaService,
    private personasService: PersonasService,
  ) {}

  async create(dto: CreateChoferDto, empresa_id: string) {
    const persona = await this.personasService.create(dto, empresa_id);
    const existing = await this.prisma.choferes.findUnique({ where: { persona_id: persona.id } });
    if (existing) throw new ConflictException('El chofer ya existe para esa persona');

    return this.prisma.choferes.create({
      data: {
        empresa_id,
        persona_id: persona.id,
        nro_libreta_conducir: dto.nro_libreta_conducir,
        categoria_licencia: dto.categoria_licencia,
        fecha_vencimiento_licencia: dto.fecha_vencimiento_licencia ? new Date(dto.fecha_vencimiento_licencia) : null,
        activo: dto.activo ?? true,
      },
      include,
    });
  }

  async findAll(empresa_id: string, page = 1, limit = 20, activo?: boolean) {
    const where: any = { empresa_id };
    if (activo !== undefined) where.activo = activo;
    const [items, total] = await Promise.all([
      this.prisma.choferes.findMany({
        where,
        include,
        skip: (page - 1) * limit,
        take: limit,
        orderBy: { created_at: 'desc' },
      }),
      this.prisma.choferes.count({ where }),
    ]);
    return { items, total, page, limit, lastPage: Math.ceil(total / limit) };
  }

  async search(empresa_id: string, q: string, limit = 20) {
    return this.prisma.choferes.findMany({
      where: {
        empresa_id,
        activo: true,
        personas: {
          OR: [
            { razon_social: { contains: q, mode: 'insensitive' } },
            { ruc: { contains: q, mode: 'insensitive' } },
            { nro_documento: { contains: q, mode: 'insensitive' } },
          ],
        },
      },
      include,
      take: limit,
    });
  }

  async findOne(id: string, empresa_id: string) {
    const item = await this.prisma.choferes.findFirst({ where: { id, empresa_id }, include });
    if (!item) throw new NotFoundException('Chofer no encontrado');
    return item;
  }

  async update(id: string, empresa_id: string, dto: UpdateChoferDto) {
    const item = await this.findOne(id, empresa_id);
    await this.personasService.update(item.persona_id, dto as any, empresa_id);
    return this.prisma.choferes.update({
      where: { id },
      data: {
        nro_libreta_conducir: dto.nro_libreta_conducir,
        categoria_licencia: dto.categoria_licencia,
        fecha_vencimiento_licencia: dto.fecha_vencimiento_licencia ? new Date(dto.fecha_vencimiento_licencia) : undefined,
        activo: dto.activo,
        updated_at: new Date(),
      },
      include,
    });
  }

  async remove(id: string, empresa_id: string) {
    await this.findOne(id, empresa_id);
    return this.prisma.choferes.update({
      where: { id },
      data: { activo: false, updated_at: new Date() },
    });
  }
}
