#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "beep.h"
#include "usmart.h"
#include "sram.h"
#include "lan8720.h"
#include "timer.h"
#include "rtc.h"
#include "adc.h"
#include "malloc.h"
#include "lwip/netif.h"
#include "lwip_comm.h"
#include "lwipopts.h"
#include "tcp_client_demo.h"
#include "tcp_server_demo.h"
#include "udp_demo.h"
#include "httpd.h"

// ==========================
// MQTT SDK 头文件
// ==========================
#include "mqtt_client_sdk.h"

// ==========================
// MQTT 实际产品配置
// ==========================
#define MQTT_BROKER_IP          "192.168.1.100"    // 你的MQTT服务器IP
#define MQTT_BROKER_PORT        1883
#define MQTT_CLIENT_ID          "STM32F407_DEVICE"
#define MQTT_SUB_TOPIC          "stm32/cmd"
#define MQTT_PUB_TOPIC          "stm32/data"

// ==========================
// MQTT 全局句柄
// ==========================
static MqttSdkClient g_mqtt_client = NULL;

// ==========================
// MQTT 消息接收回调
// ==========================
static void mqtt_msg_callback(const MqttSdkMsg* msg)
{
    if(!msg || !msg->topic || !msg->payload) return;

    printf("\r\n[MQTT 收到消息]\r\n");
    printf("Topic: %s\r\n", msg->topic);
    printf("Data: %.*s\r\n", (int)msg->payload_len, msg->payload);
}

// ==========================
// MQTT 连接状态回调
// ==========================
static void mqtt_conn_callback(const MqttSdkBrokerRespStatus* status)
{
    if(!status) return;

    if(status->resp_type == MQTT_SDK_BROKER_RESP_CONNACK)
    {
        if(status->err_code == MQTT_SDK_OK)
        {
            printf("[MQTT] 连接成功 ✅\r\n");
            LED1 = 0;

            // 连接成功 → 自动订阅
            xxl_mqtt_sdk_client_subscribe(g_mqtt_client, MQTT_SUB_TOPIC, MQTT_SDK_QOS0, NULL);
        }
        else
        {
            printf("[MQTT] 连接失败 ❌\r\n");
        }
    }
}

// ==========================
// MQTT 初始化
// ==========================
static void mqtt_init(void)
{
    MqttSdkClientCfg cfg = {0};

    // 全局初始化
    xxl_mqtt_sdk_global_init();

    // 配置
    cfg.client_id     = MQTT_CLIENT_ID;
    cfg.broker_ip     = MQTT_BROKER_IP;
    cfg.broker_port   = MQTT_BROKER_PORT;
    cfg.clean_start   = true;
    cfg.keep_alive    = 60;
    cfg.mqtt_version  = MQTT_SDK_PROTOCOL_V311;

    // 创建客户端
    g_mqtt_client = xxl_mqtt_sdk_client_create(&cfg, mqtt_msg_callback, mqtt_conn_callback);

    if(g_mqtt_client)
    {
        xxl_mqtt_sdk_client_connect(g_mqtt_client);
        printf("[MQTT] 正在连接服务器...\r\n");
    }
}

// ==========================
// MQTT 发布测试
// ==========================
static void mqtt_publish_test(void)
{
    const char* data = "STM32F407 MQTT OK";
    MqttSdkMsg msg = {0};
    msg.topic = MQTT_PUB_TOPIC;
    msg.payload = (uint8_t*)data;
    msg.payload_len = strlen(data);
    msg.qos = MQTT_SDK_QOS0;

    xxl_mqtt_sdk_client_publish(g_mqtt_client, &msg);
    printf("[MQTT] 上传：%s\r\n", data);
}

/************************************************
 ALIENTEK 探索者 STM32F407 实验58
 网络通信实验-HAL库版本
************************************************/

//显示UI
void lwip_test_ui(u8 mode)
{
    u8 speed;
    u8 buf[30];
    POINT_COLOR=RED;
    if(mode&1<<0)
    {
        LCD_Fill(30,30,lcddev.width,110,WHITE);
        LCD_ShowString(30,30,200,16,16,"Explorer STM32F4");
        LCD_ShowString(30,50,200,16,16,"Ethernet lwIP Test");
        LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(30,90,200,16,16,"2017/5/15");
    }
    if(mode&1<<1)
    {
        LCD_Fill(30,110,lcddev.width,lcddev.height,WHITE);
        LCD_ShowString(30,110,200,16,16,"lwIP Init Successed");
        if(lwipdev.dhcpstatus==2)
            sprintf((char*)buf,"DHCP IP:%d.%d.%d.%d",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
        else
            sprintf((char*)buf,"Static IP:%d.%d.%d.%d",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);

        LCD_ShowString(30,130,210,16,16,buf);
        speed=LAN8720_Get_Speed();

        if(speed&1<<1)
            LCD_ShowString(30,150,200,16,16,"Ethernet Speed:100M");
        else
            LCD_ShowString(30,150,200,16,16,"Ethernet Speed:10M");

        LCD_ShowString(30,170,200,16,16,"KEY0:TCP Server Test");
        LCD_ShowString(30,190,200,16,16,"KEY1:TCP Client Test");
        LCD_ShowString(30,210,200,16,16,"KEY2:UDP Test");
    }
}

int main(void)
{
    u8 t;
    u8 key;

    HAL_Init();
    Stm32_Clock_Init(336,8,2,7);
    delay_init(168);
    uart_init(115200);
    usmart_dev.init(84);
    LED_Init();
    BEEP_Init();
    KEY_Init();
    LCD_Init();
    SRAM_Init();
    MY_ADC_Init();
    RTC_Init();
    TIM3_Init(1000-1,840-1);

    my_mem_init(SRAMIN);
    my_mem_init(SRAMEX);
    my_mem_init(SRAMCCM);

    POINT_COLOR=RED;
    LED0=0;
    lwip_test_ui(1);
    LCD_ShowString(30,110,200,16,16,"lwIP Initing...");

    while(lwip_comm_init())
    {
        LCD_ShowString(30,110,200,20,16,"LWIP Init Falied! ");
        delay_ms(500);
        LCD_ShowString(30,110,200,16,16,"Retrying...       ");
        delay_ms(500);
    }

    LCD_ShowString(30,110,200,20,16,"LWIP Init Success!");
    LCD_ShowString(30,130,200,16,16,"DHCP IP configing...");

#if LWIP_DHCP
    while((lwipdev.dhcpstatus!=2)&&(lwipdev.dhcpstatus!=0XFF))
    {
        lwip_periodic_handle();
    }
#endif

    lwip_test_ui(2);
    httpd_init();

    // ==========================
    // 网络初始化完成 → 启动MQTT
    // ==========================
    mqtt_init();

    while(1)
    {
        key=KEY_Scan(0);
        switch(key)
        {
            case KEY0_PRES:
                tcp_server_test();
                lwip_test_ui(3);
                break;

            case KEY1_PRES:
                tcp_client_test();
                lwip_test_ui(3);
                break;

            case KEY2_PRES:
                udp_demo_test();
                lwip_test_ui(3);
                break;
        }

        lwip_periodic_handle();

        // ==========================
        // MQTT 轮询（必须加）
        // ==========================
        if(g_mqtt_client != NULL)
        {
            xxl_mqtt_sdk_client_loop(g_mqtt_client);
        }

        delay_ms(2);
        t++;

        if(t==100)
            LCD_ShowString(30,230,200,16,16,"Please choose a mode!");

        if(t==200)
        {
            t=0;
            LCD_Fill(30,230,230,230+16,WHITE);
            LED0=!LED0;
        }
    }
}
