#include "esp_log.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "esp_mac.h"
#include "esp_http_server.h"

#include "wifi_service.h"
#include "http_service.h"

static const char* TAG = "wifi_service";

wifi_service_t g_wifi_service;

esp_netif_t* wifi_ap_netif = NULL;

extern httpd_handle_t http_server;

static void wifi_event_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED)
    {
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*)event_data;
        ESP_LOGI(TAG, "---- 设备加入网络, MAC地址 :" MACSTR ", 编号(AID) = %d.", MAC2STR(event->mac), event->aid);
        start_webserver_handler(event_handler_arg);
        // wifi_service_stop_timer_clear();
    }
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED)
    {
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*)event_data;
        ESP_LOGI(TAG, "---- 设备退出网络, MAC地址 :" MACSTR ", 编号(AID) = %d.", MAC2STR(event->mac), event->aid);
        stop_webserver_handler(event_handler_arg);
        // wifi_service_stop_timer_clear();
    }
}

void wifi_ap_start(void)
{
    // 创建系统事件循环
    ESP_LOGI(TAG, "---- 创建系统事件循环...");
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    // 将WiFi的所有事件作为实例注册进系统事件循环中
    ESP_LOGI(TAG, "---- 注册WiFi事件实例...");
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, &http_server));

    // 初始化网卡相关的底层配置
    ESP_LOGI(TAG, "---- 网卡初始化...");
    ESP_ERROR_CHECK(esp_netif_init());

    // 以默认的方式创建一个ap类型的网卡
    ESP_LOGI(TAG, "---- 创建AP类型网卡...");
    wifi_ap_netif = esp_netif_create_default_wifi_ap();

    // 初始化WiFi底层配置
    ESP_LOGI(TAG, "---- WiFi初始化...");
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    // all configuration will only store in the memory
    esp_wifi_set_storage(WIFI_STORAGE_RAM);

    // 将WiFi设置成AP模式
    ESP_LOGI(TAG, "---- 配置WiFi为AP模式...");
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));

    // 创建AP配置
    ESP_LOGI(TAG, "---- 创建AP配置...");
    wifi_config_t wifi_config = {
        .ap = {
            .ssid = WIFI_AP_SSID,
            .password = WIFI_AP_PASSWD,
            .ssid_len = strlen(WIFI_AP_SSID),
            .channel = 11,
            .max_connection = 1,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK} };

    // 获取当前AP的MAC地址
    unsigned char wifi_ap_mac[6];
    esp_wifi_get_mac(WIFI_IF_AP, wifi_ap_mac);

    // 将MAC地址后两个字节转为字符串
    char wifi_ap_temp_str[5];
    sprintf(wifi_ap_temp_str, "%02X%02X", wifi_ap_mac[4], wifi_ap_mac[5]);

    // 将MAC地址拼接到 ESP_WIFI_SSID 后面
    char wifi_ap_ssid[32] = WIFI_AP_SSID;
    strcat(wifi_ap_ssid, wifi_ap_temp_str);

    // 重新配置 ssid 和 ssid_len
    memcpy(wifi_config.ap.ssid, wifi_ap_ssid, sizeof(wifi_config.ap.ssid));
    wifi_config.ap.ssid_len = strlen(wifi_ap_ssid);

    // 配置AP的属性
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));

    // 关闭WiFi省电模式
    esp_wifi_set_ps(WIFI_PS_NONE);

    // 设置WiFi功率为最大 20dBm
    esp_wifi_set_max_tx_power(20);

    // 开启WiFi
    ESP_LOGI(TAG, "---- 开启WiFi, 名称 : %s 密码 : %s", wifi_config.ap.ssid, wifi_config.ap.password);
    ESP_ERROR_CHECK(esp_wifi_start());
}

void wifi_ap_stop(void)
{
    // 关闭WiFi
    ESP_LOGI(TAG, "---- 关闭WiFi...");
    ESP_ERROR_CHECK(esp_wifi_stop());

    // WiFi反初始化
    ESP_LOGI(TAG, "---- WiFi反初始化...");
    ESP_ERROR_CHECK(esp_wifi_deinit());

    // 销毁网卡实例
    ESP_LOGI(TAG, "---- 销毁网卡实例...");
    esp_netif_destroy_default_wifi(wifi_ap_netif);

    // 网卡反初始化 - 官方未实现的功能
    // ESP_LOGI(TAG, "---- 网卡反初始化...");
    // ESP_ERROR_CHECK(esp_netif_deinit());

    // 注销WiFi事件实例
    ESP_LOGI(TAG, "---- 注销WiFi事件实例...");
    ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler));

    // 删除系统事件循环
    ESP_LOGI(TAG, "---- 删除系统事件循环...");
    ESP_ERROR_CHECK(esp_event_loop_delete_default());
}

unsigned char wifi_turn_on(void)
{
    unsigned char ret;

    if (g_wifi_service.status == WIFI_SERVICE_STOP)
    {
        g_wifi_service.status = WIFI_SERVICE_START;
        wifi_ap_start();
        ret = WIFI_SERVICE_OK;
    }
    else if (g_wifi_service.status == WIFI_SERVICE_START)
    {
        ret = WIFI_SERVICE_START;
    }
    else
    {
        ret = WIFI_SERVICE_ERR;
    }

    return ret;
}

unsigned char wifi_turn_off(void)
{
    unsigned char ret;

    if (g_wifi_service.status == WIFI_SERVICE_START)
    {
        g_wifi_service.status = WIFI_SERVICE_STOP;
        wifi_ap_stop();
        ret = WIFI_SERVICE_OK;
    }
    else if (g_wifi_service.status == WIFI_SERVICE_STOP)
    {
        ret = WIFI_SERVICE_STOP;
    }
    else
    {
        ret = WIFI_SERVICE_ERR;
    }

    return ret;
}

void wifi_service_status_init()
{
    g_wifi_service.status = WIFI_SERVICE_STOP;
}
