#include "config.h"
#include "globals.h"
#include <SD.h>
#include <string.h>
#include <ctype.h>
#include <strings.h>
#include <stdio.h>

// Global config instance
Config config;

const char* getConfigFilePath() {
    static char path[64];
    static bool init = false;
    if (!init) {
        // Build "/<sys_dir>/<config_file>" once into a static buffer
        snprintf(path, sizeof(path), "/%s/%s", sys_dir ? sys_dir : "", config_file ? config_file : "");
        init = true;
    }
    return path;
}

void setDefaultConfig() {
    config.initialVolume = 7;
    config.maxVolume = 15;
    config.sleepTime = 1800000;
    config.minVoltage = 3000;
    config.voltage100Percent = 4200;
    config.sleepDelay = 1800000;
    config.sleepMessageDelay = 1798000;
    config.rfidLoopInterval = 25;
    config.startAtStoredProgress = true;
    config.wifiSSID[0] = '\0';
    config.wifiPassword[0] = '\0';
}

bool loadConfig() {
    const char* configPath = getConfigFilePath();

    if (!SD.exists(configPath)) {
        Serial.println(F("Config file not found, using defaults"));
        setDefaultConfig();
        return saveConfig(); // Create config file with defaults
    }

    File file = SD.open(configPath, FILE_READ);
    if (!file) {
        Serial.println(F("Failed to open config file"));
        setDefaultConfig();
        return false;
    }

    // Set defaults first
    setDefaultConfig();

    // Parse config file line by line using a fixed-size buffer (no dynamic allocation)
    char line[160];
    while (true) {
        int idx = 0;
        int c;
        // Read characters until newline or EOF
        while (idx < (int)sizeof(line) - 1 && (c = file.read()) >= 0) {
            if (c == '\r') continue;
            if (c == '\n') break;
            line[idx++] = (char)c;
        }
        if (idx == 0 && c < 0) {
            // EOF with no more data
            break;
        }
        line[idx] = '\0';

        // Trim leading/trailing whitespace
        char* s = line;
        while (*s && isspace((unsigned char)*s)) ++s;
        char* end = s + strlen(s);
        while (end > s && isspace((unsigned char)end[-1])) --end;
        *end = '\0';

        // Skip empty lines and comments
        if (*s == '\0' || *s == '#') {
            if (c < 0) break;
            continue;
        }

        // Split at '='
        char* eq = strchr(s, '=');
        if (!eq) {
            if (c < 0) break;
            continue;
        }
        *eq = '\0';
        char* key = s;
        char* val = eq + 1;

        // Trim key
        while (*key && isspace((unsigned char)*key)) ++key;
        char* kend = key + strlen(key);
        while (kend > key && isspace((unsigned char)kend[-1])) --kend;
        *kend = '\0';

        // Trim val
        while (*val && isspace((unsigned char)*val)) ++val;
        char* vend = val + strlen(val);
        while (vend > val && isspace((unsigned char)vend[-1])) --vend;
        *vend = '\0';

        // Parse each configuration value
        if (strcmp(key, "initialVolume") == 0) {
            long v = strtol(val, nullptr, 10);
            if (v < 0) v = 0; if (v > 21) v = 21;
            config.initialVolume = (uint8_t)v;
        } else if (strcmp(key, "maxVolume") == 0) {
            long v = strtol(val, nullptr, 10);
            if (v < 1) v = 1; if (v > 21) v = 21;
            config.maxVolume = (uint8_t)v;
        } else if (strcmp(key, "sleepTime") == 0) {
            config.sleepTime = (uint32_t)strtoul(val, nullptr, 10);
        } else if (strcmp(key, "minVoltage") == 0) {
            config.minVoltage = (uint16_t)strtoul(val, nullptr, 10);
        } else if (strcmp(key, "voltage100Percent") == 0) {
            config.voltage100Percent = (uint16_t)strtoul(val, nullptr, 10);
        } else if (strcmp(key, "sleepDelay") == 0) {
            config.sleepDelay = (uint32_t)strtoul(val, nullptr, 10);
        } else if (strcmp(key, "sleepMessageDelay") == 0) {
            config.sleepMessageDelay = (uint32_t)strtoul(val, nullptr, 10);
        } else if (strcmp(key, "rfidLoopInterval") == 0) {
            long v = strtol(val, nullptr, 10);
            if (v < 1) v = 1; if (v > 255) v = 255;
            config.rfidLoopInterval = (uint8_t)v;
        } else if (strcmp(key, "startAtStoredProgress") == 0) {
            bool b = (strcmp(val, "1") == 0) || (strcasecmp(val, "true") == 0);
            config.startAtStoredProgress = b;
        } else if (strcmp(key, "wifiSSID") == 0) {
            strncpy(config.wifiSSID, val, sizeof(config.wifiSSID) - 1);
            config.wifiSSID[sizeof(config.wifiSSID) - 1] = '\0';
        } else if (strcmp(key, "wifiPassword") == 0) {
            strncpy(config.wifiPassword, val, sizeof(config.wifiPassword) - 1);
            config.wifiPassword[sizeof(config.wifiPassword) - 1] = '\0';
        }

        if (c < 0) break; // EOF after processing last line
    }

    file.close();

    Serial.println(F("Config loaded successfully"));
    Serial.print(F("Initial Volume: ")); Serial.println(config.initialVolume);
    Serial.print(F("Max Volume: ")); Serial.println(config.maxVolume);
    Serial.print(F("Sleep Delay: ")); Serial.println(config.sleepDelay);
    Serial.print(F("RFID Interval: ")); Serial.println(config.rfidLoopInterval);
    Serial.print(F("min Voltage: ")); Serial.println(config.minVoltage);

    return true;
}

bool saveConfig() {
    const char* configPath = getConfigFilePath();

    File file = SD.open(configPath, FILE_WRITE);
    if (!file) {
        Serial.println(F("Failed to create config file"));
        return false;
    }

    // Write config file with comments for user reference
    file.println(F("# HannaBox Conf File"));
    file.println(F("# format: key=value"));
    file.println();

    file.println(F("# Audio"));
    file.print(F("initialVolume=")); file.println(config.initialVolume);
    file.print(F("maxVolume=")); file.println(config.maxVolume);
    file.println();

    file.println(F("# Power Management (in milliseconds)"));
    file.print(F("sleepTime=")); file.println(config.sleepTime);
    file.print(F("sleepDelay=")); file.println(config.sleepDelay);
    file.print(F("sleepMessageDelay=")); file.println(config.sleepMessageDelay);
    file.println();

    file.println(F("# Battery (in millivolts)"));
    file.print(F("minVoltage=")); file.println(config.minVoltage);
    file.print(F("voltage100Percent=")); file.println(config.voltage100Percent);
    file.println();

    file.println(F("# RFID"));
    file.print(F("rfidLoopInterval=")); file.println(config.rfidLoopInterval);
    file.println();

    file.println(F("# Playback"));
    file.print(F("startAtStoredProgress=")); file.println(config.startAtStoredProgress ? F("true") : F("false"));
    file.println();

    file.println(F("# WiFi (leave empty to use current WiFiManager)"));
    file.print(F("wifiSSID=")); file.println(config.wifiSSID);
    file.print(F("wifiPassword=")); file.println(config.wifiPassword);

    file.close();

    Serial.println(F("Config saved successfully"));
    return true;
}
