#ifndef CONFIG_MODBUS_H
#define CONFIG_MODBUS_H

#include <macros.h>

//////////////////////////////////////////////////////////////////
//
// Commons
//
#define MB_PRINT_ERRORS true
#define MAX_MODBUS_COMPONENTS 280
#define RS485_LOOP_INTERVAL_MS 50

// Baudrate for RS485/Modbus communication (must be equal, for that modbus network)
#define MB_RTU_BAUDRATE 38400

//////////////////////////////////////////////////////////////////
//
// Modbus RTU
//
// Serial configuration
#define MODBUS_SERIAL_MODE SERIAL_8N1
#define MODBUS_SERIAL_TIMEOUT 1000

//@todo : Modbus max slave ids
#define MAX_MODBUS_SLAVES 32
#define MAX_ADDRESSES_PER_SLAVE 32
#define MAX_PENDING_OPERATIONS 24
#define MAX_HIGH_PRIORITY_OPERATIONS 16

// Filter Constants
#define FILTER_RATE_LIMIT_MIN_INTERVAL 10

// Delay constants
#define DELAY_SERIAL_INIT 500  // ms to wait for serial initialization
#define DELAY_CLIENT_INIT 1000 // ms to wait for client initialization
#define DELAY_RESET_PAUSE 200  // ms to pause during reset

#define MAX_READ_BLOCKS 16

#define PRIORITY_HIGHEST 100
#define PRIORITY_HIGH 80
#define PRIORITY_MEDIUM 60
#define PRIORITY_LOW 40
#define PRIORITY_LOWEST 20

// Maximum registers per device
#define MAX_INPUT_REGISTERS 16
#define MAX_OUTPUT_REGISTERS 8

// Modbus coil values
#define COIL_ON 0xFF00  // Proper Modbus value for coil ON
#define COIL_OFF 0x0000 // Proper Modbus value for coil OFF

// Operation timing
#define OPERATION_TIMEOUT 2500

// Define pins for RS485 communication
// Define the actual GPIO numbers used for RX and TX on your ESP32 board for Serial1
#define TXD1 17
#define RXD1 18

#define RXD1_PIN RXD1
#define TXD1_PIN TXD1

// Define the HardwareSerial instance to use for RS485
#define RS485_SERIAL_PORT Serial1 // Use Serial1

// Try with an explicit DE/RE pin - GPIO_NUM_4 is often used for this
#define REDEPIN_MODBUS GPIO_NUM_4

// Define maximum array sizes for fixed arrays if not already defined
#ifndef MAX_ADDRESSES_PER_SLAVE
#define MAX_ADDRESSES_PER_SLAVE 16
#endif

// Add constants from ModbusRTU.h
#define MAX_RETRIES 3

// Define flags for ModbusOperation status
#define OP_USED_BIT 0          // Bit for Used flag
#define OP_HIGH_PRIORITY_BIT 1 // Bit for High Priority flag
#define OP_IN_PROGRESS_BIT 2   // Bit for In Progress flag
#define OP_BROADCAST_BIT 3     // Bit for Broadcast flag
#define OP_SYNCHRONIZED_BIT 4  // Bit for Synchronized flag

///////////////////////////////////////////////////////////////
//
// Components
//
#define OMRON_E5_READ_BLOCK_INTERVAL 50

///////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
//
// Modbus TCP Port
//
#define MODBUS_PORT 502 // Standard Modbus TCP port

//////////////////////////////////////////////////////////////////
//
// System Level Registers - TCP

#define MAX_REGISTERS 256

#define MB_ADDR_SYSTEM_ERROR 0               // R - System-wide error code
#define MB_ADDR_APP_STATE 1                  // R - Application state (see PHApp::APP_STATE)
#define MB_ADDR_SUB_STATE_0 2                // R - Primary sub system state
#define MB_ADDR_SUB_STATE_1 3                // R - Secondary sub system state
#define MB_ADDR_IS_SLAVE 4                   // R/W - Is Slave
#define MB_ADDR_ALL_OMRON_STOP 5             // R/W - All Omrons Stop
#define MB_ADDR_ALL_OMRON_COM_WRITE 6        // R/W - All Omrons Com Write
#define MB_ADDR_CMD_WRITE 7                  // R/W - PHApp Command Write
#define MB_ADDR_ECHO_TEST 8                  // R/W - Echo test
#define MB_ADDR_MEM_FREE_HEAP_KB 10          // R - Free Heap (kB)
#define MB_ADDR_MEM_MAX_FREE_BLOCK_KB 11     // R - Max Free Block (kB)
#define MB_ADDR_MEM_FRAGMENTATION_PERCENT 12 // R - Heap Fragmentation (%)
#define MB_ADDR_APP_WARMUP 13                // R/W - Enable Warmup for temperature profiles
#define MB_ADDR_APP_PID_LAG 14               // R/W - Enable lag compensation for PID SP

#define MB_ADDR_SYSTEM_END 20
#define MB_ADDR_LOGGER_0 36          // R/W - Logger 0
#define MB_ADDR_RESET_CONTROLLER 100 // W - Write any value to reset

#define MB_ADDR_MB_MIRROR_START 150 // Modbus Mirror Start Address

#define MB_ADDR_SETTINGS_BASE 800 // R/W - Settings Address Base

