#include "link_uart.h"
#include "remote_control.h"
#include "wifidevnum_config.h"
#include "device_nvs.h"
#include "rc_pwm_control.h"
#include "esp_log.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

#include "sdkconfig.h"

#include "core/build_config.h"
#include "task_manager.h"
#include "heart_payload.h"

/* OTA 二进制流模块 */
#include "ota_binary_stream.h"

static const char *tag_s = "LINK_UART";

/* UART 配置 */
#define UART_LINK_PORT          UART_NUM_1
#define UART_LINK_BUF_SIZE      2048
#define UART_LINK_QUEUE_SIZE    16
#define UART_LINK_RX_TIMEOUT_MS 100

/* JSON 接收缓冲 */
#define UART_JSON_MAX_BYTES     REMOTE_CTRL_JSON_MAX_BYTES

/* 心跳周期 */
#ifndef UART_HEART_PERIOD_MS
#define UART_HEART_PERIOD_MS    3000
#endif

/* 协议帧分隔符（使用换行符作为 JSON 分隔） */
#define UART_FRAME_DELIMITER    '\n'

/* 函数前向声明 */
static int uart_link_send_json_line(const char *json);

static TaskHandle_t rx_task_handle_s = NULL;
static TaskHandle_t hb_task_handle_s = NULL;
static QueueHandle_t uart_queue_s = NULL;
static volatile bool link_up_s = false;
static volatile uint32_t last_rx_time_ms = 0;

/* 发送互斥 */
static SemaphoreHandle_t tx_mutex_s = NULL;

/* 接收 JSON 缓冲区 */
static char rx_json_buf_s[UART_JSON_MAX_BYTES + 1];
static size_t rx_buf_pos_s = 0;

/* OTA 状态缓冲 */
static char last_ota_stat_json_s[192];

/* OTA 专用接收缓冲 */
static uint8_t ota_rx_buf_s[512];
static size_t ota_rx_pos_s = 0;
static bool ota_rx_mode_s = false;

static uint32_t get_current_time_ms(void)
{
    return (uint32_t)(xTaskGetTickCount() * portTICK_PERIOD_MS);
}

/* UART OTA 状态回调：通过 UART 发送 OTA 状态 JSON */
static void uart_ota_status_callback(const char *json)
{
    if (json == NULL) {
        return;
    }
    strncpy(last_ota_stat_json_s, json, sizeof(last_ota_stat_json_s) - 1);
    last_ota_stat_json_s[sizeof(last_ota_stat_json_s) - 1] = '\0';

    /* 直接通过 UART 发送 OTA 状态 */
    uart_link_send_json_line(json);
}

/* UART OTA 初始化 */
static void uart_ota_init(void)
{
    /* 初始化通用 OTA 模块 */
    esp_err_t err = ota_binary_stream_init(OTA_TRANSPORT_UART, uart_ota_status_callback, NULL);
    if (err != ESP_OK) {
        ESP_LOGE(tag_s, "UART OTA init failed: %s", esp_err_to_name(err));
    } else {
        ESP_LOGI(tag_s, "UART OTA initialized");
    }
}

static int uart_link_send_internal(const uint8_t *data, size_t len)
{
    if (!data || len == 0) {
        return -1;
    }

    int written = uart_write_bytes(UART_LINK_PORT, data, len);
    return written;
}

int link_uart_send_raw(const uint8_t *data, size_t len)
{
    if (tx_mutex_s == NULL) {
        return -1;
    }

    if (xSemaphoreTake(tx_mutex_s, pdMS_TO_TICKS(100)) != pdTRUE) {
        return -1;
    }

    int ret = uart_link_send_internal(data, len);

    xSemaphoreGive(tx_mutex_s);
    return ret;
}

static int uart_link_send_json_line(const char *json)
{
    if (!json) {
        return -1;
    }

    size_t len = strlen(json);
    if (len == 0 || len > 1024) {
        return -1;
    }

    /* 发送 JSON 加换行符 */
    if (xSemaphoreTake(tx_mutex_s, pdMS_TO_TICKS(100)) != pdTRUE) {
        return -1;
    }

    int ret = uart_link_send_internal((const uint8_t *)json, len);
    if (ret > 0) {
        ret += uart_link_send_internal((const uint8_t *)"\n", 1);
    }

    xSemaphoreGive(tx_mutex_s);
    return ret;
}

int link_uart_send_heartbeat(const char *json)
{
    return uart_link_send_json_line(json);
}

int link_uart_send_log(const char *json)
{
    return uart_link_send_json_line(json);
}

