// =======================================================================
// ARDUINO LOGICKISTE: UNIVERSELLE SCHALTUHR (ENCODER & DISPLAY)
// =======================================================================

Blockly.defineBlocksWithJsonArray([
    // 1. ENCODER KONTROLLER
    {
        "type": "ard_timer_encoder_ctrl",
        "message0": "🎛️ Schaltuhr per Encoder steuern",
        "message1": "Encoder Pin A: %1 Pin B: %2 | Taster: %3",
        "args1": [
            {"type": "field_input", "name": "PIN_A", "text": "2"},
            {"type": "field_input", "name": "PIN_B", "text": "3"},
            {"type": "field_input", "name": "PIN_BTN", "text": "4"}
        ],
        "previousStatement": null,
        "nextStatement": null,
        "colour": 120,
        "tooltip": "Verarbeitet Encoder und Taster im Hintergrund zur Einstellung."
    },
    // 2. TEXT-AUSGABE 
    {
        "type": "ard_timer_get_display_text",
        "message0": "📟 Schaltuhr Menü-Text: %1",
        "args0": [
            {"type": "field_dropdown", "name": "LINE", "options": [
                ["Zeile 1 (Slot, Modus, Tage)", "1"],
                ["Zeile 2 (Zeiten & Cursor)", "2"]
            ]}
        ],
        "output": "String",
        "colour": 160
    },
    // 3. LOGIK-AUSWERTUNG & ZEITQUELLE
    {
        "type": "ard_timer_slot_eval",
        "message0": "⏰ Ist Schaltuhr (Universal) aktiv? | Quelle: %1",
        "args0": [
            {
                "type": "field_dropdown",
                "name": "TIME_SRC",
                "options": [
                    ["Interne R4 RTC (oder NTP)", "INT"],
                    ["Externe RTC (I2C Modul)", "EXT"]
                ]
            }
        ],
        "output": "Boolean",
        "colour": 120,
        "tooltip": "Prüft alle 7 konfigurierten Slots. Wähle die Zeitquelle aus."
    }
]);

// --- GEMEINSAMER C++ HEADER (Universal) ---
function addUniTimerGlobals() {
    ArduinoGenerator.globals_.add(`
#ifndef UNI_TIMER_GLOBALS
#define UNI_TIMER_GLOBALS

struct UniTimerSlot {
  uint8_t mode; 
  uint8_t days; 
  uint8_t onH, onM, offH, offM;
};

UniTimerSlot uni_timers[7] = {
  {1, 1, 6, 0, 22, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}
};

int uni_curSlot = 0;   
int uni_curField = 0;  
unsigned long uni_slotImpulseTime[7] = {0};

const char* uni_daysStr[] = {"Alle ", "Mo-Fr", "Sa-So", "Mo   ", "Di   ", "Mi   ", "Do   ", "Fr   ", "Sa   ", "So   "};
const char* uni_modeStr[] = {"AUS", "EIN", "IMP"};

bool uni_evalTimerLogic(int curH, int curM, int curS, int curD) {
  int curMinTotal = (curH * 60) + curM;
  for (int i = 0; i < 7; i++) {
    UniTimerSlot &s = uni_timers[i];
    if (s.mode == 0) continue; 
    bool dayOk = false;
    if (s.days == 0) dayOk = true; 
    else if (s.days == 1 && curD >= 1 && curD <= 5) dayOk = true; 
    else if (s.days == 2 && (curD == 6 || curD == 7)) dayOk = true; 
    else if (s.days >= 3 && (s.days - 2) == curD) dayOk = true; 
    if (!dayOk) continue;

    if (s.mode == 2) {
      if (curH == s.onH && curM == s.onM && curS == 0) {
        if (millis() - uni_slotImpulseTime[i] > 2000) uni_slotImpulseTime[i] = millis();
      }
      if (millis() - uni_slotImpulseTime[i] <= 1000) return true;
    } else if (s.mode == 1) {
      int onMin = (s.onH * 60) + s.onM;
      int offMin = (s.offH * 60) + s.offM;
      if (onMin <= offMin) {
        if (curMinTotal >= onMin && curMinTotal < offMin) return true;
      } else {
        if (curMinTotal >= onMin || curMinTotal < offMin) return true; 
      }
    }
  }
  return false;
}
#endif
`);
}

