package de.simolzimol.mclogger.consent;

import java.util.List;

import org.bukkit.configuration.file.FileConfiguration;

/**
 * Strongly-typed wrapper around the plugin's {@code config.yml}.
 * Call {@link #reload()} after {@link ConsentPlugin#reloadConfig()} to
 * pick up any changes.
 *
 * @author SimolZimol
 */
public class ConsentConfig {

    /** Enforcement modes for the plugin. */
    public enum EnforcementMode {
        /** Kick the player at login if they have no stored consent. */
        KICK,
        /**
         * Let the player join but freeze them until they accept.
         * Kicks after the grace period if still pending.
         */
        HOLD,
        /** Allow full access; send periodic reminders but never kick. */
        REMIND
    }

    private final ConsentPlugin plugin;
    private FileConfiguration   cfg;

    public ConsentConfig(ConsentPlugin plugin) {
        this.plugin = plugin;
        reload();
    }

    /** Re-reads the YAML file into memory. */
    public void reload() {
        plugin.reloadConfig();
        cfg = plugin.getConfig();
    }

    // ── Global ───────────────────────────────────────────────

    public boolean isEnabled() {
        return cfg.getBoolean("enabled", true);
    }

    // ── Database ─────────────────────────────────────────────

    public String getDbHost()     { return cfg.getString("database.host",     "localhost"); }
    public int    getDbPort()     { return cfg.getInt   ("database.port",     3306);        }
    public String getDbDatabase() { return cfg.getString("database.database", "mclogger");  }
    public String getDbUsername() { return cfg.getString("database.username", "mclogger");  }
    public String getDbPassword() { return cfg.getString("database.password", "");          }
    public boolean isDbSsl()      { return cfg.getBoolean("database.ssl",     false);       }
    public int    getDbPoolSize() { return cfg.getInt   ("database.pool-size", 5);          }

    // ── Consent settings ─────────────────────────────────────

    public String getPolicyVersion() {
        return cfg.getString("consent.policy-version", "1.0");
    }

    public String getPolicyUrl() {
        return cfg.getString("consent.policy-url", "https://example.com/privacy-policy");
    }

    public EnforcementMode getEnforcementMode() {
        String raw = cfg.getString("consent.enforcement-mode", "HOLD");
        try {
            return EnforcementMode.valueOf(raw.toUpperCase());
        } catch (IllegalArgumentException e) {
            plugin.getLogger().warning(
                    "[MCConsent] Unknown enforcement-mode '" + raw + "' – defaulting to HOLD.");
            return EnforcementMode.HOLD;
        }
    }

    /** Display name for the consent command used in prompt text. */
    public String getCommand() {
        return cfg.getString("consent.command", "consent");
    }

    /** Seconds before a HOLD-mode player is kicked for not consenting (0 = infinite). */
    public int getGracePeriodSeconds() {
        return cfg.getInt("consent.grace-period-seconds", 120);
    }

    /** Seconds between reminder messages in REMIND mode (0 = once on join only). */
    public int getReminderIntervalSeconds() {
        return cfg.getInt("consent.reminder-interval-seconds", 300);
    }

    /** Minimum seconds between move-blocked messages (avoids chat spam). */
    public int getMoveMessageCooldownSeconds() {
        return cfg.getInt("consent.move-message-cooldown-seconds", 5);
    }

    /** Worlds listed here are exempt from consent enforcement. */
    public List<String> getExemptWorlds() {
        return cfg.getStringList("consent.exempt-worlds");
    }

    public String getBypassPermission() {
        return cfg.getString("consent.bypass-permission", "consent.bypass");
    }

    // ── Admin settings ───────────────────────────────────────

    public boolean isLogToMCLoggerDb() {
        return cfg.getBoolean("admin.log-to-mclogger-db", true);
    }

    public boolean isNotifyAdmins() {
        return cfg.getBoolean("admin.notify-admins", false);
    }

    public String getAdminPermission() {
        return cfg.getString("admin.admin-permission", "consent.admin");
    }

    // ── Messages ─────────────────────────────────────────────

