#include <Arduino.h>

#define IR_RECEIVER_PIN 2
#define LED_PIN 13
#define OK_BUTTON_CODE 0x44

class IRController {
private:
  uint8_t irReceiverPin;
  bool anyButtonPressed;
  uint8_t ledPin;
  uint8_t okButtonPressCount;

public:
  IRController(uint8_t receiverPin, uint8_t statusLedPin)
      : irReceiverPin(receiverPin), anyButtonPressed(false), ledPin(statusLedPin), okButtonPressCount(0) {}

  void setup() {
    pinMode(irReceiverPin, INPUT);
    pinMode(ledPin, OUTPUT);
    attachInterrupt(digitalPinToInterrupt(irReceiverPin), &IRController::handleIRInterrupt, CHANGE);
  }

  bool isAnyButtonPressed() {
    return anyButtonPressed;
  }

  uint8_t getPressedButtonCode() {
    return decodeIR();
  }

  bool isButtonPressed(uint8_t buttonCode) {
    return (decodeIR() == buttonCode);
  }

  void turnOnOffStatusLED(bool on) {
    digitalWrite(ledPin, on ? HIGH : LOW);
  }

  void printButtonInfoToSerial() {
    static bool firstPress = true;
    if (anyButtonPressed) {
      if (firstPress) {
        uint8_t buttonCode = getPressedButtonCode();
        Serial.print("Button Pressed: ");
        Serial.print("Code: 0x");
        Serial.print(buttonCode, HEX);
        Serial.println();
        firstPress = false;
      } else {
        Serial.println("Button Pressed Again");
      }
    }
  }

  void handleIRInterrupt() {
    anyButtonPressed = true;
    detachInterrupt(digitalPinToInterrupt(irReceiverPin));
  }

  void handleLEDFlash() {
    if (okButtonPressCount >= 5 && okButtonPressCount < 8) {
      // Flash LED at 5Hz
      digitalWrite(ledPin, !digitalRead(ledPin));
      delay(100);
    } else if (okButtonPressCount == 8) {
      digitalWrite(ledPin, LOW);
      okButtonPressCount = 0;
    }
  }

  void loop() {
    if (anyButtonPressed) {
      printButtonInfoToSerial();
      turnOnOffStatusLED(true);
      handleLEDFlash();
      anyButtonPressed = false;
      okButtonPressCount++;
      attachInterrupt(digitalPinToInterrupt(irReceiverPin), &IRController::handleIRInterrupt, CHANGE);
    }
  }

  uint8_t decodeIR() {
    return 0;
  }
};

IRController irController(IR_RECEIVER_PIN, LED_PIN);

void setup() {
  Serial.begin(9600);
  irController.setup();
}

void loop() {
  irController.loop();
}