import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { CreateDeviceDto, UpdateDeviceDto } from './dto/devices.dto';

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

  list(orgId: string) {
    return this.prisma.device.findMany({
      where: { orgId },
      orderBy: { createdAt: 'asc' },
    });
  }

  async create(orgId: string, dto: CreateDeviceDto) {
    const existing = await this.prisma.device.findUnique({
      where: { mqttUsername: dto.mqttUsername },
    });
    if (existing) {
      throw new ConflictException('A device with this MQTT username already exists');
    }
    const device = await this.prisma.device.create({
      data: { orgId, name: dto.name, mqttUsername: dto.mqttUsername, serialNumber: dto.serialNumber },
    });
    return {
      ...device,
      provisioning: {
        mqttUsername: device.mqttUsername,
        pointsTopic: `devices/${device.mqttUsername}/points`,
        jobsTopic: `devices/${device.mqttUsername}/jobs`,
        note: 'Broker credentials must be created separately (mosquitto_passwd) until dynamic broker auth lands.',
      },
    };
  }

  async update(orgId: string, deviceId: string, dto: UpdateDeviceDto) {
    await this.get(orgId, deviceId);
    return this.prisma.device.update({ where: { id: deviceId }, data: dto });
  }

  async remove(orgId: string, deviceId: string) {
    await this.get(orgId, deviceId);
    await this.prisma.device.delete({ where: { id: deviceId } });
    return { ok: true };
  }

  private async get(orgId: string, deviceId: string) {
    const device = await this.prisma.device.findFirst({ where: { id: deviceId, orgId } });
    if (!device) {
      throw new NotFoundException('Device not found');
    }
    return device;
  }
}
