#include <stdio.h>
#include <string.h>
#include "esp_rom_sys.h" 
#include "esp_task_wdt.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "esp_spiffs.h"
#include "esp_sntp.h"
#include "wifi_config_portal.h"
#include "mqtt_handler.h"
#include "led_driver.h"
#include "esp_random.h"
#include "eeprom_virtual.h"
#include "eeprom_tls.h"


typedef struct {
    int total_creditos;
    int total_saidas;
} contadores_t;

static const char *TAG = "APP";
static uint32_t segundos = 0;
static bool wifi_ready = false;

// === Contador simples de debug ===
void segundos_task(void *pv) {
    while (1) {
        vTaskDelay(pdMS_TO_TICKS(1000));
        segundos++;
     //   ESP_LOGI("TIMER", "⏱ %lu segundos", segundos);
    }
}

uint32_t get_segundos(void) {
    return segundos;
}

// === Task de LEDs ===
void led_task(void *pv) {
    bool tem_creditos = false;
    while (1) {
        if (wifi_ready && tem_creditos) {
            uint16_t target = esp_random() % LED_COUNT;
            led_spin_to(target, 2, 12, 80);
            tem_creditos = false;
        } else if (wifi_ready) {
            led_idle_animation();
        } else {
            vTaskDelay(pdMS_TO_TICKS(100)); // espera Wi-Fi
        }
        vTaskDelay(pdMS_TO_TICKS(50));
    }
}

// === Callback quando Wi-Fi e IP estão prontos ===
static void on_wifi_connected(void) {
    wifi_ready = true;
    ESP_LOGI(TAG, "✅ Wi-Fi conectado, IP obtido — iniciando MQTT e LEDs...");

    mqtt_handler_start();

    ESP_LOGI(TAG, "🕒 Inicializando SNTP...");
    esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
    esp_sntp_setservername(0, "pool.ntp.org");
    esp_sntp_init();

    ESP_LOGI(TAG, "💡 Inicializando LEDs...");
    led_init();
}

#include "esp_rom_sys.h"

void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
    esp_rom_printf("\n🧨 Stack overflow em %s!\n", pcTaskName);
    // NÃO reinicia aqui — isso bloqueia o WiFi event task e causa WDT
    // apenas marca para reiniciar depois
    esp_task_wdt_reset(); 
    vTaskDelay(pdMS_TO_TICKS(1000));
    esp_restart();
}


// === Função principal ===
void app_main(void) {
    // ---------- EEPROM ----------
    eeprom_virtual_init();

    contadores_t contadores = {100, 25};
    eeprom_virtual_write_bin("contadores", &contadores, sizeof(contadores));
    ESP_LOGI("EEPROM", "💾 Gravado: total_creditos=%d, total_saidas=%d",
             contadores.total_creditos, contadores.total_saidas);

    contadores_t lidos = {0};
    size_t len = sizeof(lidos);
    if (eeprom_virtual_read_bin("contadores", &lidos, &len) == ESP_OK) {
        ESP_LOGI("EEPROM", "📖 Lido: total_creditos=%d, total_saidas=%d",
                 lidos.total_creditos, lidos.total_saidas);
    } else {
        ESP_LOGW("EEPROM", "⚠️ Falha ao ler dados!");
    }

    // ---------- NVS ----------
    ESP_ERROR_CHECK(nvs_flash_init());

    // ---------- LOG ----------
    esp_log_level_set("wifi", ESP_LOG_WARN);

    // ---------- SPIFFS ----------
    ESP_LOGI(TAG, "🔧 Montando SPIFFS...");
    esp_vfs_spiffs_conf_t spiffs_conf = {
        .base_path = "/spiffs",
        .partition_label = "storage",
        .max_files = 5,
        .format_if_mount_failed = true
    };
    esp_err_t ret = esp_vfs_spiffs_register(&spiffs_conf);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "❌ Falha ao montar SPIFFS (%s)", esp_err_to_name(ret));
    } else {
        size_t total = 0, used = 0;
        esp_spiffs_info(spiffs_conf.partition_label, &total, &used);
        ESP_LOGI(TAG, "📦 SPIFFS OK: total=%d bytes, usado=%d", total, used);
    }

    // ---------- Wi-Fi ----------
    wifi_config_t cfg;
    bool have_creds = false;
    if (esp_wifi_get_config(WIFI_IF_STA, &cfg) == ESP_OK) {
        if (strlen((char *)cfg.sta.ssid) > 0) {
            ESP_LOGI(TAG, "📂 Credenciais encontradas no NVS: SSID=%s", cfg.sta.ssid);
            have_creds = true;
        }
    }

    wifi_config_portal_init(on_wifi_connected, have_creds);

    // ---------- Tasks ----------
    xTaskCreate(segundos_task, "segundos_task", 12288, NULL, 5, NULL);
    xTaskCreate(led_task, "led_task", 12288, NULL, 5, NULL);

    // ---------- Loop principal (livre) ----------
    while (1) {
        if (wifi_ready) {
            mqtt_handler_loop();  // mantém MQTT ativo
        }
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}
