#ifndef PROJECT_CHARGE_MANAGER_H
#define PROJECT_CHARGE_MANAGER_H

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

/* HUSB238 snapshot values come from registers 0x00, 0x01 and 0x02. */
typedef struct {
    uint8_t pd_status0;
    uint8_t pd_status1;
    uint8_t src_pdo_5v;
    uint16_t vbus_mv;      /* BQ25798 VBUS ADC, register 0x35/0x36. */
    uint16_t snapshot_age_ms;
    bool source_read_ok;
    bool charger_read_ok;
    bool pack_and_ntc_valid; /* Must include BQ TS status and pack checks. */
    bool charger_fault_free;
} charge_observation;

typedef enum {
    CHARGE_DETACHED = 0,
    CHARGE_ACTIVE,
    CHARGE_SOURCE_UNKNOWN,
    CHARGE_UNSUPPORTED_VOLTAGE,
    CHARGE_VBUS_MISMATCH,
    CHARGE_PACK_OR_TEMPERATURE_FAULT,
    CHARGE_CHARGER_FAULT,
    CHARGE_IO_ERROR,
    CHARGE_INVALID_ARGUMENT
} charge_state;

typedef struct {
    void *ctx;
    /* enabled=true pulls BQ25798 CE low. Hardware pull-up defaults to disabled. */
    bool (*set_charge_enabled)(void *ctx, bool enabled);
    bool (*set_input_limit_ma)(void *ctx, uint16_t milliamps);
    bool (*set_charge_limit_ma)(void *ctx, uint16_t milliamps);
    /* Controls BQ25798 REG14.EN_EXTILIM (bit 1); true restores ILIM_HIZ clamp. */
    bool (*set_external_ilim_enabled)(void *ctx, bool enabled);
} charge_hal;

typedef struct {
    charge_state state;
    bool active;
    uint16_t source_limit_ma;
    uint16_t programmed_input_limit_ma;
    uint16_t programmed_charge_limit_ma;
} charge_report;

/* Decode only source states supported by this product: USB PD 5V/9V or
 * detected legacy/Type-C 5V. The result includes a 10% system-load margin
 * and a hard 2A product ceiling. */
bool charge_decode_source(uint8_t pd_status0, uint8_t pd_status1,
                          uint8_t src_pdo_5v, uint16_t *voltage_mv,
                          uint16_t *current_limit_ma);

/* Main-loop service function. Call after a fresh USB/charger status snapshot.
 * The output remains disabled for stale/invalid/unsafe observations and on any
 * write failure. Poll at >=20 ms; reject snapshots older than 500 ms. Do not
 * call from an ISR. */
charge_state charge_manager_step(const charge_hal *hal,
                                 const charge_observation *observation,
                                 charge_report *report);

/* BQ25798 REG06 IINDPM encoding: 100-3300mA, 10mA/LSB. */
bool bq25798_encode_iindpm(uint16_t requested_ma, uint16_t *register_value,
                           uint16_t *applied_ma);

#endif
