#ifndef CONFIG_H
#define CONFIG_H

#include "secrets.h"
#include <Arduino.h>
#include <stdint.h>

#define FIRMWARE_VERSION "v1.0.0-stepper"

// --- Pin Definitions (ESP32-C6 Super Mini) ---
// TMC2209 Standalone Mode pins
#define PIN_STEPPER_EN 2   // GP2  - Enable (Active LOW)
#define PIN_STEPPER_STEP 4 // GP4  - Step
#define PIN_STEPPER_DIR 5  // GP5  - Direction

// Inputs
#define PIN_TOUCH 21 // GP21 - TTP223 Sensor (Active HIGH to toggle blind)

// Status LED
#define PIN_STATUS_LED -1 // Disabled

// --- Constants ---
#define SERIAL_BAUD 115200

// --- EEPROM Configuration ---
#define EEPROM_SIZE 2048
#define CONFIG_MAGIC 0x8BADF00D
#define CONFIG_VERSION 12 // V12 (safe mode + POSIX TZ)

// PACKED: Prevents compiler from inserting padding bytes between fields.
// This ensures the struct layout is deterministic across different compiler
// optimization flags, which is critical because the checksum covers the raw
// bytes. Without packing, an OTA compiled with different flags could change
// padding and invalidate the stored checksum.
struct __attribute__((packed)) ConfigData {
  uint32_t magic;
  uint32_t version;
  uint32_t checksum;

  bool setup_complete;

  // Stepper Limits (positions in steps). Can be negative.
  int32_t stepper_top_position;
  int32_t stepper_bottom_position;
  int32_t stepper_current_position; // Persisted across reboots
  uint32_t stepper_open_speed;      // Configurable max speed for opening

  // Motor Control Tuning
  uint32_t stepper_relax_steps;     // Tension relief steps after upward move (default 128)
  uint32_t stepper_stop_delay_ms;   // Motor idle timeout before disable (default 3000 ms)
  uint32_t stepper_acceleration;    // Acceleration/deceleration rate steps/s² (default 2000)

  // WiFi Credentials
  char wifi_ssid[33];
  char wifi_pass[65];

  // WiFi 6 TWT Power Saving
  bool twt_enabled;

  // MQTT Remote Access
  bool mqtt_enabled;
  char mqtt_broker[80];
  uint16_t mqtt_port;
  char mqtt_user[48];
  char mqtt_pass[64];
  char mqtt_device_id[16];
  
  // Timezone (auto-detected from Weather API)
  int32_t gmt_offset;
  int32_t daylight_offset;

  // Speed Configuration
  uint32_t stepper_close_speed;

  // Automation Rules — Sunset
  bool sunset_enabled;
  int32_t sunset_offset;
  int32_t sunset_target;

  bool presence_enabled;
  // Presence close timeout — how long the room must be empty before closing blinds.
  // Named "motion_timeout" for MQTT wire compatibility with the web app's "motionTimeout"
  // field. Zaylo splits this into separate motion_timeout (light) and presence_timeout
  // (blinds), but StepperMote only needs one since it's a blinds-only device.
  // Unit: SECONDS. Range: [60, 3600]. Default: 300 (5 minutes).
  int32_t motion_timeout;
  int32_t presence_target;
  int32_t presence_open_target;
  
  // Automation Rules — Presence
  uint8_t presence_action;      // 0 = close_only, 1 = open_close
  uint8_t presence_time_filter; // 0 = all, 1 = day, 2 = night

  bool morning_enabled;
  uint8_t morning_days;         // Bitmask: [Sat][Fri][Thu][Wed][Tue][Mon][Sun]
  uint8_t morning_time_h[7];   // Per-day wake-up hour   (index 0=Sun..6=Sat)
  uint8_t morning_time_m[7];   // Per-day wake-up minute
  int32_t morning_duration[7]; // Per-day gradual duration (minutes)
  int32_t morning_target[7];   // Per-day target position (0-100%)

  bool night_enabled;
  uint8_t night_days;           // Bitmask: [Sat][Fri][Thu][Wed][Tue][Mon][Sun]
  uint8_t night_time_h;
  uint8_t night_time_m;
  int32_t night_target;

  bool temp_enabled;
  int32_t temp_threshold;
  int32_t temp_target;

  char linked_device_id[16];

  // Boot crash counter — tracks consecutive firmware crashes.
  // If >= 3, the device enters safe mode on next boot.
  // Reset to 0 on normal boot or after safe mode recovery.
  uint8_t boot_crash_count;

  // POSIX timezone string for correct DST handling.
  // e.g., "GMT0BST,M3.5.0/1,M10.5.0" for UK.
  // Set via MQTT from the web app. Falls back to gmt_offset/daylight_offset
  // if empty (for backwards compatibility with devices not yet configured).
  char tz_posix[48];
};

extern ConfigData config;

static_assert(
    sizeof(ConfigData) * 2 + 16 + 4 <= EEPROM_SIZE,
    "ConfigData too large for EEPROM! Increase EEPROM_SIZE or shrink struct.");

#endif