bool link_uart_is_connected(void)
{
    /* UART 有最近接收数据即认为在线 */
    uint32_t now = get_current_time_ms();
    uint32_t last = last_rx_time_ms;

    /* 5秒内有数据交互认为在线 */
    return link_up_s && (now - last) < 5000;
}

/* 处理接收到的 JSON 数据 */
static void process_received_json(const char *json)
{
    if (!json || strlen(json) == 0) {
        return;
    }

#if !BUILD_IS_RELEASE
    ESP_LOGI(tag_s, "RX JSON: %s", json);
#endif

    /* 更新最后接收时间 */
    last_rx_time_ms = get_current_time_ms();
    link_up_s = true;

    /* 调用遥控协议处理 JSON */
    remote_control_apply_json(json);
}

/* 处理 OTA 数据包（二进制格式） */
static void process_ota_packet(const uint8_t *data, uint16_t len)
{
    if (!data || len == 0) {
        return;
    }

    /* 通过通用 OTA 模块处理 */
    ota_binary_stream_process_packet(data, len);

    /* OTA 数据包也更新连接状态 */
    last_rx_time_ms = get_current_time_ms();
    link_up_s = true;
}

/* 检查数据是否为 OTA 命令（以 0x01/0x02/0x03 开头） */
static bool is_ota_command(uint8_t first_byte)
{
    return (first_byte == 0x01 || first_byte == 0x02 || first_byte == 0x03);
}

static void uart_rx_task(void *param)
{
    (void)param;

    uint8_t *data = (uint8_t *)malloc(UART_LINK_BUF_SIZE);
    if (!data) {
        ESP_LOGE(tag_s, "RX buffer alloc failed");
        vTaskDelete(NULL);
        return;
    }

    rx_buf_pos_s = 0;
    ota_rx_pos_s = 0;
    ota_rx_mode_s = false;

    while (1) {
        int len = uart_read_bytes(UART_LINK_PORT, data, UART_LINK_BUF_SIZE - 1,
                                  pdMS_TO_TICKS(UART_LINK_RX_TIMEOUT_MS));

        if (len > 0) {
            last_rx_time_ms = get_current_time_ms();

            /* 检查是否为 OTA 命令（首字节为 0x01/0x02/0x03） */
            if (len > 0 && is_ota_command(data[0])) {
                /* OTA 二进制数据模式 */
                process_ota_packet(data, len);
                continue;
            }

            /* JSON 文本模式 - 处理接收到的数据，按行分隔 */
            for (int i = 0; i < len; i++) {
                uint8_t ch = data[i];

                /* 如果遇到 OTA 命令字节，切换模式 */
                if (is_ota_command(ch) && i == 0 && rx_buf_pos_s == 0) {
                    /* 复制剩余数据到 OTA 缓冲区 */
                    uint16_t remaining = len - i;
                    if (remaining > sizeof(ota_rx_buf_s)) {
                        remaining = sizeof(ota_rx_buf_s);
                    }
                    memcpy(ota_rx_buf_s, data + i, remaining);
                    process_ota_packet(ota_rx_buf_s, remaining);
                    break;
                }

                if (ch == UART_FRAME_DELIMITER || ch == '\r') {
                    /* 找到行尾，处理 JSON */
                    if (rx_buf_pos_s > 0) {
                        rx_json_buf_s[rx_buf_pos_s] = '\0';
                        process_received_json(rx_json_buf_s);
                        rx_buf_pos_s = 0;
                    }
                } else {
                    /* 累积字符 */
                    if (rx_buf_pos_s < UART_JSON_MAX_BYTES) {
                        rx_json_buf_s[rx_buf_pos_s++] = ch;
                    } else {
                        /* 缓冲区溢出，重置 */
                        rx_buf_pos_s = 0;
                    }
                }
            }
        }

        /* 检查连接状态 */
        uint32_t now = get_current_time_ms();
        if (last_rx_time_ms > 0 && (now - last_rx_time_ms) > 5000) {
            link_up_s = false;
        }
    }

    free(data);
    vTaskDelete(NULL);
}

static void uart_heartbeat_task(void *param)
{
    (void)param;

    char devid[32] = {0};
    read_from_nvs(DEVICE_CFG_KEY_DEVICE_ID, devid, sizeof(devid));

    while (1) {
        vTaskDelay(pdMS_TO_TICKS(UART_HEART_PERIOD_MS));

        /* 生成心跳 JSON（与 BLE 0xFFE3 相同结构） */
        char *heartbeat = heart_payload_json_malloc(devid, NULL, false);
        if (heartbeat) {
            link_uart_send_heartbeat(heartbeat);
            free(heartbeat);
        }
    }
}