    public String getPrefix()              { return cfg.getString("messages.prefix",               "<gold>[Privacy]</gold> "); }
    public String getMsgJoinPrompt()       { return cfg.getString("messages.join-prompt",           "Please accept our Privacy Policy. Type /{command} accept"); }
    public String getMsgAccepted()         { return cfg.getString("messages.accepted",              "<green>Thank you for accepting the Privacy Policy!</green>"); }
    public String getMsgDeclined()         { return cfg.getString("messages.declined",              "<red>You declined the Privacy Policy.</red>"); }
    public String getMsgKick()             { return cfg.getString("messages.kick-message",          "Privacy Policy consent required.\nVisit: {url}\nReconnect and type /{command} accept."); }
    public String getMsgDeclineKick()      { return cfg.getString("messages.decline-kick-message",  "You declined the Privacy Policy."); }
    public String getMsgGraceKick()        { return cfg.getString("messages.grace-kick-message",    "Consent timeout.\nVisit: {url}\nReconnect and type /{command} accept."); }
    public String getMsgHoldMoveBlocked()  { return cfg.getString("messages.hold-move-blocked",     "<red>Accept the Privacy Policy first! Type /{command} accept</red>"); }
    public String getMsgHoldChatBlocked()  { return cfg.getString("messages.hold-chat-blocked",     "<red>You cannot chat until you accept the Privacy Policy.</red>"); }
    public String getMsgHoldCmdBlocked()   { return cfg.getString("messages.hold-command-blocked",  "<red>Commands disabled until you accept the Privacy Policy.</red>"); }
    public String getMsgAlreadyAccepted()  { return cfg.getString("messages.already-accepted",      "<green>You have already accepted the current Privacy Policy.</green>"); }
    public String getMsgNoConsentNeeded()  { return cfg.getString("messages.no-consent-required",   "<gray>No consent is currently required.</gray>"); }
    public String getMsgGraceWarning()     { return cfg.getString("messages.grace-warning",         "<yellow>You have {seconds}s left to accept or you will be disconnected.</yellow>"); }
    public String getMsgAdminAccept()      { return cfg.getString("messages.admin-notify-accept",   "<dark_gray>[Consent] {player} accepted (v{version}).</dark_gray>"); }
    public String getMsgAdminDecline()     { return cfg.getString("messages.admin-notify-decline",  "<dark_gray>[Consent] {player} declined (v{version}).</dark_gray>"); }
    public String getMsgHelpHeader()       { return cfg.getString("messages.help-header",           "<gold><bold>===== MCConsent Help =====</bold></gold>"); }
    public String getMsgRemind()           { return cfg.getString("messages.remind-message",        "<yellow>Please accept our Privacy Policy. Type /{command} accept</yellow>"); }
    public String getMsgStatusAccepted()   { return cfg.getString("messages.status-accepted",       "<green>You have accepted the Privacy Policy (v{version}).</green>"); }
    public String getMsgStatusPending()    { return cfg.getString("messages.status-pending",        "<yellow>You have NOT yet accepted the Privacy Policy (v{version}).</yellow>"); }
    public String getMsgNoPermission()     { return cfg.getString("messages.no-permission",         "<red>You don't have permission to use this command.</red>"); }
    public String getMsgAdminNotifyConsent() { return cfg.getString("messages.admin-notify-consent", "<dark_gray>[Consent] {player} accepted the Privacy Policy (v{version}).</dark_gray>"); }
    public String getMsgWithdrawn()          { return cfg.getString("messages.withdrawn",             "<yellow>Your consent has been withdrawn. You will be disconnected.</yellow>"); }
    public String getMsgWithdrawKick()       { return cfg.getString("messages.withdraw-kick-message", "Consent withdrawn.\nYou may reconnect at any time and accept the Privacy Policy.\nVisit: {policy_url}"); }

    /** Whether a message should be sent to online admins when a player accepts. */
    public boolean isNotifyAdminsOnConsent() {
        return cfg.getBoolean("admin.notify-admins-on-consent", false);
    }

    /**
     * How many days to keep accepted  consent records (0 = keep forever).
     * GDPR Art. 5(1)(e) – storage limitation.
     */
    public int getConsentRetentionDays() {
        return cfg.getInt("consent.retention-days-consent", 1095); // 3 years default
    }

    /**
     * How many days to keep decline records (0 = keep forever).
     */
    public int getDeclineRetentionDays() {
        return cfg.getInt("consent.retention-days-declines", 1095);
    }

    /**
     * Returns the help text as a list of MiniMessage lines.
     * Falls back to a built-in list if not configured.
     */
    public List<String> getHelpLines() {
        List<String> lines = cfg.getStringList("messages.help-lines");
        if (!lines.isEmpty()) return lines;
        return List.of(
                getMsgHelpHeader(),
                "<gray>/consent accept</gray>   <white>Accept the Privacy Policy</white>",
                "<gray>/consent decline</gray>  <white>Decline and disconnect</white>",
                "<gray>/consent status</gray>   <white>Check your consent status</white>",
                "<gray>Policy: <aqua>{policy_url}</aqua>"
        );
    }

    /**
     * When {@code true}, kick messages are forwarded to the Velocity / BungeeCord
     * proxy via the {@code BungeeCord} plugin-messaging channel so the player is
     * removed from the entire network rather than just the current server.
     */
    public boolean isVelocityKick() {
        return cfg.getBoolean("consent.velocity-kick", false);
    }
}
