#ifndef VACUUM_FAN_MANAGER_H
#define VACUUM_FAN_MANAGER_H

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

typedef enum {
    VACUUM_FAN_OK = 0,
    VACUUM_FAN_NOT_READY,
    VACUUM_FAN_STALE_SAMPLE,
    VACUUM_FAN_UNDERVOLTAGE,
    VACUUM_FAN_OVERVOLTAGE,
    VACUUM_FAN_OVERCURRENT,
    VACUUM_FAN_TACH_STALL,
    VACUUM_FAN_IO_FAILURE,
    VACUUM_FAN_OFF_UNCONFIRMED
} vacuum_fan_status_t;

typedef struct {
    uint32_t sample_age_ms;
    uint32_t now_ms;
    uint32_t vbus_mv;
    uint32_t fan_current_ma;
    uint32_t tach_edges_100ms;
    uint16_t control_duty_permille;
    bool measurement_valid;
    bool fan_profile_valid;
    bool run_requested;
} vacuum_fan_input_t;

typedef struct {
    uint32_t min_vbus_mv;
    uint32_t max_vbus_mv;
    uint32_t max_fan_current_ma;
    uint32_t max_sample_age_ms;
    uint32_t min_tach_edges_100ms;
    uint32_t tach_startup_grace_ms;
} vacuum_fan_limits_t;

typedef struct {
    void *context;
    int (*set_fan_power)(void *context, bool enabled);
    int (*set_control_duty_permille)(void *context, uint16_t duty_permille);
} vacuum_fan_io_t;

typedef struct {
    bool fan_power_enabled;
    bool fan_power_command_confirmed;
    bool fan_start_time_valid;
    uint32_t fan_started_at_ms;
    bool fault_latched;
    vacuum_fan_status_t status;
} vacuum_fan_manager_t;

/* Call before peripheral setup; the hardware switch itself is active-high and defaults off. */
void vacuum_fan_manager_init(vacuum_fan_manager_t *manager, const vacuum_fan_io_t *io);

/* Tach threshold and startup grace must come from the selected fan's measured profile.
 * The duty callback must implement the selected fan's electrical polarity and timing. */
vacuum_fan_status_t vacuum_fan_manager_step(vacuum_fan_manager_t *manager,
                                            const vacuum_fan_input_t *input,
                                            const vacuum_fan_limits_t *limits,
                                            const vacuum_fan_io_t *io);

#endif