static esp_err_t uart_link_init_hardware(void)
{
    uart_config_t uart_cfg = {
        .baud_rate = CONFIG_APP_UART_LINK_BAUDRATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };

    esp_err_t err = uart_param_config(UART_LINK_PORT, &uart_cfg);
    if (err != ESP_OK) {
        ESP_LOGE(tag_s, "UART param config failed: %d", err);
        return err;
    }

    /* 设置引脚：GPIO17 TX, GPIO18 RX */
    int tx_gpio = CONFIG_APP_UART_LINK_TX_GPIO;
    int rx_gpio = CONFIG_APP_UART_LINK_RX_GPIO;

    if (tx_gpio < 0 || rx_gpio < 0) {
        ESP_LOGE(tag_s, "Invalid UART GPIO config: TX=%d, RX=%d", tx_gpio, rx_gpio);
        return ESP_ERR_INVALID_ARG;
    }

    err = uart_set_pin(UART_LINK_PORT, tx_gpio, rx_gpio,
                       UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    if (err != ESP_OK) {
        ESP_LOGE(tag_s, "UART set pin failed: %d", err);
        return err;
    }

    err = uart_driver_install(UART_LINK_PORT, UART_LINK_BUF_SIZE * 2,
                              UART_LINK_BUF_SIZE * 2, UART_LINK_QUEUE_SIZE,
                              &uart_queue_s, 0);
    if (err != ESP_OK) {
        ESP_LOGE(tag_s, "UART driver install failed: %d", err);
        return err;
    }

    return ESP_OK;
}

esp_err_t link_uart_start(void)
{
    ESP_LOGI(tag_s, "启动 UART 链路 (GPIO%d TX / GPIO%d RX, %d baud)",
             CONFIG_APP_UART_LINK_TX_GPIO, CONFIG_APP_UART_LINK_RX_GPIO,
             CONFIG_APP_UART_LINK_BAUDRATE);

    /* 初始化 UART OTA 模块 */
    uart_ota_init();

    /* 初始化 UART 硬件 */
    esp_err_t err = uart_link_init_hardware();
    if (err != ESP_OK) {
        return err;
    }

    /* 创建发送互斥锁 */
    tx_mutex_s = xSemaphoreCreateMutex();
    if (!tx_mutex_s) {
        ESP_LOGE(tag_s, "TX mutex create failed");
        uart_driver_delete(UART_LINK_PORT);
        return ESP_ERR_NO_MEM;
    }

    /* 启动遥控看门狗（与 BLE 模式相同） */
    remote_control_watchdog_start();

    /* 启动接收任务 */
    BaseType_t ret = xTaskCreate(uart_rx_task, "uart_rx",
                                 4096, NULL, 5, &rx_task_handle_s);
    if (ret != pdPASS) {
        ESP_LOGE(tag_s, "RX task create failed");
        vSemaphoreDelete(tx_mutex_s);
        tx_mutex_s = NULL;
        uart_driver_delete(UART_LINK_PORT);
        return ESP_ERR_NO_MEM;
    }

    /* 启动心跳任务 */
    ret = xTaskCreate(uart_heartbeat_task, "uart_hb",
                      4096, NULL, 5, &hb_task_handle_s);
    if (ret != pdPASS) {
        ESP_LOGE(tag_s, "Heartbeat task create failed");
        vTaskDelete(rx_task_handle_s);
        rx_task_handle_s = NULL;
        vSemaphoreDelete(tx_mutex_s);
        tx_mutex_s = NULL;
        uart_driver_delete(UART_LINK_PORT);
        return ESP_ERR_NO_MEM;
    }

    link_up_s = true;
    last_rx_time_ms = get_current_time_ms();

    ESP_LOGI(tag_s, "UART 链路启动成功");
    return ESP_OK;
}

void link_uart_stop(void)
{
    /* 停止心跳任务 */
    if (hb_task_handle_s) {
        vTaskDelete(hb_task_handle_s);
        hb_task_handle_s = NULL;
    }

    /* 停止接收任务 */
    if (rx_task_handle_s) {
        vTaskDelete(rx_task_handle_s);
        rx_task_handle_s = NULL;
    }

    /* 停止遥控看门狗 */
    remote_control_watchdog_stop();

    /* 删除互斥锁 */
    if (tx_mutex_s) {
        vSemaphoreDelete(tx_mutex_s);
        tx_mutex_s = NULL;
    }

    /* 卸载 UART 驱动 */
    uart_driver_delete(UART_LINK_PORT);

    link_up_s = false;

    ESP_LOGI(tag_s, "UART 链路已停止");
}
