/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.bausystem.tracer.record;

import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.tracer.show.Record;
import de.steamwar.bausystem.tracer.show.StoredRecords;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.scheduler.BukkitTask;

import java.util.HashMap;
import java.util.Map;

public class Recorder implements Listener {

    private static final World world = Bukkit.getWorlds().get(0);

    private final Map<TNTPrimed, Record.TNTRecord> recordMap = new HashMap<>();
    private final BukkitTask task;
    private final Record record;

    Recorder() {
        Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin());
        task = Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), this::run, 1, 1);
        record = new Record();

        // To trace TNT initial positions with AutoTracer
        run();
    }

    void stopRecording() {
        HandlerList.unregisterAll(this);
        task.cancel();
    }

    int size() {
        return record.size();
    }

    long getStartTime() {
        return record.getStartTime();
    }

    void postClear() {
        record.clear();
        recordMap.clear();
        StoredRecords.add(record);
    }

    private void run() {
        world.getEntitiesByClass(TNTPrimed.class).forEach(tntPrimed -> get(tntPrimed).add(tntPrimed));
    }

    @EventHandler
    public void onEntityExplode(EntityExplodeEvent event) {
        if (!(event.getEntity() instanceof TNTPrimed))
            return;
        TNTPrimed tntPrimed = (TNTPrimed) event.getEntity();

        get(tntPrimed).explode(tntPrimed);
        recordMap.remove(tntPrimed);
    }

    private Record.TNTRecord get(TNTPrimed tntPrimed) {
        Record.TNTRecord tntRecord = recordMap.get(tntPrimed);
        if (tntRecord != null)
            return tntRecord;

        tntRecord = this.record.spawn();
        recordMap.put(tntPrimed, tntRecord);
        return tntRecord;
    }
}
