package net.viper.status.modules.chat;

import java.io.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

/**
 * Verwaltet den gegenseitigen Blockier-/Ignore-Status zwischen Spielern.
 *
 * Admins/OPs mit dem Bypass-Permission sind nicht blockierbar.
 *
 * Format der Speicherdatei:
 *   <blocker-uuid>|<blocked-uuid1>,<blocked-uuid2>,...
 */
public class BlockManager {

    private final File file;
    private final Logger logger;

    // blocker UUID → Set der blockierten UUIDs
    private final ConcurrentHashMap<UUID, Set<UUID>> blocked = new ConcurrentHashMap<>();

    public BlockManager(File dataFolder, Logger logger) {
        this.file   = new File(dataFolder, "chat_blocked.dat");
        this.logger = logger;
    }

    // ===== Block-Logik =====

    /** Spieler `blocker` blockiert Spieler `target`. */
    public void block(UUID blocker, UUID target) {
        blocked.computeIfAbsent(blocker, k -> Collections.newSetFromMap(new ConcurrentHashMap<>()))
               .add(target);
        save();
    }

    /** Spieler `blocker` hebt den Block f\u00fcr `target` auf. */
    public void unblock(UUID blocker, UUID target) {
        Set<UUID> set = blocked.get(blocker);
        if (set != null) {
            set.remove(target);
            if (set.isEmpty()) blocked.remove(blocker);
        }
        save();
    }

    /**
     * Pr\u00fcft ob `blocker` den Spieler `target` blockiert hat.
     * Admins (isAdmin=true) sind niemals blockiert.
     */
    public boolean isBlocked(UUID blocker, UUID target) {
        Set<UUID> set = blocked.get(blocker);
        return set != null && set.contains(target);
    }

    /**
     * Pr\u00fcft ob eine Nachricht von `sender` an `receiver` zugestellt werden soll.
     * Gibt false zur\u00fcck, wenn einer der beiden den anderen blockiert.
     */
    public boolean canReceive(UUID sender, UUID receiver) {
        // receiver hat sender blockiert → keine Nachricht
        if (isBlocked(receiver, sender)) return false;
        // sender hat receiver blockiert → keine Nachricht (Komfort)
        if (isBlocked(sender, receiver)) return false;
        return true;
    }

    /** Gibt alle UUIDs zur\u00fcck, die `blocker` blockiert hat. */
    public Set<UUID> getBlockedBy(UUID blocker) {
        Set<UUID> set = blocked.get(blocker);
        if (set == null) return Collections.emptySet();
        return Collections.unmodifiableSet(set);
    }

    // ===== Persistenz =====

    public void save() {
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))) {
            for (Map.Entry<UUID, Set<UUID>> e : blocked.entrySet()) {
                if (e.getValue().isEmpty()) continue;
                StringBuilder sb = new StringBuilder();
                sb.append(e.getKey()).append("|");
                Iterator<UUID> it = e.getValue().iterator();
                while (it.hasNext()) {
                    sb.append(it.next());
                    if (it.hasNext()) sb.append(",");
                }
                bw.write(sb.toString());
                bw.newLine();
            }
        } catch (IOException e) {
            logger.warning("[ChatModule] Fehler beim Speichern der Block-Liste: " + e.getMessage());
        }
    }

    public void load() {
        blocked.clear();
        if (!file.exists()) return;
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (line.isEmpty()) continue;
                String[] parts = line.split("\\|", 2);
                if (parts.length < 2) continue;
                try {
                    UUID blocker = UUID.fromString(parts[0]);
                    Set<UUID> targets = Collections.newSetFromMap(new ConcurrentHashMap<>());
                    for (String rawUUID : parts[1].split(",")) {
                        rawUUID = rawUUID.trim();
                        if (!rawUUID.isEmpty()) {
                            try { targets.add(UUID.fromString(rawUUID)); }
                            catch (Exception ignored) {}
                        }
                    }
                    if (!targets.isEmpty()) blocked.put(blocker, targets);
                } catch (Exception ignored) {}
            }
        } catch (IOException e) {
            logger.warning("[ChatModule] Fehler beim Laden der Block-Liste: " + e.getMessage());
        }
    }
}