// p6_nfc.h — NFC / alchemical-symbols puzzle driver for Zacus master (P6).
//
// When CONFIG_ZACUS_P6_NFC_ENABLE=n (default) all functions are empty stubs
// (init returns ESP_OK, arm/disarm are no-ops) so callers need no #ifdef guards.
//
// When enabled:
//   1. Call p6_nfc_init() once at boot.
//   2. Call p6_nfc_arm(expected_uid, solved_cb) when the gateway POSTs
//      /game/step with a "nfc" puzzle. `expected_uid` is a hex UID string
//      like "A1:B2:C3:D4" (4-byte NTAG213) or a space-separated sequence
//      of UIDs for ordered multi-tag placement.
//   3. A FreeRTOS task polls the NFC reader at ~5 Hz and calls solved_cb
//      when the presented tag UID matches (or the full sequence is placed).
//   4. Call p6_nfc_disarm() on step change or game reset.
//
// Hardware backend is selected via Kconfig:
//   PN532 over I2C or SPI  → CONFIG_ZACUS_P6_READER_PN532
//   PN7150 over I2C        → CONFIG_ZACUS_P6_READER_PN7150
//
// The hardware HAL is STUBBED in this scaffold revision: the read function
// compiles, links, and logs "NFC read (stub)" but returns no UIDs until the
// real HAL is wired in. This is the same pattern as media_manager stubs.

#pragma once

#include "esp_err.h"
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

// Callback type invoked on the p6_nfc task when the tag / sequence is solved.
// Must not call p6_nfc_arm/disarm from within — defer via task notification.
typedef void (*p6_nfc_solved_cb_t)(void);

/**
 * @brief Initialise the P6 NFC puzzle driver.
 *
 * Initialises the configured bus (I2C or SPI) and the NFC reader IC.
 * Spawns the NFC polling task (blocked until p6_nfc_arm() is called).
 * Idempotent — safe to call more than once.
 *
 * When CONFIG_ZACUS_P6_NFC_ENABLE=n returns ESP_OK immediately.
 *
 * @return ESP_OK on success, or a driver error code.
 */
esp_err_t p6_nfc_init(void);

/**
 * @brief Arm the NFC puzzle for a specific expected tag UID or sequence.
 *
 * @param expected_uid  NUL-terminated UID string to match. Format:
 *                      single tag  → "A1:B2:C3:D4"
 *                      The string is copied — caller buffer may be transient.
 * @param solved_cb     Callback invoked exactly once on a match.
 *                      Pass NULL to skip (e.g. during tests).
 *
 * When CONFIG_ZACUS_P6_NFC_ENABLE=n this is a no-op.
 */
void p6_nfc_arm(const char *expected_uid, p6_nfc_solved_cb_t solved_cb);

/**
 * @brief Disarm the puzzle (stop polling, reset state).
 *
 * When CONFIG_ZACUS_P6_NFC_ENABLE=n this is a no-op.
 */
void p6_nfc_disarm(void);

#ifdef __cplusplus
}
#endif
