package net.viper.status.stats;

import java.util.UUID;

public class PlayerStats {
    public final UUID uuid;
    public String name;
    public long firstSeen;
    public long lastSeen;
    public long totalPlaytime;
    public long currentSessionStart;
    public int joins;

    // Combat
    public int kills;
    public int deaths;

    // Economy
    public double balance;
    public double totalEarned;
    public double totalSpent;
    public int transactionsCount;

    // Punishments
    public int bansCount;
    public int mutesCount;
    public int warnsCount;
    public long lastPunishmentAt;      // Unix-Timestamp (Sek.), 0 = nie
    public String lastPunishmentType;  // "ban", "mute", "warn", "kick", "" = nie
    public int punishmentScore;

    public PlayerStats(UUID uuid, String name) {
        this.uuid = uuid;
        this.name = name;
        long now = System.currentTimeMillis() / 1000L;
        this.firstSeen = now;
        this.lastSeen = now;
        this.totalPlaytime = 0;
        this.currentSessionStart = 0;
        this.joins = 0;
        this.kills = 0;
        this.deaths = 0;
        this.balance = 0.0;
        this.totalEarned = 0.0;
        this.totalSpent = 0.0;
        this.transactionsCount = 0;
        this.bansCount = 0;
        this.mutesCount = 0;
        this.warnsCount = 0;
        this.lastPunishmentAt = 0;
        this.lastPunishmentType = "";
        this.punishmentScore = 0;
    }

    public synchronized void onJoin() {
        long now = System.currentTimeMillis() / 1000L;
        if (this.currentSessionStart == 0) this.currentSessionStart = now;
        this.lastSeen = now;
        this.joins++;
        if (this.firstSeen == 0) this.firstSeen = now;
    }

    public synchronized void onQuit() {
        long now = System.currentTimeMillis() / 1000L;
        if (this.currentSessionStart > 0) {
            long session = now - this.currentSessionStart;
            if (session > 0) this.totalPlaytime += session;
            this.currentSessionStart = 0;
        }
        this.lastSeen = now;
    }

    public synchronized long getPlaytimeWithCurrentSession() {
        long now = System.currentTimeMillis() / 1000L;
        if (this.currentSessionStart > 0) return totalPlaytime + (now - currentSessionStart);
        return totalPlaytime;
    }

    /**
     * Format: uuid|name|firstSeen|lastSeen|totalPlaytime|currentSessionStart|joins|
     *         kills|deaths|
     *         balance|totalEarned|totalSpent|transactionsCount|
     *         bansCount|mutesCount|warnsCount|lastPunishmentAt|lastPunishmentType|punishmentScore
     *
     * HINWEIS: kills/deaths wurden in Version 1.17.1 als Felder 7 und 8 eingef\u00fcgt.
     * fromLine() ist r\u00fcckw\u00e4rtskompatibel (alte Dateien ohne kills/deaths werden 0 gesetzt).
     */
    public synchronized String toLine() {
        String safeType = (lastPunishmentType == null ? "" : lastPunishmentType).replace("|", "_");
        return uuid + "|" + name.replace("|", "_")
                + "|" + firstSeen
                + "|" + lastSeen
                + "|" + totalPlaytime
                + "|" + currentSessionStart
                + "|" + joins
                + "|" + kills
                + "|" + deaths
                + "|" + balance
                + "|" + totalEarned
                + "|" + totalSpent
                + "|" + transactionsCount
                + "|" + bansCount
                + "|" + mutesCount
                + "|" + warnsCount
                + "|" + lastPunishmentAt
                + "|" + safeType
                + "|" + punishmentScore;
    }