// --- GENERATOREN ---
ArduinoGenerator.hardwareScanners['ard_timer_encoder_ctrl'] = function(block) {
    addUniTimerGlobals();
    const pinA = block.getFieldValue('PIN_A');
    const pinB = block.getFieldValue('PIN_B');
    const pinBtn = block.getFieldValue('PIN_BTN');

    ArduinoGenerator.usedPinsInput.add(pinA);
    ArduinoGenerator.usedPinsInput.add(pinB);
    ArduinoGenerator.usedPinsInput.add(pinBtn);
    ArduinoGenerator.pinModes.set(pinA, 'INPUT_PULLUP');
    ArduinoGenerator.pinModes.set(pinB, 'INPUT_PULLUP');
    ArduinoGenerator.pinModes.set(pinBtn, 'INPUT_PULLUP');

    ArduinoGenerator.globals_.add(`
int uni_encLastA = HIGH;
int uni_btnLast = HIGH;
unsigned long uni_btnDebounce = 0;

void uni_updateEncoder(const int pA, const int pB, const int pBtn) {
  int btnState = digitalRead(pBtn);
  if (btnState == LOW && uni_btnLast == HIGH && (millis() - uni_btnDebounce > 200)) {
    uni_btnDebounce = millis();
    uni_curField = (uni_curField + 1) % 7;
  }
  uni_btnLast = btnState;
  int aState = digitalRead(pA);
  if (aState != uni_encLastA && aState == LOW) {
    int dir = (digitalRead(pB) != aState) ? 1 : -1;
    UniTimerSlot &s = uni_timers[uni_curSlot];
    switch(uni_curField) {
      case 0: uni_curSlot = (uni_curSlot + dir + 7) % 7; break;
      case 1: s.mode = (s.mode + dir + 3) % 3; break;
      case 2: s.days = (s.days + dir + 10) % 10; break;
      case 3: s.onH = (s.onH + dir + 24) % 24; break;
      case 4: s.onM = (s.onM + dir + 60) % 60; break;
      case 5: s.offH = (s.offH + dir + 24) % 24; break;
      case 6: s.offM = (s.offM + dir + 60) % 60; break;
    }
  }
  uni_encLastA = aState;
}
`);
};

ArduinoGenerator.forBlock['ard_timer_encoder_ctrl'] = function(block) {
    const pinA = block.getFieldValue('PIN_A');
    const pinB = block.getFieldValue('PIN_B');
    const pinBtn = block.getFieldValue('PIN_BTN');
    ArduinoGenerator.autoLoop_.push(`  uni_updateEncoder(pin${pinA}, pin${pinB}, pin${pinBtn});\n`);
    return ''; 
};

ArduinoGenerator.hardwareScanners['ard_timer_get_display_text'] = function(block) {
    addUniTimerGlobals();
    ArduinoGenerator.globals_.add(`
String uni_getTimerMenuLine(const int line) {
  UniTimerSlot &s = uni_timers[uni_curSlot];
  char buf[21];
  if (line == 1) {
    sprintf(buf, "U%d:%s [%s]%s", uni_curSlot + 1, uni_daysStr[s.days], uni_modeStr[s.mode], (uni_curField == 0 ? "*" : ""));
  } else {
    char onH_c = (uni_curField == 3) ? '>' : ' ';
    char onM_c = (uni_curField == 4) ? '>' : ' ';
    char offH_c = (uni_curField == 5) ? '>' : ' ';
    char offM_c = (uni_curField == 6) ? '>' : ' ';
    sprintf(buf, "%c%02d:%c%02d-%c%02d:%c%02d", onH_c, s.onH, onM_c, s.onM, offH_c, s.offH, offM_c, s.offM);
  }
  return String(buf);
}
`);
};

ArduinoGenerator.forBlock['ard_timer_get_display_text'] = function(block) {
    const line = block.getFieldValue('LINE');
    return [`uni_getTimerMenuLine(${line})`, 0];
};

ArduinoGenerator.hardwareScanners['ard_timer_slot_eval'] = function(block) {
    addUniTimerGlobals();
    const timeSrc = block.getFieldValue('TIME_SRC');
    
    if (timeSrc === 'INT') {
        ArduinoGenerator.includes_.add('#include "RTC.h"');
        ArduinoGenerator.globals_.add(`
bool uni_evalTimer_Int() {
  RTCTime t; RTC.getTime(t);
  return uni_evalTimerLogic(t.getHour(), t.getMinutes(), t.getSeconds(), (int)t.getDayOfWeek());
}
`);
    } else {
        ArduinoGenerator.globals_.add(`
bool uni_evalTimer_Ext() {
  DateTime now = extRTC.now();
  int dow = now.dayOfTheWeek();
  return uni_evalTimerLogic(now.hour(), now.minute(), now.second(), (dow == 0 ? 7 : dow));
}
`);
    }
};

ArduinoGenerator.forBlock['ard_timer_slot_eval'] = function(block) {
    const timeSrc = block.getFieldValue('TIME_SRC');
    return [(timeSrc === 'INT') ? 'uni_evalTimer_Int()' : 'uni_evalTimer_Ext()', 0];
};