// ╔══════════════════════════════════════════════════════════════════════════╗
// ║                  BLUEHASH COMMUNITY PROGRAM TEMPLATE                    ║
// ║                         Version 1.0.0                                   ║
// ║                                                                          ║
// ║  HOW TO USE THIS TEMPLATE:                                               ║
// ║    1. Fill in the METADATA section below                                 ║
// ║    2. Document your button map                                           ║
// ║    3. Write your helpers/state in the YOUR CODE section                  ║
// ║    4. Write your logic inside bh_program_<id>_main()                    ║
// ║    5. Test locally (see TESTING section at bottom)                       ║
// ║    6. Submit at bluehash.in/library                                      ║
// ║                                                                          ║
// ║  RULES (all required for acceptance):                                    ║
// ║    ✓ Only use bh_* functions — never call Arduino APIs directly          ║
// ║    ✓ Always check bh_exit_requested() in your main loop                  ║
// ║    ✓ Always call bh_program_exit() before returning                      ║
// ║    ✓ Prefix all globals/helpers with a unique short prefix               ║
// ║    ✓ Use bh_delay() not delay()                                          ║
// ║    ✓ Clean up WiFi/BLE/SD before exiting                                 ║
// ║                                                                          ║
// ║  REFERENCE:                                                              ║
// ║    HAL API  →  bluehash.in/docs/hal                                      ║
// ║    Examples →  bluehash.in/docs/programs                                 ║
// ║    Submit   →  bluehash.in/library                                       ║
// ╚══════════════════════════════════════════════════════════════════════════╝

#pragma once
#include "../../hal/bh_hal.h"


// ════════════════════════════════════════════════════════════════════════════
// METADATA
// Fill in every field. These appear in the editor library browser.
// ════════════════════════════════════════════════════════════════════════════

// Unique identifier — lowercase letters, numbers, hyphens only. No spaces.
// This must be unique across all community programs.
// Example: "my-ir-blaster"  "snake-v2"  "wifi-scanner"
#define PROGRAM_ID          "my-program"

// Display name shown in the editor library browser
#define PROGRAM_NAME        "My Program"

// Your name or handle
#define PROGRAM_AUTHOR      "your-name"

// Semantic version — increment when you update
#define PROGRAM_VERSION     "1.0.0"

// One-line description shown in the library browser (max ~80 chars)
#define PROGRAM_DESCRIPTION "What your program does in one sentence"

// Category — pick exactly one:
//   game       → games and interactive entertainment
//   tool       → productivity, utilities, calculators
//   utility    → system tools, diagnostics, info displays
//   rf         → RF 433MHz capture, replay, analysis
//   ble        → Bluetooth LE tools and toys
//   network    → WiFi, HTTP, MQTT, WebSocket tools
#define PROGRAM_CATEGORY    "tool"

// Output ports (optional) — declare any ports your program exposes
// so users can wire them in the flow editor. Format: "port:type"
// Types: trigger | string | number | boolean
// Example: "done:trigger,score:number,name:string"
// Leave empty string if your program has no outputs
#define PROGRAM_OUTPUTS     ""


// ════════════════════════════════════════════════════════════════════════════
// BUTTON MAP
// Document what each button does in your program.
// Users see this in the library browser before installing.
// ════════════════════════════════════════════════════════════════════════════

//  OK   (GPIO 0)  = <describe what OK does>
//  UP   (GPIO 36) = <describe what UP does>
//  DOWN (GPIO 37) = <describe what DOWN does>
//  BACK (GPIO 35) = <describe what BACK does — short press>
//  BTN1 (GPIO 38) = <describe or leave blank if unused>
//  BTN2 (GPIO 39) = <describe or leave blank if unused>
//
//  BACK hold 1.5s = Exit to device flow  ← MANDATORY, do not override


// ════════════════════════════════════════════════════════════════════════════
// YOUR CODE
// ════════════════════════════════════════════════════════════════════════════
//
// Naming rules:
//   • Prefix ALL static variables, enums, structs, and helper functions
//     with a short unique prefix. Example: _mp_ for "my program".
//   • This avoids name collisions when multiple programs are compiled into
//     the same firmware binary.
//
// Display cheatsheet:
//   bh_display_clear()                        — clear buffer
//   bh_display_show()                         — flush to OLED
//   bh_display_font(BH_FONT_SMALL)            — set font size
//   bh_display_print(x, y, "text")            — draw text at x,y
//   bh_display_print_center(y, "text")        — draw text centered
//   bh_display_notify("msg", 1500)            — popup for 1500ms
//   bh_display_progress(x, y, w, h, pct)      — progress bar 0-100
//   bh_display_rect(x, y, w, h)               — unfilled rectangle
//   bh_display_fill_rect(x, y, w, h)          — filled rectangle
//   bh_display_hline(x, y, w)                 — horizontal line
//   bh_display_pixel(x, y, true)              — single pixel
//
// Button cheatsheet:
//   bh_wait_button()                          — block until pressed
//   bh_wait_button_timeout(ms)                — block until pressed or timeout
//   bh_poll_button()                          — non-blocking, BH_BTN_NONE if none
//   bh_exit_requested()                       — true if user held BACK 1.5s
//
// Button constants:
//   BH_BTN_OK=0  BH_BTN_BACK=1  BH_BTN_UP=2  BH_BTN_DOWN=3
//   BH_BTN_1=4   BH_BTN_2=5    BH_BTN_EXIT=99  BH_BTN_NONE=-1
//
// Sound:
//   bh_beep(freq_hz, duration_ms)             — play a tone
//   bh_click()                                — short click sound
//
// Storage (survives reboot + OTA):
//   bh_nvs_set_int("key", value)
//   bh_nvs_get_int("key", default_value)
//   bh_nvs_set_string("key", "value")
//   bh_nvs_get_string("key", "default")
//
// Full reference: bluehash.in/docs/hal