    public static PlayerStats fromLine(String line) {
        String[] parts = line.split("\\|", -1);
        if (parts.length < 7) return null;
        try {
            UUID uuid = UUID.fromString(parts[0]);
            String name = parts[1];
            PlayerStats ps = new PlayerStats(uuid, name);
            ps.firstSeen          = Long.parseLong(parts[2]);
            ps.lastSeen           = Long.parseLong(parts[3]);
            ps.totalPlaytime      = Long.parseLong(parts[4]);
            ps.currentSessionStart = Long.parseLong(parts[5]);
            ps.joins              = Integer.parseInt(parts[6]);

            // Erkennung ob altes Format (ohne kills/deaths, Economy ab Index 7)
            // oder neues Format (kills/deaths ab Index 7, Economy ab Index 9).
            // Altes Format hat 17 Felder (Index 0-16), neues hat 19 (Index 0-18).
            // Heuristik: Wenn parts[7] ein g\u00fcltiger Integer ist UND parts[9] wie eine
            // Gleitkommazahl aussieht → neues Format. Sonst altes Format.
            boolean newFormat = false;
            if (parts.length >= 19) {
                try {
                    Integer.parseInt(parts[7]);  // kills
                    Integer.parseInt(parts[8]);  // deaths
                    Double.parseDouble(parts[9]); // balance (Gleitkomma)
                    newFormat = true;
                } catch (Exception ignored) {}
            }

            if (newFormat) {
                // Neues Format: kills ab [7], deaths ab [8], economy ab [9]
                try { ps.kills  = Integer.parseInt(parts[7]); } catch (Exception ignored) {}
                try { ps.deaths = Integer.parseInt(parts[8]); } catch (Exception ignored) {}
                if (parts.length >= 13) {
                    try { ps.balance          = Double.parseDouble(parts[9]);  } catch (Exception ignored) {}
                    try { ps.totalEarned      = Double.parseDouble(parts[10]); } catch (Exception ignored) {}
                    try { ps.totalSpent       = Double.parseDouble(parts[11]); } catch (Exception ignored) {}
                    try { ps.transactionsCount = Integer.parseInt(parts[12]);  } catch (Exception ignored) {}
                }
                if (parts.length >= 19) {
                    try { ps.bansCount         = Integer.parseInt(parts[13]);  } catch (Exception ignored) {}
                    try { ps.mutesCount        = Integer.parseInt(parts[14]);  } catch (Exception ignored) {}
                    try { ps.warnsCount        = Integer.parseInt(parts[15]);  } catch (Exception ignored) {}
                    try { ps.lastPunishmentAt  = Long.parseLong(parts[16]);   } catch (Exception ignored) {}
                    ps.lastPunishmentType = parts[17];
                    try { ps.punishmentScore   = Integer.parseInt(parts[18]); } catch (Exception ignored) {}
                }
            } else {
                // Altes Format (kompatibel): kills/deaths = 0, Economy ab [7]
                ps.kills  = 0;
                ps.deaths = 0;
                if (parts.length >= 11) {
                    try { ps.balance          = Double.parseDouble(parts[7]);  } catch (Exception ignored) {}
                    try { ps.totalEarned      = Double.parseDouble(parts[8]);  } catch (Exception ignored) {}
                    try { ps.totalSpent       = Double.parseDouble(parts[9]);  } catch (Exception ignored) {}
                    try { ps.transactionsCount = Integer.parseInt(parts[10]); } catch (Exception ignored) {}
                }
                if (parts.length >= 17) {
                    try { ps.bansCount         = Integer.parseInt(parts[11]); } catch (Exception ignored) {}
                    try { ps.mutesCount        = Integer.parseInt(parts[12]); } catch (Exception ignored) {}
                    try { ps.warnsCount        = Integer.parseInt(parts[13]); } catch (Exception ignored) {}
                    try { ps.lastPunishmentAt  = Long.parseLong(parts[14]);  } catch (Exception ignored) {}
                    ps.lastPunishmentType = parts[15];
                    try { ps.punishmentScore   = Integer.parseInt(parts[16]); } catch (Exception ignored) {}
                }
            }
            return ps;
        } catch (Exception e) {
            return null;
        }
    }
}