// =======================================================================
// KEYESTUDIO PN532 NFC/RFID CONTROLLER SHIELD
// =======================================================================

Blockly.defineBlocksWithJsonArray([
    // 1. INITIALISIEREN (Setup)
    {
        "type": "ks_pn532_setup",
        "message0": "PN532 NFC Shield starten (CS-Pin: %1) | Debug Serial: %2",
        "args0": [
            { "type": "field_number", "name": "CS_PIN", "value": 10, "min": 0, "max": 53 },
            { 
                "type": "field_dropdown", 
                "name": "DEBUG", 
                "options": [ 
                    ["Nein", "FALSE"], 
                    ["Ja (9600 Baud)", "TRUE"] 
                ] 
            }
        ],
        "previousStatement": null,
        "nextStatement": null,
        "colour": 210,
        "tooltip": "Initialisiert das PN532 Shield. Standard CS-Pin ist 10. Gehört ins SETUP."
    },

    // 2. MANUELLES ABFRAGEN (Update)
    {
        "type": "ks_pn532_update",
        "message0": "PN532 Karte jetzt abfragen",
        "previousStatement": null,
        "nextStatement": null,
        "colour": 210,
        "tooltip": "Liest den Sensor aus. Platziere diesen Block im Loop oder in einer Bedingung, um die Karte aktiv abzufragen."
    },

    // 3. EREIGNIS-ABFRAGE
    {
        "type": "ks_pn532_check_event",
        "message0": "Wenn PN532 %1",
        "args0": [
            {
                "type": "field_dropdown",
                "name": "EVENT",
                "options": [
                    ["irgendeine Karte erkennt", "ANY"],
                    ["neue Karte auflegt (einmalig)", "NEW"],
                    ["Karte entfernt wird", "REMOVED"]
                ]
            }
        ],
        "output": "Boolean",
        "colour": 210,
        "tooltip": "Prüft auf verschiedene Karten-Ereignisse. Nutzt eine clevere Flankenerkennung."
    },

    // 4. SPEZIFISCHE UID-ABFRAGE
    {
        "type": "ks_pn532_check_uid",
        "message0": "Wenn PN532 Karte entspricht UID (HEX): %1",
        "args0": [
            { "type": "field_input", "name": "UID", "text": "A1B2C3D4" }
        ],
        "output": "Boolean",
        "colour": 210,
        "tooltip": "Prüft, ob die erkannte Karte exakt dieser HEX-UID entspricht (ohne Leerzeichen)."
    },

    // 5. DATEN AUSLESEN
    {
        "type": "ks_pn532_get_data",
        "message0": "PN532 Lese: %1",
        "args0": [
            {
                "type": "field_dropdown",
                "name": "DATA",
                "options": [
                    ["Karten-UID als Text (HEX)", "UID_HEX"],
                    ["Karten-UID als Zahl (Dezimal)", "UID_DEC"],
                    ["Chip Firmware-Version", "FIRMWARE"]
                ]
            }
        ],
        "output": null,
        "colour": 210,
        "tooltip": "Gibt die ausgelesenen Daten der Karte oder des Chips zurück."
    },

    // 6. HELFER: SERIAL PRINT
    {
        "type": "ks_pn532_action_serial",
        "message0": "PN532 gelesene Karten-UID auf Serial ausgeben",
        "previousStatement": null,
        "nextStatement": null,
        "colour": 210,
        "tooltip": "Gibt die aktuelle UID automatisch als HEX und Dezimal im Seriellen Monitor aus, sobald eine neue Karte aufgelegt wird."
    }
]);


// =======================================================================
// DEZENTRALER SCANNER & GENERATOR
// =======================================================================

const pn532ScannerLogic = function(block) {
    let csPin = 10;
    
    const setupBlock = block.workspace.getBlocksByType('ks_pn532_setup', false)[0];
    if (setupBlock) {
        csPin = setupBlock.getFieldValue('CS_PIN');
    }

    ArduinoGenerator.globals_.add(`#include <PN532.h>`);
    ArduinoGenerator.globals_.add(`#include <SPI.h>`);
    ArduinoGenerator.globals_.add(`PN532 nfc(${csPin});`);
    
    ArduinoGenerator.globals_.add(`uint32_t pn532_current_uid = 0;`);
    ArduinoGenerator.globals_.add(`uint32_t pn532_last_uid = 0;`);
    
    ArduinoGenerator.globals_.add(`
String getPN532_UID_HEX() {
  if (pn532_current_uid == 0) return "";
  String hexStr = String(pn532_current_uid, HEX);
  hexStr.toUpperCase();
  return hexStr;
}
`);
};

