import { ExtendedCharacter, TSocket } from '../utilities/types'
import prisma from '../utilities/prisma'
import ZoneRepository from '../repositories/zoneRepository'
import ZoneManager from '../managers/zoneManager'
import { Character, ZoneEventTile, ZoneEventTileTeleport } from '@prisma/client'
import { Server } from 'socket.io'
import CharacterManager from '../managers/characterManager'

export class ZoneEventTileService {
  public async handleTeleport(io: Server, socket: TSocket, character: ExtendedCharacter, teleport: ZoneEventTileTeleport): Promise<void> {
    if (teleport.toZoneId === character.zoneId) return

    const zone = await ZoneRepository.getById(teleport.toZoneId)
    if (!zone) return

    // CharacterManager.moveCharacterBetweenZones(character, zone)

    const oldZoneId = character.zoneId
    const newZoneId = teleport.toZoneId

    // Update character in database
    await prisma.character.update({
      where: { id: character.id },
      data: {
        zoneId: newZoneId,
        positionX: teleport.toPositionX,
        positionY: teleport.toPositionY
      }
    })

    // Update local character object
    character.zoneId = newZoneId
    character.positionX = teleport.toPositionX
    character.positionY = teleport.toPositionY

    // Emit events
    io.to(oldZoneId.toString()).emit('zone:character:leave', character.id)
    io.to(newZoneId.toString()).emit('zone:character:join', character)
    socket.emit('zone:character:load_assets', newZoneId);

    // Update socket rooms
    socket.leave(oldZoneId.toString())
    socket.join(newZoneId.toString())

    // Send teleport information to the client
    socket.emit('zone:teleport', {
      zone,
      characters: CharacterManager.getCharactersInZone(zone)
    })
  }
}