#ifndef DRILL_SPEED_SUPERVISOR_H
#define DRILL_SPEED_SUPERVISOR_H

#include <stdbool.h>
#include <stdint.h>

#define DS_LISTING_MAX_RPM 50000u
#define DS_BEGINNER_MAX_RPM 30000u

typedef enum {
    DS_DISABLED = 0,
    DS_RUNNING,
    DS_REVERSAL_WAIT,
    DS_FAULT
} ds_state;

typedef enum {
    DS_FAULT_NONE = 0,
    DS_FAULT_CONFIG,
    DS_FAULT_SERVICE_GAP,
    DS_FAULT_FEEDBACK_STALE,
    DS_FAULT_INTERLOCK,
    DS_FAULT_DRIVER,
    DS_FAULT_OVERSPEED,
    DS_FAULT_TARGET
} ds_fault;

typedef struct {
    uint32_t max_rpm;                 /* Never above the linked 50,000 rpm claim. */
    uint32_t current_limit_ma;        /* Must come from the verified motor/system limit. */
    uint32_t feedback_max_age_ms;
    uint32_t max_service_gap_ms;
    uint32_t ramp_rpm_per_s;          /* EVT tuning value, not a product measurement. */
    uint32_t zero_speed_rpm;          /* Reversal interlock threshold, needs calibration. */
    uint32_t zero_speed_dwell_ms;
    uint32_t kp_q16_ma_per_rpm;
    uint32_t ki_q16_ma_per_rpm_s;
} ds_config;

typedef struct {
    bool power_ok;
    bool driver_ready;
    bool observer_locked;
    bool current_calibrated;
    bool hardware_fault;              /* Includes DRV nFAULT/TIM1 break. */
    bool overcurrent_fault;
    bool regen_permitted;             /* Only true after battery/BMS absorption is verified. */
    bool handpiece_sensor_ok;         /* HAL has validated the park sensor input. */
    bool handpiece_parked;            /* Normalized active state from HANDPIECE_MAGNET_PARK. */
    int32_t measured_rpm;             /* Signed estimate from a validated FOC observer/sensor. */
    uint32_t measured_at_ms;
} ds_inputs;

typedef struct {
    ds_state state;
    ds_fault fault;
    bool run_enable;
    bool beginner_mode;
    uint32_t active_speed_limit_rpm;
    int32_t ramped_target_rpm;
    int32_t q_current_ref_ma;         /* Request to an inner current loop; never raw PWM. */
} ds_output;

typedef struct {
    ds_config cfg;
    ds_state state;
    ds_fault fault;
    bool configured;
    bool beginner_mode;
    bool zero_timer_active;
    int8_t direction;
    uint32_t last_service_ms;
    uint32_t zero_since_ms;
    uint32_t ramp_remainder;
    int32_t target_rpm;
    int32_t ramped_target_rpm;
    int64_t integral_q16_ma;
    int32_t q_current_ref_ma;
} ds_supervisor;

/* This module supervises an already-started closed-loop motor controller.
   Rotor alignment/open-loop startup, FOC, ADC timing, and TIM1 PWM remain target work. */
bool ds_init(ds_supervisor *s, const ds_config *cfg, uint32_t now_ms);
/* Speed mode changes are accepted only while stopped; no live mode jump. */
bool ds_set_beginner_mode(ds_supervisor *s, bool enabled);
bool ds_start(ds_supervisor *s, int32_t target_rpm, uint32_t now_ms,
              const ds_inputs *inputs);
ds_output ds_update(ds_supervisor *s, int32_t target_rpm, uint32_t now_ms,
                    const ds_inputs *inputs);
void ds_stop(ds_supervisor *s);
bool ds_clear_fault(ds_supervisor *s, uint32_t now_ms,
                    const ds_inputs *inputs);

#endif
