import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { AuthUser } from '../../common/current-user.decorator';
import { RegionScopeService } from '../../common/region-scope.service';
import { PrismaService } from '../prisma/prisma.service';

@Injectable()
export class AlarmsService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly regionScope: RegionScopeService,
  ) {}

  async findAll(user: AuthUser, query: any) {
    const page = Math.max(Number(query.page ?? 1), 1);
    const pageSize = Math.min(Math.max(Number(query.pageSize ?? query.limit ?? 20), 1), 100);
    const where = await this.regionScope.alarmWhere(user, {
      ...(query.status ? { status: query.status } : {}),
      ...(query.level ? { level: query.level } : {}),
      ...(query.type ? { type: query.type } : {}),
    }, query.regionId);

    const [items, total] = await Promise.all([
      this.prisma.alarm.findMany({
        where,
        include: { lamp: true, region: true, handleRecords: { include: { user: true }, orderBy: { createdAt: 'desc' } } },
        orderBy: { occurredAt: 'desc' },
        skip: (page - 1) * pageSize,
        take: pageSize,
      }),
      this.prisma.alarm.count({ where }),
    ]);

    return { items, total, page, pageSize };
  }

  async createFromIngestion(user: AuthUser, dto: any) {
    const code = typeof dto.code === 'string' ? dto.code.trim() : '';
    const name = typeof dto.name === 'string' ? dto.name.trim() : '';
    if (!code || !name) {
      throw new BadRequestException('code 与 name 均为必填，且须与资产库中路灯一致');
    }

    const lamp = await this.prisma.streetLamp.findUnique({ where: { code } });
    if (!lamp) {
      throw new NotFoundException('路灯设备不存在');
    }
    if (lamp.name.trim() !== name) {
      throw new BadRequestException('路灯名称与编号不一致');
    }

    await this.regionScope.assertLampRowWritableByUser(user, lamp);

    const existing = await this.prisma.alarm.findUnique({ where: { sourceAlarmId: dto.sourceAlarmId } });
    if (existing) {
      if (user.tenantId != null && existing.tenantId !== user.tenantId) {
        throw new NotFoundException('报警不存在');
      }
      if (existing.lampId !== lamp.id) {
        throw new BadRequestException('路灯与既有报警不匹配');
      }
    }

    const tenantId =
      user.tenantId != null ? user.tenantId : dto.tenantId !== undefined ? dto.tenantId : lamp.tenantId;

    return this.prisma.alarm.upsert({
      where: { sourceAlarmId: dto.sourceAlarmId },
      update: {
        status: dto.status,
        recoveredAt: dto.recoveredAt ? new Date(dto.recoveredAt) : undefined,
        events: { create: { eventType: 'UPDATED_FROM_API', payload: dto } },
      },
      create: {
        sourceAlarmId: dto.sourceAlarmId,
        tenantId: tenantId ?? lamp.tenantId,
        lampId: lamp.id,
        regionId: lamp.regionId,
        type: dto.type,
        title: dto.title,
        description: dto.description,
        level: dto.level ?? 'MEDIUM',
        status: dto.status ?? 'OPEN',
        occurredAt: dto.occurredAt ? new Date(dto.occurredAt) : new Date(),
        events: { create: { eventType: 'CREATED_FROM_API', payload: dto } },
      },
    });
  }

  async handle(user: AuthUser, id: string, dto: any) {
    const alarm = await this.prisma.alarm.findFirst({ where: await this.regionScope.alarmWhere(user, { id }) });
    if (!alarm) {
      throw new NotFoundException('报警不存在或无权限访问');
    }

    return this.prisma.alarm.update({
      where: { id },
      data: {
        status: dto.status ?? 'PROCESSING',
        handledAt: new Date(),
        recoveredAt: dto.status === 'RESOLVED' ? new Date() : undefined,
        handleRecords: {
          create: {
            userId: user.sub,
            action: dto.action ?? 'HANDLE',
            remark: dto.remark,
          },
        },
      },
      include: { handleRecords: true },
    });
  }
}
