#pragma once

#include <Arduino.h>
#include <EEPROM.h>

#include "config.h"

// After TuningData (15 bytes) + checksum (1 byte) at address 0
static const uint16_t SETTINGS_MAGIC = 0xDA7F;
static const int SETTINGS_EEPROM_ADDR = 16;

struct SettingsData {
  uint16_t magic = 0;
  float targetC = TARGET_TEMP_C;
  uint8_t stirFanPwm = 0; // 0 = use FAN_STIR_PWM from config
};

inline uint8_t settingsChecksum(const SettingsData &data) {
  const uint8_t *bytes = reinterpret_cast<const uint8_t *>(&data);
  uint8_t sum = 0;
  for (uint8_t i = 0; i < sizeof(SettingsData) - 1; ++i) {
    sum ^= bytes[i];
  }
  return sum;
}

inline bool settingsLoad(SettingsData &out) {
  EEPROM.get(SETTINGS_EEPROM_ADDR, out);
  const uint8_t stored = EEPROM.read(SETTINGS_EEPROM_ADDR + sizeof(SettingsData));
  if (out.magic != SETTINGS_MAGIC) {
    return false;
  }
  return settingsChecksum(out) == stored;
}

inline void settingsSave(const SettingsData &data) {
  EEPROM.put(SETTINGS_EEPROM_ADDR, data);
  EEPROM.write(SETTINGS_EEPROM_ADDR + sizeof(SettingsData), settingsChecksum(data));
}

inline void settingsSaveTarget(float targetC) {
  SettingsData data;
  if (settingsLoad(data)) {
    data.targetC = targetC;
  } else {
    data.magic = SETTINGS_MAGIC;
    data.targetC = targetC;
    data.stirFanPwm = 0;
  }
  settingsSave(data);
}

inline void settingsSaveStirFan(uint8_t stirFanPwm) {
  SettingsData data;
  if (settingsLoad(data)) {
    data.stirFanPwm = stirFanPwm;
  } else {
    data.magic = SETTINGS_MAGIC;
    data.stirFanPwm = stirFanPwm;
  }
  settingsSave(data);
}

inline void settingsClear() {
  SettingsData cleared;
  settingsSave(cleared);
}
