#if DEBUG_MEMORY_LOG_ENABLED
#define DEBUG_PRINT_ENABLE 1
#else
#define DEBUG_PRINT_ENABLE 0
#endif
#include <xs1.h>
#include <platform.h>
#include <print.h>
#include <string.h>
#include "xmath/filter.h"
#include "stdio.h"
#include "xc_ptr.h"
#include "eq.h"
#include "share_buffer.h"
#include "debug_print.h"
#include "eq_flash_storage.h"

#if 0
#define DPRINTF(...) printf(__VA_ARGS__)
#else
#define DPRINTF(...)
#endif

#define LEN_FADE_ (2024)

    // EQ Flash存储初始化标志
int eq_flash_initialized = 0;
extern unsigned int is_mode_changed(void);
extern void change_eq_mode(unsigned sample_freq);
extern void clear_eq_status(unsigned sample_freq, unsigned ch_no);
extern unsigned int g_request_eq_mode;
extern unsigned int g_eq_enable;  // 改动原因：添加EQ使能开关外部声明，用于初始化时检查EQ状态
extern unsigned int g_saved_eq_mode;  // 改动原因：添加保存模式外部声明，用于初始化时设置保存的模式
extern void debug_print_eq_params(unsigned sample_freq);
extern uint32_t get_reference_time(void);
extern void update_eq_post_gain(void);
extern unsigned int g_eq_sample_rate;
extern unsigned g_windows_detect_done;
extern unsigned g_dnr_init_flag;
extern unsigned g_ex3d_key_verified;

#pragma unsafe arrays
void dsp_core0(void)
{
    unsigned t0,t1;
    static int audio_in_samples[2]; // idx 0: input_samples
    static int audio_out_samples[2]; // idx 0: input_samples
    static unsigned int usb_to_dsp_ratio = 1;
    static int buffer_in_active = 0;
    static int buffer_out_active = 0;
    static unsigned int sample_freq = 48000 ;
    unsigned b_fade_in = 0;
    unsigned u_in_step;
    unsigned b_fade_out = 0;
    unsigned u_out_step;

    // EQ Flash存储初始化标志

    delay_milliseconds(300);
    unsigned windows_detect_done, dnr_init_flag, ex3d_key_verified;
    GET_SHARED_GLOBAL(windows_detect_done, g_windows_detect_done);
#if DNR_ENABLE
    GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag);
#endif
#if USE_EX3D
    GET_SHARED_GLOBAL(ex3d_key_verified, g_ex3d_key_verified);
#endif
    while ((windows_detect_done == 0)
#if DNR_ENABLE
     || (dnr_init_flag == 0) 
#endif
#if USE_EX3D
     || (ex3d_key_verified == 0)
#endif
     ) {
        asm("nop");
        GET_SHARED_GLOBAL(windows_detect_done, g_windows_detect_done);
#if DNR_ENABLE
        GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag);
#endif
#if USE_EX3D
        GET_SHARED_GLOBAL(ex3d_key_verified, g_ex3d_key_verified);
#endif

    }

