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

const mapPointInclude = {
  region: true,
  alarms: { where: { status: { in: [AlarmStatus.OPEN, AlarmStatus.PROCESSING] } } },
} satisfies Prisma.StreetLampInclude;

type MapPointLamp = Prisma.StreetLampGetPayload<{ include: typeof mapPointInclude }>;

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

  async points(user: AuthUser, query: any = {}) {
    const deviceType = query.deviceType === '单灯' || query.deviceType === '监控终端' ? query.deviceType : undefined;
    const where = await this.regionScope.lampWhere(user, {
      ...(deviceType ? { deviceType } : {}),
    }, query.regionId);
    const page = Math.max(Number(query.page ?? 1), 1);
    const pageSize = Math.min(Math.max(Number(query.pageSize ?? query.limit ?? 20), 1), 100);

    if (query.all === '1' || query.all === 'true' || query.all === true) {
      const lamps = await this.prisma.streetLamp.findMany({ where, include: mapPointInclude });
      return lamps.map((lamp) => this.toPoint(lamp));
    }

    const [lamps, total] = await Promise.all([
      this.prisma.streetLamp.findMany({
        where,
        include: mapPointInclude,
        skip: (page - 1) * pageSize,
        take: pageSize,
      }),
      this.prisma.streetLamp.count({ where }),
    ]);

    return {
      items: lamps.map((lamp) => this.toPoint(lamp)),
      total,
      page,
      pageSize,
    };
  }

  private toPoint(lamp: MapPointLamp) {
    return {
      id: lamp.id,
      code: lamp.code,
      name: lamp.name,
      address: lamp.address,
      deviceType: lamp.deviceType,
      longitude: Number(lamp.longitude),
      latitude: Number(lamp.latitude),
      regionName: lamp.region.name,
      status: lamp.status,
      onlineStatus: lamp.onlineStatus,
      isPowerOn: lamp.isPowerOn,
      lastReportedAt: lamp.lastReportedAt,
      activeAlarmCount: lamp.alarms.length,
      highestAlarmLevel: lamp.alarms[0]?.level ?? null,
      activeAlarms: lamp.alarms.map((alarm) => ({
        id: alarm.id,
        title: alarm.title,
        type: alarm.type,
        level: alarm.level,
        status: alarm.status,
        occurredAt: alarm.occurredAt,
      })),
    };
  }
}