// ── State variables ──────────────────────────────────────────────────────
// static int  _mp_score = 0;
// static bool _mp_running = false;

// ── Helper functions ─────────────────────────────────────────────────────
// static void _mp_draw_screen() {
//   bh_display_clear();
//   bh_display_font(BH_FONT_SMALL);
//   bh_display_print_center(0, PROGRAM_NAME);
//   bh_display_hline(0, 9, 128);
//   bh_display_show();
// }


// ════════════════════════════════════════════════════════════════════════════
// ENTRY POINT
// The function name MUST follow this pattern exactly:
//   bh_program_<PROGRAM_ID>_main()
// Replace hyphens in PROGRAM_ID with underscores.
// Example: PROGRAM_ID "my-program" → bh_program_my_program_main()
// ════════════════════════════════════════════════════════════════════════════
void bh_program_my_program_main() {

  // ── One-time setup ────────────────────────────────────────────────────
  // Runs once when the Program node triggers your program.
  // Initialize state, show title screen, play startup sound, etc.

  bh_display_clear();
  bh_display_font(BH_FONT_LARGE);
  bh_display_print_center(8, PROGRAM_NAME);
  bh_display_font(BH_FONT_SMALL);
  bh_display_print_center(36, "v" PROGRAM_VERSION);
  bh_display_print_center(48, "OK to start");
  bh_display_show();
  bh_beep(440, 80);
  bh_delay(50);
  bh_beep(660, 80);

  // Wait for OK to start (or BACK/EXIT to quit immediately)
  int _start = bh_wait_button();
  if (_start == BH_BTN_BACK || _start == BH_BTN_EXIT) {
    bh_program_exit();  // ← MANDATORY: always call before returning
    return;
  }

  // ── Main loop ─────────────────────────────────────────────────────────
  // Keep looping until the user exits.
  // ALWAYS check bh_exit_requested() — this is non-negotiable.

  while (!bh_exit_requested()) {  // ← MANDATORY check

    // ── Option A: blocking button wait ──────────────────────────────
    // Use this when your program waits for user input between actions.
    int btn = bh_wait_button();
    if (btn == BH_BTN_EXIT) break;  // ← MANDATORY

    if (btn == BH_BTN_OK) {
      // handle OK press
    }
    else if (btn == BH_BTN_UP) {
      // handle UP press
    }
    else if (btn == BH_BTN_DOWN) {
      // handle DOWN press
    }
    else if (btn == BH_BTN_BACK) {
      // handle short BACK press (1.5s hold is exit — handled above)
    }

    // ── Option B: non-blocking poll (for games/animations) ───────────
    // Use bh_poll_button() instead of bh_wait_button() when you need
    // the loop to keep running every frame regardless of input.
    //
    // int btn = bh_poll_button();
    // if (btn == BH_BTN_EXIT) break;
    // if (btn == BH_BTN_UP)   { /* handle */ }
    //
    // // Your game/animation update logic here
    // _mp_update();
    // _mp_draw();
    // bh_delay(16);  // ~60fps cap

    // ── Draw your screen ────────────────────────────────────────────
    // Always call bh_display_clear() then bh_display_show() around draws.
    bh_display_clear();
    bh_display_font(BH_FONT_SMALL);
    // ... your drawing code here ...
    bh_display_show();
  }

  // ── Cleanup ───────────────────────────────────────────────────────────
  // Stop anything you started. Failing to clean up causes issues for
  // the next program or flow that runs after yours.

  // bh_wifi_disconnect();   // if you called bh_wifi_connect()
  // bh_ble_stop();          // if you called bh_ble_start()
  // bh_led(false);          // if you turned on the LED

  // Save high scores or state to NVS here if needed
  // bh_nvs_set_int("mp_best", _mp_score);

  bh_program_exit();  // ← MANDATORY: always the last line
}


// ════════════════════════════════════════════════════════════════════════════
// TESTING LOCALLY
// ════════════════════════════════════════════════════════════════════════════
//
// 1. Copy this file to:
//      bluehash-firmware/programs/examples/my_program.h
//
// 2. Open bluehash-firmware/src/main.ino and add to BH_PROGRAMS[]:
//      #include "../programs/examples/my_program.h"
//      ...
//      { "my-program", bh_program_my_program_main },
//
// 3. Flash via the editor or:
//      cd bluehash-firmware && pio run -e esp32s3 --target upload
//
// 4. In the editor, drag a Program node, select your program ID,
//    connect the trigger, and click Flash.
//
// ════════════════════════════════════════════════════════════════════════════
// SUBMITTING
// ════════════════════════════════════════════════════════════════════════════
//
// When ready to share with the community:
//   1. Make sure PROGRAM_ID is unique (search the library first)
//   2. Fill in all METADATA fields above
//   3. Go to bluehash.in/library
//   4. Click "Submit a program"
//   5. Paste your source and fill in the form
//   6. After review it appears in the editor for all users
//
// Questions? → github.com/bluehash-dev
// ════════════════════════════════════════════════════════════════════════════