#if EQ_EN

    uint32_t time = get_reference_time(), time2;
    // EQ Flash存储初始化 - 只在第一次运行时执行
    if (eq_flash_initialized == 0) {
        // 延迟更长时间，确保QSPI Flash完全初始化
        debug_printf("Initializing EQ Flash storage system\n");

        // 初始化EQ Flash存储系统
        if (eq_flash_init() == 0) {
            debug_printf("EQ Flash storage initialized successfully\n");
            init_mode_info();
            eq_load_gain_and_names();
            // 检查Flash中是否有EQ参数数据
            debug_printf("Loading EQ parameters from Flash using simplified storage\n");
            // 简化加载逻辑：每个模式只加载一次，会自动应用到所有采样率和通道
            int loaded_modes = 0;

            for (int mode = EQ_USER_MODE_MIN; mode <= EQ_USER_MODE_MAX; mode++) {
                if (eq_load_all_params_and_calculate_coefficients(44100, mode) == 0) {
                    loaded_modes++;
                    debug_printf("Loaded mode %d parameters from Flash (applied to all sample rates and channels)\n", mode);
                }
            }
            debug_printf("Loaded %d EQ modes from Flash successfully\n", loaded_modes);

            // 从mode info里获取gain值，并相应的赋值到eq数组的post gain
            update_eq_post_gain();
            // 从Flash加载并设置当前EQ模式和使能状态
            // 改动原因：修复EQ开关逻辑问题，确保从Flash加载模式时正确设置g_saved_eq_mode和g_eq_enable
            // eq_flash_load_current_mode()会同时加载模式并设置g_eq_enable
            int saved_mode_result = eq_flash_load_current_mode();

            // 改动原因：确保g_eq_enable被正确加载，无论模式加载是否成功
            // eq_flash_load_current_mode()已经设置了g_eq_enable，这里读取确认
            unsigned int eq_enable = g_eq_enable;

            if (saved_mode_result >= 0 && saved_mode_result <= 9) {
                uint8_t saved_mode = (uint8_t)saved_mode_result;
                debug_printf("Loaded current EQ mode %d and enable %d from Flash\n", saved_mode, eq_enable);

                // 改动原因：将eq_enable独立为全局开关，所有模式共用一个开关
                // 无论EQ是否启用，都设置到Flash中保存的模式，eq_enable只控制EQ处理开关
                g_saved_eq_mode = saved_mode;
                SET_SHARED_GLOBAL(g_request_eq_mode, saved_mode);
                debug_printf("EQ initialization: Set mode to %d from Flash, EQ enable: %d (global switch, independent of mode)\n",
                            saved_mode, eq_enable);
            } else {
                // Flash加载失败时，使用默认模式0，EQ默认禁用
                // 改动原因：如果模式加载失败，确保g_eq_enable也被设置为默认值0
                g_saved_eq_mode = 0;
                SET_SHARED_GLOBAL(g_request_eq_mode, 0);
                g_eq_enable = 0;
                eq_enable = 0;  // 同步本地变量
                debug_printf("Failed to load EQ mode from Flash, using default mode 0, EQ disabled (enable: %d)\n", eq_enable);
            }

        } else {
            debug_printf("Failed to initialize EQ Flash storage system, continuing without Flash storage\n");
            // 即使Flash初始化失败，也标记为已初始化，避免重复尝试
            // 系统将继续运行，只是不使用Flash存储功能
        }

        eq_single_param_database_init();
        time2 = get_reference_time();
        debug_printf("EQ Flash storage initialized time %lu\n", time2 - time);
        eq_flash_initialized = 1;

        init_eq_data(48000);
        clear_ring_buffer(0);
        clear_ring_buffer(1);
        clear_ring_buffer(2);
        clear_ring_buffer(3);
    }


    while (1)
    {
        if(is_ring_buffer_empty(0) && is_ring_buffer_empty(1))
        {
           // delay_microseconds(1);
        }
        else
        {
            GET_SHARED_GLOBAL(sample_freq, g_eq_sample_rate);
            if (sample_freq == 0) sample_freq = 48000;
            audio_in_samples[0] = read_from_ring_buffer(0);
            audio_in_samples[1] = read_from_ring_buffer(1);

            if (is_mode_changed() && b_fade_out == 0 && b_fade_in == 0)
            {

                debug_printf("mode changed ====================== \n");
                //debug_print_eq_params(sample_freq);
                b_fade_out=1;
                u_out_step=1;
            }


            audio_out_samples[0] = handler_eq_filter(sample_freq, 0,  audio_in_samples[0]);
            audio_out_samples[1] = handler_eq_filter(sample_freq, 1,  audio_in_samples[1]);


            if(b_fade_out)
            {
                audio_out_samples[0] /= LEN_FADE_;
                audio_out_samples[0] *= (LEN_FADE_-u_out_step) ;

                audio_out_samples[1] /= LEN_FADE_;
                audio_out_samples[1] *= (LEN_FADE_-u_out_step) ;

                ++u_out_step;
            }

            if(b_fade_out == 1 && u_out_step == LEN_FADE_){
                    b_fade_out = 0;
                    change_eq_mode(sample_freq);
                    clear_eq_status(sample_freq, 0);
                    clear_eq_status(sample_freq, 1);
                    clear_ring_buffer(0);
                    clear_ring_buffer(1);
                    b_fade_in=1;
                    u_in_step=1;
                }


            if (b_fade_in)
            {
                audio_out_samples[0] /= LEN_FADE_;
                audio_out_samples[0] *= (u_in_step) ;

                audio_out_samples[1] /= LEN_FADE_;
                audio_out_samples[1] *= (u_in_step);

                if(++u_in_step >= LEN_FADE_){
                    b_fade_in = 0;
                }
            }

            write_to_ring_buffer(2, audio_out_samples[0]);
            write_to_ring_buffer(3, audio_out_samples[1]);
        }
    }
#endif
}
