import {Character, Zone} from "@prisma/client";
import ZoneRepository from "./repositories/ZoneRepository";
import ZoneService from "./services/ZoneService";

type TLoadedZone = {
    zone: Zone;
    characters: Character[];
}

class ZoneManager {
    private loadedZones: TLoadedZone[] = [];

    // Method to initialize zone manager
    public async boot() {
        if (!await ZoneRepository.getById(1)) {
            const zoneService = new ZoneService();
            await zoneService.createDemoZone();
        }

        const zones = await ZoneRepository.getAll();

        for (const zone of zones) {
            this.loadZone(zone);
        }

        console.log('[✅] Zone manager loaded');
    }

    // Method to handle individual zone loading
    public loadZone(zone: Zone) {
        this.loadedZones.push({
            zone,
            characters: []
        });
        console.log(`[✅] Zone ID ${zone.id} loaded`);
    }

    // Method to handle individual zone unloading
    public unloadZone(zoneId: number) {
        this.loadedZones = this.loadedZones.filter((loadedZone) => {
            return loadedZone.zone.id !== zoneId;
        });
        console.log(`[❌] Zone ID ${zoneId} unloaded`);
    }

    // Getter for loaded zones
    public getLoadedZones(): TLoadedZone[] {
        return this.loadedZones;
    }

    public addCharacterToZone(zoneId: number, character: Character) {
        const loadedZone = this.loadedZones.find((loadedZone) => {
            return loadedZone.zone.id === zoneId;
        });
        if (loadedZone) {
            loadedZone.characters.push(character);
        }
    }

    public removeCharacterFromZone(zoneId: number, character: Character) {
        const loadedZone = this.loadedZones.find((loadedZone) => {
            return loadedZone.zone.id === zoneId;
        });
        if (loadedZone) {
            loadedZone.characters = loadedZone.characters.filter((loadedCharacter) => {
                return loadedCharacter.id !== character.id;
            });
        }
    }

    public updateCharacterInZone(zoneId: number, character: Character) {
        const loadedZone = this.loadedZones.find((loadedZone) => {
            return loadedZone.zone.id === zoneId;
        });
        if (loadedZone) {
            const characterIndex = loadedZone.characters.findIndex((loadedCharacter) => {
                return loadedCharacter.id === character.id;
            });
            if (characterIndex !== -1) {
                loadedZone.characters[characterIndex] = character;
            }
        }
    }

    public getCharactersInZone(zoneId: number): Character[] {
        const loadedZone = this.loadedZones.find((loadedZone) => {
            return loadedZone.zone.id === zoneId;
        });
        return loadedZone ? loadedZone.characters : [];
    }
}

export default new ZoneManager;