#include <Wire.h>
#include <SPI.h>
#include <Arduino.h>
#include "OutputPin.h"
#include "Display.h"
#include "Power.h"
#include "Storage.h"
#include "KeyFrame.h"
#include "Animation.h"

// #define EB_FAST 30     // таймаут быстрого поворота, мс
// #define EB_DEB 30      // дебаунс кнопки, мс
// #define EB_HOLD 1000   // таймаут удержания кнопки, мс
// #define EB_STEP 200    // период срабатывания степ, мс
// #define EB_CLICK 400   // таймаут накликивания, мс

#include "EncButton.h"

#define CALIBRATION false
#define DEFAULT_VOLTAGE_READ_DELAY 10000

Display display{};

Power power;

Storage storage;

unsigned long lastVoltageRead = 0;
unsigned long lastFPSUpdate = 0;
unsigned long lastFPSDisplay = 0;
unsigned int readVoltageDelay = DEFAULT_VOLTAGE_READ_DELAY;

struct {
    EncButton<EB_TICK, 2> vape;
    EncButton<EB_TICK, 3> set;
    EncButton<EB_TICK, 4> down;
    EncButton<EB_TICK, 5> up;
} buttons;

struct {
    OutputPin led{LED_BUILTIN};
    OutputPin vibro{PIN_A1};
} pins;

KeyFrame keyFrames[]{
    {"VAPE!!", 666},
    {"vape!!", 666}
};

struct {
    Animation vaping = Animation(keyFrames, (sizeof(keyFrames) / sizeof(keyFrames[0])), true);
} animations;

void setup() {
    Serial.begin(9600);
    display.init();
    storage.readData();
    power.setVoltageConst(storage.data.voltsConst);
}

bool menuMode = false;
bool vapeMode = false;
unsigned long vapeStartTime;
int maxVapeTime = 10000;
bool isActionChanged = true;

void loop() {
    buttons.vape.tick();
    // if (millis() - lastFPSUpdate > 1000 || lastFPSUpdate == 0) {
        // display.frames = 0;
        // lastFPSUpdate = millis();
    // }
    if (millis() - lastVoltageRead > readVoltageDelay || lastVoltageRead == 0) {
        int voltage = power.readBatteryVoltage();
        Serial.println(voltage);
        lastVoltageRead = millis();
        display.printHeader(power.percentage);
//        display.printFooter("Volts:" + power.readableVoltage);
    }
    if (vapeMode) {
        vapeAction();
    } else if (menuMode) {
        menuAction();
    } else {
        defaultAction();
    }
    display.update();

    // if (millis() - lastFPSDisplay > 250 || lastFPSDisplay == 0) {
    //    display.printFps();
        // lastFPSDisplay = millis();
    // }
}

void defaultAction() {
    if (isActionChanged) {
        Serial.println("Default mode enabled");
    }
    pins.led.disable();
    pins.vibro.disable();
    display.println("DEFAULT");
    readVoltageDelay = DEFAULT_VOLTAGE_READ_DELAY;
    isActionChanged = false;
    if (buttons.vape.isHolded()) {
        vapeMode = true;
        isActionChanged = true;
    } else if (buttons.vape.hasClicks(2)) {
        menuMode = true;
        isActionChanged = true;
    }
}

void vapeAction() {
    if (isActionChanged) {
        Serial.println("Vape mode enabled");
        vapeStartTime = millis();
    }
    pins.led.enable();
    pins.vibro.enable();
    display.playAnimation(animations.vaping);
    readVoltageDelay = 1000;
    isActionChanged = false;
    bool expired = millis() - vapeStartTime >= maxVapeTime;
    Serial.println(millis() - vapeStartTime);
    if (expired || buttons.vape.isRelease()) {
        vapeMode = false;
        isActionChanged = true;
    }
}

void menuAction() {
    if (isActionChanged) {
        Serial.println("Menu mode enabled");
    }
    pins.led.disable();
    pins.vibro.disable();
    display.println("MENU");
    readVoltageDelay = DEFAULT_VOLTAGE_READ_DELAY;
    isActionChanged = false;
    if (buttons.vape.hasClicks(3)) {
        menuMode = false;
        isActionChanged = true;
    }
}