#include "app_run.h"

#include "sdkconfig.h"

#include <stdio.h>

#include <string.h>

#include "esp_wifi.h"

#include "esp_event.h"

#include "esp_log.h"

#include "core/system_init.h"

#include "core/build_config.h"

#include "wifidevnum_config.h"

#include "device_nvs.h"

#include "driver_manager.h"

#include "ota_manager.h"

#include "freertos/FreeRTOS.h"

#include "freertos/task.h"



#define OTA_CONFIRM_DELAY_MS 30000



#if CONFIG_APP_LINK_WIFI

#include "mqttconf_commun.h"

#endif

#if CONFIG_APP_LINK_BLE

#include "link_ble.h"

#endif

#if CONFIG_APP_LINK_UART

#include "link_uart.h"

#endif



extern void example_uart_comm_start(void);



static const char *tag_s = "APP";



#if CONFIG_APP_LINK_WIFI

static bool init_task_triggered_s = false;



static void wifi_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data)

{

    (void)arg;

    if (base == IP_EVENT && id == IP_EVENT_STA_GOT_IP) {

        ip_event_got_ip_t *event = (ip_event_got_ip_t *)data;

        ESP_LOGI(tag_s, "获取 IP: " IPSTR, IP2STR(&event->ip_info.ip));



        char devid_check[32] = {0};

        if (read_from_nvs(DEVICE_CFG_KEY_DEVICE_ID, devid_check, sizeof(devid_check)) == ESP_OK &&

            strlen(devid_check) > 0) {

            if (!init_task_triggered_s) {

                ESP_LOGI(tag_s, "启动 MQTT");

                mqtt_manager_init_sequence();

                init_task_triggered_s = true;

            }

        } else {

            ESP_LOGE(tag_s, "device_id 为空，无法启动 MQTT");

        }

    } else if (base == WIFI_EVENT && id == WIFI_EVENT_STA_DISCONNECTED) {

        ESP_LOGW(tag_s, "WiFi 断开，重连...");

        esp_wifi_connect();

    }

}

#endif



#if CONFIG_APP_LINK_WIFI

static void run_wifi_mode(void)

{

    char ssid[32] = {0}, pass[64] = {0};

    esp_err_t wifi_ret = read_from_nvs(DEVICE_CFG_KEY_WIFI_SSID, ssid, sizeof(ssid));



    if (wifi_ret == ESP_OK) {

        read_from_nvs(DEVICE_CFG_KEY_WIFI_PASS, pass, sizeof(pass));



        esp_netif_create_default_wifi_sta();



        esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL);

        esp_event_handler_instance_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &wifi_event_handler, NULL,

                                            NULL);



        button_monitor_task_init();



        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

        esp_wifi_init(&cfg);



        wifi_config_t sta_cfg = {

            .sta =

                {

                    .scan_method = WIFI_ALL_CHANNEL_SCAN,

                    .sort_method = WIFI_CONNECT_AP_BY_SIGNAL,

                },

        };

        strncpy((char *)sta_cfg.sta.ssid, ssid, sizeof(sta_cfg.sta.ssid));

        strncpy((char *)sta_cfg.sta.password, pass, sizeof(sta_cfg.sta.password));



        esp_wifi_set_mode(WIFI_MODE_STA);

        esp_wifi_set_config(WIFI_IF_STA, &sta_cfg);

        esp_wifi_start();

        esp_wifi_connect();

    } else {

        ESP_LOGI(tag_s, "无 WiFi 配置，启动配网页");

        nowifidata_start_config_web();

    }

}

#endif



#if CONFIG_APP_LINK_BLE

static void run_ble_mode(void)

{

    char dev[32] = {0};

    char ble[32] = {0};

    read_from_nvs(DEVICE_CFG_KEY_DEVICE_ID, dev, sizeof(dev));

    read_from_nvs(DEVICE_CFG_KEY_BLE_ADV_NAME, ble, sizeof(ble));



    if (strlen(dev) == 0 || strlen(ble) == 0) {

        ESP_LOGI(tag_s, "需配置 device_id 与蓝牙名，启动热点配网");

        nowifidata_start_config_web();

        return;

    }



    button_monitor_task_init();



    if (link_ble_start() != ESP_OK) {

        ESP_LOGE(tag_s, "BLE 启动失败");

    }

}

#endif



#if CONFIG_APP_LINK_UART

static void run_uart_mode(void)

{

    char dev[32] = {0};

    read_from_nvs(DEVICE_CFG_KEY_DEVICE_ID, dev, sizeof(dev));



    if (strlen(dev) == 0) {

        ESP_LOGI(tag_s, "UART 模式: 需配置 device_id，启动配网热点");

        nowifidata_start_config_web();

        return;

    }



    ESP_LOGI(tag_s, "UART 模式: device_id=%s", dev);



    /* 启动按键监控任务（长按重置设备号） */

    button_monitor_task_init();



    /* 启动 UART 链路通信 */

    if (link_uart_start() != ESP_OK) {

        ESP_LOGE(tag_s, "UART 链路启动失败");

    }

}

#endif



static void ota_confirm_task(void *arg)

{

    (void)arg;

    vTaskDelay(pdMS_TO_TICKS(OTA_CONFIRM_DELAY_MS));

    if (ota_manager_get_state() == OTA_STATE_SUCCESS) {

        ESP_LOGI(tag_s, "OTA 稳定运行，确认新固件");

        ota_manager_mark_success();

    }

    vTaskDelete(NULL);

}



static void schedule_ota_confirm_if_needed(void)

{

    if (ota_manager_get_state() == OTA_STATE_SUCCESS) {

        xTaskCreate(ota_confirm_task, "ota_confirm", 3072, NULL, 1, NULL);

    }

}



void app_run(void)

{

    ESP_ERROR_CHECK(system_core_init());

    ESP_ERROR_CHECK(driver_manager_init_from_nvs());



#if BUILD_SERIAL_LOG_ENABLED

#if BUILD_IS_RELEASE

    ESP_LOGI(tag_s, "构建类型: Release (Os优化)");

    #if UART_MODE_COMMUNICATION

        ESP_LOGI(tag_s, "UART模式: 普通通信串口");

    #else

        ESP_LOGI(tag_s, "UART模式: 调试打印");

    #endif

#else

    ESP_LOGI(tag_s, "构建类型: Debug (Og优化)");

    ESP_LOGI(tag_s, "UART模式: 调试打印");

#endif

#endif



#if CONFIG_APP_LINK_WIFI

    run_wifi_mode();

#elif CONFIG_APP_LINK_BLE

    run_ble_mode();

#elif CONFIG_APP_LINK_UART

    run_uart_mode();

#else

#error "请在 menuconfig 中选择 APP_LINK_WIFI / APP_LINK_BLE / APP_LINK_UART"

#endif



#if BUILD_IS_RELEASE && UART_MODE_COMMUNICATION

    example_uart_comm_start();

#endif



    schedule_ota_confirm_if_needed();

}

