import { Injectable, NotFoundException } from '@nestjs/common';
import { MqttClientService } from '../ingest/mqtt-client.service';
import { PrismaService } from '../prisma/prisma.service';
import { SimPublishPointDto } from './dto/sim.dto';
import { SimMqttsService } from './sim-mqtts.service';

@Injectable()
export class SimService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly mqttClient: MqttClientService,
    private readonly simMqtts: SimMqttsService,
  ) {}

  // Publishes onto the real broker rather than writing to the DB directly, so
  // the simulator exercises the exact same ingest path a real locator would.
  // "relay" (default) reuses the backend's own privileged connection; "mqtts"
  // instead opens a real TLS connection authenticated with the device's own
  // client certificate, so it's subject to the same mTLS handshake and
  // devices/%u/# ACL a real device would be.
  async publish(orgId: string, dto: SimPublishPointDto) {
    const job = await this.prisma.job.findFirst({ where: { id: dto.jobId, orgId }, select: { id: true } });
    if (!job) {
      throw new NotFoundException('Job not found in this organization');
    }

    const { serial, transport, ...payload } = dto;
    const topic = `devices/${serial}/log`;
    if (transport === 'mqtts') {
      await this.simMqtts.publish(orgId, serial, topic, payload);
    } else {
      this.mqttClient.publish(topic, payload);
    }
    return { ok: true, topic, transport: transport ?? 'relay' };
  }
}
