import { BadRequestException, Injectable } from '@nestjs/common';
import { SaveRoomDecorPlacementDto } from '../../../business/room_decor/dto/save_room_decor_placement.dto';
import { RoomDecorPlacements } from './room_decor_placements.entity';

@Injectable()
export class RoomDecorPlacementsMemoryService {
  private placements: Map<bigint, RoomDecorPlacements> = new Map();
  private userDecorIndex: Map<string, bigint> = new Map();
  private currentId: bigint = BigInt(1);

  async listPlacements(userId: bigint): Promise<RoomDecorPlacements[]> {
    return Array.from(this.placements.values())
      .filter((row) => row.user_id === userId)
      .sort((a, b) => {
        const createdDiff = a.created_at.getTime() - b.created_at.getTime();
        return createdDiff !== 0 ? createdDiff : Number(a.id - b.id);
      });
  }

  async savePlacement(userId: bigint, placement: SaveRoomDecorPlacementDto): Promise<RoomDecorPlacements> {
    const decorId = this.normalizeDecorId(placement.decor_id);
    const key = this.indexKey(userId, decorId);
    const existingId = this.userDecorIndex.get(key);
    const row = existingId ? this.placements.get(existingId) as RoomDecorPlacements : new RoomDecorPlacements();
    if (!existingId) {
      row.id = this.currentId++;
      row.user_id = userId;
      row.decor_id = decorId;
      row.created_at = new Date();
      this.userDecorIndex.set(key, row.id);
      this.placements.set(row.id, row);
    }
    row.placed = placement.placed;
    row.position_x = placement.placed ? Number(placement.position_x ?? row.position_x ?? 0) : null;
    row.position_y = placement.placed ? Number(placement.position_y ?? row.position_y ?? 0) : null;
    row.scale = Number(placement.scale ?? row.scale ?? 1);
    row.z_index = Number(placement.z_index ?? row.z_index ?? 0);
    row.updated_at = new Date();
    return row;
  }

  private indexKey(userId: bigint, decorId: string): string {
    return `${userId.toString()}:${decorId}`;
  }

  private normalizeDecorId(decorId: string): string {
    const normalized = (decorId || '').trim();
    if (!/^[A-Za-z0-9_:-]{1,100}$/.test(normalized)) {
      throw new BadRequestException('摆件ID格式不正确');
    }
    return normalized;
  }
}