// Scanner an alle PN532-Blöcke binden
ArduinoGenerator.hardwareScanners['ks_pn532_setup'] = pn532ScannerLogic;
ArduinoGenerator.hardwareScanners['ks_pn532_update'] = pn532ScannerLogic;
ArduinoGenerator.hardwareScanners['ks_pn532_check_event'] = pn532ScannerLogic;
ArduinoGenerator.hardwareScanners['ks_pn532_check_uid'] = pn532ScannerLogic;
ArduinoGenerator.hardwareScanners['ks_pn532_get_data'] = pn532ScannerLogic;
ArduinoGenerator.hardwareScanners['ks_pn532_action_serial'] = pn532ScannerLogic;

// -----------------------------------------------------------------------
// CODE GENERATOREN
// -----------------------------------------------------------------------

ArduinoGenerator.forBlock['ks_pn532_setup'] = function(block) {
    const debug = block.getFieldValue('DEBUG') === 'TRUE';
    
    let code = `  nfc.begin();\n  nfc.SAMConfig();\n`;
    if (debug) {
        code += `  Serial.begin(9600);\n`;
        code += `  uint32_t versiondata = nfc.getFirmwareVersion();\n`;
        code += `  if (!versiondata) {\n`;
        code += `    Serial.println("PN53x Board nicht gefunden!");\n`;
        code += `  } else {\n`;
        code += `    Serial.print("Gefunden: PN532 | Firmware V");\n`;
        code += `    Serial.println((versiondata>>16) & 0xFF, DEC);\n`;
        code += `  }\n`;
    }
    return code;
};

// DER NEUE UPDATE-BLOCK
ArduinoGenerator.forBlock['ks_pn532_update'] = function(block) {
    let code = `  pn532_last_uid = pn532_current_uid;\n`;
    code += `  pn532_current_uid = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);\n`;
    return code;
};

ArduinoGenerator.forBlock['ks_pn532_check_event'] = function(block) {
    const event = block.getFieldValue('EVENT');
    let code = "";
    
    switch (event) {
        case "ANY":
            code = `(pn532_current_uid != 0)`;
            break;
        case "NEW":
            code = `(pn532_current_uid != 0 && pn532_last_uid == 0)`;
            break;
        case "REMOVED":
            code = `(pn532_current_uid == 0 && pn532_last_uid != 0)`;
            break;
    }
    return [code, 0];
};

ArduinoGenerator.forBlock['ks_pn532_check_uid'] = function(block) {
    const uidMatch = block.getFieldValue('UID').toUpperCase().trim();
    let code = `(pn532_current_uid != 0 && getPN532_UID_HEX() == "${uidMatch}")`;
    return [code, 0];
};

ArduinoGenerator.forBlock['ks_pn532_get_data'] = function(block) {
    const data = block.getFieldValue('DATA');
    let code = "";
    
    switch (data) {
        case "UID_HEX":
            code = `getPN532_UID_HEX()`;
            break;
        case "UID_DEC":
            code = `pn532_current_uid`;
            break;
        case "FIRMWARE":
            code = `nfc.getFirmwareVersion()`;
            break;
    }
    return [code, 0];
};

ArduinoGenerator.forBlock['ks_pn532_action_serial'] = function(block) {
    let code = `  if (pn532_current_uid != 0 && pn532_last_uid == 0) {\n`;
    code += `    Serial.print("NFC Karte! UID (Dez): ");\n`;
    code += `    Serial.print(pn532_current_uid);\n`;
    code += `    Serial.print(" | UID (Hex): ");\n`;
    code += `    Serial.println(getPN532_UID_HEX());\n`;
    code += `  }\n`;
    return code;
};