package net.viper.status.modules.forum;

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

/**
 * Speichert ausstehende Forum-Benachrichtigungen (Datei-basiert).
 * Benachrichtigungen die nicht sofort zugestellt werden konnten (Spieler offline)
 * werden hier gespeichert und beim n\u00e4chsten Login zugestellt.
 */
public class ForumNotifStorage {

    private final File file;
    private final Logger logger;

    // UUID -> Liste ausstehender Notifications
    private final ConcurrentHashMap<UUID, CopyOnWriteArrayList<ForumNotification>> pending = new ConcurrentHashMap<>();

    public ForumNotifStorage(File pluginFolder, Logger logger) {
        if (!pluginFolder.exists()) pluginFolder.mkdirs();
        this.file = new File(pluginFolder, "forum_notifications.dat");
        this.logger = logger;
    }

    /**
     * F\u00fcgt eine Benachrichtigung hinzu.
     */
    public void add(ForumNotification notification) {
        pending.computeIfAbsent(notification.getPlayerUuid(), k -> new CopyOnWriteArrayList<>())
               .add(notification);
    }

    /**
     * Gibt alle ausstehenden (nicht zugestellten) Benachrichtigungen eines Spielers zur\u00fcck.
     */
    public List<ForumNotification> getPending(UUID playerUuid) {
        CopyOnWriteArrayList<ForumNotification> list = pending.get(playerUuid);
        if (list == null) return Collections.emptyList();
        List<ForumNotification> result = new ArrayList<>();
        for (ForumNotification n : list) {
            if (!n.isDelivered()) result.add(n);
        }
        return result;
    }

    /**
     * Anzahl ausstehender Benachrichtigungen.
     */
    public int getPendingCount(UUID playerUuid) {
        CopyOnWriteArrayList<ForumNotification> list = pending.get(playerUuid);
        if (list == null) return 0;
        int count = 0;
        for (ForumNotification n : list) {
            if (!n.isDelivered()) count++;
        }
        return count;
    }

    /**
     * Markiert alle Benachrichtigungen eines Spielers als zugestellt und entfernt sie.
     */
    public void clearDelivered(UUID playerUuid) {
        CopyOnWriteArrayList<ForumNotification> list = pending.get(playerUuid);
        if (list == null) return;
        list.removeIf(ForumNotification::isDelivered);
        if (list.isEmpty()) pending.remove(playerUuid);
    }

    /**
     * Markiert alle als zugestellt.
     */
    public void markAllDelivered(UUID playerUuid) {
        CopyOnWriteArrayList<ForumNotification> list = pending.get(playerUuid);
        if (list == null) return;
        for (ForumNotification n : list) {
            n.setDelivered(true);
        }
    }

    /**
     * Entfernt Benachrichtigungen die \u00e4lter als maxDays Tage sind.
     */
    public void purgeOld(int maxDays) {
        long cutoff = System.currentTimeMillis() - ((long) maxDays * 24 * 60 * 60 * 1000);
        for (Map.Entry<UUID, CopyOnWriteArrayList<ForumNotification>> entry : pending.entrySet()) {
            entry.getValue().removeIf(n -> n.getTimestamp() < cutoff);
            if (entry.getValue().isEmpty()) pending.remove(entry.getKey());
        }
    }

    // ===== Datei-Operationen =====

    public void save() {
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))) {
            for (CopyOnWriteArrayList<ForumNotification> list : pending.values()) {
                for (ForumNotification n : list) {
                    if (!n.isDelivered()) {
                        bw.write(n.toLine());
                        bw.newLine();
                    }
                }
            }
            bw.flush();
        } catch (IOException e) {
            logger.warning("Fehler beim Speichern der Forum-Benachrichtigungen: " + e.getMessage());
        }
    }

    public void load() {
        if (!file.exists()) return;
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                ForumNotification n = ForumNotification.fromLine(line);
                if (n != null && !n.isDelivered()) {
                    pending.computeIfAbsent(n.getPlayerUuid(), k -> new CopyOnWriteArrayList<>())
                           .add(n);
                }
            }
        } catch (IOException e) {
            logger.warning("Fehler beim Laden der Forum-Benachrichtigungen: " + e.getMessage());
        }
    }
}
