#ifndef ECHEM_H
#define ECHEM_H

#include <stdint.h>

#define ECHEM_MAX_POINTS 500

typedef enum {
    LP_RTIA_200  = 0,
    LP_RTIA_1K,
    LP_RTIA_2K,
    LP_RTIA_3K,
    LP_RTIA_4K,
    LP_RTIA_6K,
    LP_RTIA_8K,
    LP_RTIA_10K,
    LP_RTIA_12K,
    LP_RTIA_16K,
    LP_RTIA_20K,
    LP_RTIA_24K,
    LP_RTIA_30K,
    LP_RTIA_32K,
    LP_RTIA_40K,
    LP_RTIA_48K,
    LP_RTIA_64K,
    LP_RTIA_85K,
    LP_RTIA_96K,
    LP_RTIA_100K,
    LP_RTIA_120K,
    LP_RTIA_128K,
    LP_RTIA_160K,
    LP_RTIA_196K,
    LP_RTIA_256K,
    LP_RTIA_512K,
    LP_RTIA_COUNT
} EchemLpRtia;

typedef struct {
    float v_start;      /* mV, cell potential start */
    float v_stop;       /* mV, cell potential stop */
    float scan_rate;    /* mV/s */
    EchemLpRtia lp_rtia;
} LSVConfig;

typedef struct {
    float v_mv;         /* mV, applied cell potential */
    float i_ua;         /* uA, measured current */
} LSVPoint;

typedef struct {
    float v_hold;       /* mV, applied cell potential */
    float interval_ms;  /* sampling interval */
    float duration_s;   /* total duration, 0 = until stopped */
    EchemLpRtia lp_rtia;
} AmpConfig;

typedef struct {
    float t_ms;         /* timestamp */
    float i_ua;         /* uA, measured current */
} AmpPoint;

/* Chlorine: multi-step chronoamperometry on Au/Ag */
typedef struct {
    float v_cond;       /* mV, conditioning potential (surface cleaning) */
    float t_cond_ms;    /* ms, conditioning duration */
    float v_free;       /* mV, free chlorine measurement potential */
    float v_total;      /* mV, total chlorine measurement potential */
    float t_dep_ms;     /* ms, deposition/settling time per step */
    float t_meas_ms;    /* ms, measurement sampling time per step */
    EchemLpRtia lp_rtia;
} ClConfig;

#define CL_PHASE_COND  0
#define CL_PHASE_FREE  1
#define CL_PHASE_TOTAL 2

typedef struct {
    float t_ms;
    float i_ua;
    uint8_t phase;
} ClPoint;

typedef struct {
    float i_free_ua;
    float i_total_ua;
} ClResult;

/* pH: open circuit potentiometry on Au/Ag */
typedef struct {
    float stabilize_s;  /* seconds to wait for OCP stabilization */
    float temp_c;       /* temperature for Nernst calculation */
} PhConfig;

typedef struct {
    float v_ocp_mv;     /* measured OCP: V(SE0) - V(RE0) */
    float ph;           /* Nernst-derived pH */
    float temp_c;       /* temperature used */
} PhResult;

typedef int (*lsv_point_cb_t)(uint16_t idx, float v_mv, float i_ua);
typedef int (*amp_point_cb_t)(uint16_t idx, float t_ms, float i_ua);
typedef int (*cl_point_cb_t)(uint16_t idx, float t_ms, float i_ua, uint8_t phase);

int echem_clean(float v_mv, float duration_s);

void echem_default_lsv(LSVConfig *cfg);
void echem_default_amp(AmpConfig *cfg);
void echem_default_cl(ClConfig *cfg);
void echem_default_ph(PhConfig *cfg);

uint32_t echem_lsv_calc_steps(const LSVConfig *cfg, uint32_t max_points);
int echem_lsv(const LSVConfig *cfg, LSVPoint *out, uint32_t max_points, lsv_point_cb_t cb);
int echem_amp(const AmpConfig *cfg, AmpPoint *out, uint32_t max_points, amp_point_cb_t cb);
int echem_chlorine(const ClConfig *cfg, ClPoint *out, uint32_t max_points, ClResult *result, cl_point_cb_t cb);
int echem_ph_ocp(const PhConfig *cfg, PhResult *result);

#endif
