#include <Wire.h>
#include <U8g2lib.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include "MAX30100_PulseOximeter.h"

// --- CONFIGURATION MATÉRIELLE (MODIFIÉE) ---
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
Adafruit_MPU6050 mpu;
PulseOximeter pox;

// Nouvelles broches assignées
#define PIN_LED_R 19
#define PIN_LED_G 18
#define PIN_LED_B 5
#define PIN_BOUTON_SWIPE 14

// --- VARIABLES SYSTÈME ---
uint32_t tsLastReport = 0;
uint32_t tsLastGraphUpdate = 0;
int pageActuelle = 0; 

// Variables Santé
int monBPM = 0;
int monSPO2 = 0;
#define SCREEN_WIDTH 128
#define GRAPH_BASELINE 55 
int pointsY[SCREEN_WIDTH];
float t_wave = 0.0;

// Variables Capteur MPU6050 et Posture
float accX = 0, accY = 0, accZ = 0;
float gyroX = 0, gyroY = 0, gyroZ = 0;
String postureTexte = "DEBOUT";

void onBeatDetected() { 
    Serial.println("♥ Battement détecté !"); 
}

void fixerCouleurRGB(int r, int g, int b) {
    digitalWrite(PIN_LED_R, r);
    digitalWrite(PIN_LED_G, g);
    digitalWrite(PIN_LED_B, b);
}

void setup() {
    Serial.begin(115200);

    // Configuration des nouvelles broches
    pinMode(PIN_LED_R, OUTPUT);
    pinMode(PIN_LED_G, OUTPUT);
    pinMode(PIN_LED_B, OUTPUT);
    pinMode(PIN_BOUTON_SWIPE, INPUT_PULLUP);

    u8g2.begin();
    u8g2.setBusClock(400000); 

    if (!mpu.begin()) { Serial.println("MPU6050 FAIL"); }
    mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
    mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

    if (!pox.begin()) { Serial.println("MAX30100 FAIL"); for(;;); }
    pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
    pox.setOnBeatDetectedCallback(onBeatDetected);

    for (int i = 0; i < SCREEN_WIDTH; i++) pointsY[i] = GRAPH_BASELINE;
}

void loop() {
    pox.update(); 

    // 1. GESTION DU SWIPE (Broche 14)
    if (digitalRead(PIN_BOUTON_SWIPE) == LOW) {
        delay(50); 
        pageActuelle = !pageActuelle; 
        while(digitalRead(PIN_BOUTON_SWIPE) == LOW) { pox.update(); } 
    }

    // 2. LECTURE DES CAPTEURS ET CALCUL DE LA POSTURE
    sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);
    accX = a.acceleration.x;
    accY = a.acceleration.y;
    accZ = a.acceleration.z;
    gyroX = g.gyro.x;
    gyroY = g.gyro.y;
    gyroZ = g.gyro.z;

    if (accZ > 8.0) postureTexte = "SUR LE DOS";
    else if (accZ < -8.0) postureTexte = "SUR LE VENTRE";
    else if (abs(accY) > 7.0 || abs(accX) > 7.0) postureTexte = "DEBOUT";
    else postureTexte = "INCLINE";

    // 3. LOGIQUE LED RGB
    if (postureTexte == "DEBOUT") {
        if (monBPM > 0) fixerCouleurRGB(LOW, HIGH, LOW); // VERT (Pouls ok)
        else fixerCouleurRGB(HIGH, HIGH, LOW);           // JAUNE (Recherche pouls)
    } else {
        fixerCouleurRGB(HIGH, LOW, HIGH); // MAUVE (Allongé / Incliné)
    }

    // 4. MISE À JOUR COURBE BPM
    if (millis() - tsLastGraphUpdate > 15) {
        tsLastGraphUpdate = millis();
        for (int i = 0; i < SCREEN_WIDTH - 1; i++) pointsY[i] = pointsY[i + 1];
        if (monBPM > 0) {
            float yOffset = (t_wave < PI) ? sin(t_wave) * 20.0 : 0;
            pointsY[SCREEN_WIDTH - 1] = GRAPH_BASELINE - yOffset;
            t_wave += 0.25; if (t_wave > 2.2 * PI) t_wave = 0;
        } else { pointsY[SCREEN_WIDTH - 1] = GRAPH_BASELINE; }
    }

    // 5. AFFICHAGE OLED (Toutes les 1 seconde)
    if (millis() - tsLastReport > 1000) {
        tsLastReport = millis();
        monBPM = (int)pox.getHeartRate();
        monSPO2 = (int)pox.getSpO2();

        u8g2.firstPage();
        do {
            pox.update(); 
            if (pageActuelle == 0) { 
                // --- PAGE 1 : SANTÉ ---
                u8g2.setFont(u8g2_font_6x10_tf);
                u8g2.drawStr(5, 10, "BPM:"); u8g2.setCursor(32, 11); u8g2.print(monBPM);
                u8g2.drawStr(70, 10, "O2:"); u8g2.setCursor(90, 11); u8g2.print(monSPO2); u8g2.print("%");
                u8g2.drawHLine(0, 14, 128);
                for (int i = 0; i < SCREEN_WIDTH - 1; i++) u8g2.drawLine(i, pointsY[i], i + 1, pointsY[i + 1]);
            } 
            else { 
                // --- PAGE 2 : GYROSCOPE & ACCÉLÉROMÈTRE ---
                u8g2.setFont(u8g2_font_6x10_tf);
                u8g2.drawStr(20, 10, "ACCEL / GYRO");
                u8g2.drawHLine(0, 13, 128);
                
                u8g2.setFont(u8g2_font_5x7_tr);
                // Affichage Accéléromètre
                u8g2.setCursor(0, 25);  u8g2.print("Acc X: "); u8g2.print(accX, 1);
                u8g2.setCursor(0, 35);  u8g2.print("Acc Y: "); u8g2.print(accY, 1);
                u8g2.setCursor(0, 45);  u8g2.print("Acc Z: "); u8g2.print(accZ, 1);
                
                // Affichage Gyroscope
                u8g2.setCursor(68, 25); u8g2.print("Gyr X: "); u8g2.print(gyroX, 1);
                u8g2.setCursor(68, 35); u8g2.print("Gyr Y: "); u8g2.print(gyroY, 1);
                u8g2.setCursor(68, 45); u8g2.print("Gyr Z: "); u8g2.print(gyroZ, 1);

                // Rappel posture
                u8g2.setFont(u8g2_font_6x10_tf);
                u8g2.setCursor(0, 60); u8g2.print("Etat: "); u8g2.print(postureTexte);
            }
        } while (u8g2.nextPage());
    }
}