// Auxiliary Registers
#define MB_ADDR_AUX_0 MB_ADDR_SYSTEM_END
#define MB_ADDR_AUX_1 MB_ADDR_AUX_0 + 4
#define MB_ADDR_AUX_2 MB_ADDR_AUX_0 + 8
#define MB_ADDR_AUX_3 MB_ADDR_AUX_0 + 12
#define MB_ADDR_AUX_4 MB_ADDR_AUX_0 + 16
#define MB_ADDR_AUX_5 MB_ADDR_AUX_0 + 20
#define MB_ADDR_AUX_6 MB_ADDR_AUX_0 + 24
#define MB_ADDR_AUX_7 MB_ADDR_AUX_0 + 28
#define MB_ADDR_AUX_8 MB_ADDR_AUX_0 + 32
#define MB_ADDR_AUX_9 MB_ADDR_AUX_0 + 36

#define MB_ADDR_SOLENOID_0 40 // R/W - Address for Solenoid 0
#define MB_ADDR_SOLENOID_1 44 // R/W - Address for Solenoid 1

#define MB_ADDR_AUX_TEST_NV 1001    // R/W - Test NetworkValue
#define MB_ADDR_AUX_TEST_NV_PB 1500 // R/W - Test NetworkValue with Protobuf

#define MB_COIL_RELAY_0 51 // R/W - Address for Relay with ID COMPONENT_KEY_MB_RELAY_0
#define MB_COIL_RELAY_1 52 // R/W - Address for Relay with ID COMPONENT_KEY_MB_RELAY_1
#define MB_COIL_RELAY_2 53 // R/W - Address for Relay with ID COMPONENT_KEY_MB_RELAY_2

#define MB_IREG_ANALOG_0 400 // R - Address for Analog Input 0
#define MB_IREG_ANALOG_1 401 // R - Address for Analog Input 1
#define MB_IREG_ANALOG_2 402 // R - Address for Analog Input 2

#define MB_IREG_3POS_SWITCH_0 501 // R - Address for 3-Pos Switch 0
#define MB_IREG_3POS_SWITCH_1 502 // R - Address for 3-Pos Switch 1

#define MB_ADDR_FEEDBACK_0 80        // R/W - Address for Feedback 0
#define MB_ADDR_FEEDBACK_1 90        // R/W - Address for Feedback 1
#define MB_ADDR_PRESS_CYLINDER_0 700 // R/W - Address for Press Cylinder 0

#define MB_ADDR_AUX_END MB_ADDR_AUX_0 + 40

#define MB_HREG_PID_0_PV 100    // R   - PID 0 Process Value
#define MB_HREG_PID_0_SP 101    // R/W - PID 0 Setpoint
#define MB_HREG_PID_0_STATE 102 // R   - PID 0 State

#define MB_HREG_PID_1_PV 103    // R   - PID 1 Process Value
#define MB_HREG_PID_1_SP 104    // R/W - PID 1 Setpoint
#define MB_HREG_PID_1_STATE 105 // R   - PID 1 State

#define MB_HREG_LOADCELL_MB_START 360 // R   - Loadcell Base Address

// Monitoring & Feedback Addresses (placeholder addresses, verify usage)
// These were originally calculated relative to other offsets in enums.h
// Define them explicitly here for now.
#define MB_MONITORING_STATUS_FEEDBACK_0 701 // R? R/W? - Address for StatusLight 0
#define MB_MONITORING_STATUS_FEEDBACK_1 702 // R? R/W? - Address for StatusLight 1

////////////////////////////////////////////////////////////////////////////////
//
// Omron Pids - E5.x series - Modbus interface
//
#define OMRON_MB_TCP_OFFSET 1000
////////////////////////////////////////////////////////////////////////////////
//
// Built-in PIDs
//
#define MB_HREG_PID_2_BASE_ADDRESS 6100
#define PID_2_REGISTER_COUNT 12
// AmperageBudgetManager addresses
#define MB_ADDR_AMPERAGE_BUDGET_BASE 0x1000 // Base address for AmperageBudgetManager

#define MB_ADDR_AMPERAGE_BUDGET_ENABLE 0x1000      // Coil: Enable/Disable
#define MB_ADDR_AMPERAGE_BUDGET_INFO 0x1001        // Holding: Status info
#define MB_ADDR_AMPERAGE_BUDGET_MIN_TIME 0x1002    // Holding: Min heating time (ms)
#define MB_ADDR_AMPERAGE_BUDGET_MAX_TIME 0x1003    // Holding: Max heating time (ms)
#define MB_ADDR_AMPERAGE_BUDGET_MAX_SIM 0x1004     // Holding: Max simultaneous heating
#define MB_ADDR_AMPERAGE_BUDGET_OFFSET 0x1005      // Holding: Window offset
#define MB_ADDR_AMPERAGE_BUDGET_START_INDEX 0x1006 // Holding: Start index for device cycling
#define MB_ADDR_AMPERAGE_BUDGET_END_INDEX 0x1007   // Holding: End index for device cycling
#define MB_ADDR_AMPERAGE_BUDGET_MODE 0x1008        // Holding: Set cycling mode

////////////////////////////////////////////////////////////////////////////////
//
// Plot Profiles
//
// Base address for the first temperature profile instance's registers
#define MB_HREG_TEMP_PROFILE_BASE 200

// Base address for the first pressure profile instance's registers
#define MB_HREG_PRESSURE_PROFILE_BASE 300

// Base address for the first signal plot instance's registers
#define MB_HREG_SIGNAL_PLOT_BASE 500

// Offline backoff configuration

#define MB_OFFLINE_BACKOFF_INITIAL SECS * 10 // Initial backoff: 10 seconds
#define MB_OFFLINE_BACKOFF_MAX SECS * 30     // Maximum backoff: 30 seconds
#define MB_OFFLINE_BACKOFF_MULTIPLIER 2      // Double the interval each time

#endif // CONFIG_MODBUS_H