#include <glad/glad.h>  // MUST be FIRST! Provides OpenGL functions
#define GLFW_INCLUDE_NONE  // Tell GLFW not to include OpenGL headers (GLAD does it)
#include "TranslationUI.h"
#include "../utils/Config.h"
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <iostream>
#include <thread>

namespace secondvoice {

TranslationUI::TranslationUI(int width, int height)
    : width_(width)
    , height_(height) {
}

TranslationUI::~TranslationUI() {
    if (window_) {
        ImGui_ImplOpenGL3_Shutdown();
        ImGui_ImplGlfw_Shutdown();
        ImGui::DestroyContext();
        glfwDestroyWindow(window_);
        glfwTerminate();
    }
}

bool TranslationUI::initialize() {
    // Initialize GLFW
    std::cout << "[UI] Initializing GLFW..." << std::endl;
    glfwSetErrorCallback([](int error, const char* description) {
        std::cerr << "[GLFW Error " << error << "] " << description << std::endl;
    });

    if (!glfwInit()) {
        std::cerr << "[UI] Failed to initialize GLFW" << std::endl;
        return false;
    }
    std::cout << "[UI] GLFW initialized successfully" << std::endl;

    // FORCE high-performance GPU (NVIDIA/AMD dedicated)
    std::cout << "[UI] Requesting high-performance GPU..." << std::endl;

    // OpenGL 3.3 - core profile
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // Create window
    std::cout << "[UI] Creating GLFW window (" << width_ << "x" << height_ << ")..." << std::endl;
    window_ = glfwCreateWindow(width_, height_, "SecondVoice - Live Translation", nullptr, nullptr);
    if (!window_) {
        std::cerr << "[UI] Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return false;
    }
    std::cout << "[UI] GLFW window created successfully" << std::endl;

    glfwMakeContextCurrent(window_);
    glfwSwapInterval(1);  // Enable vsync

    // Initialize GLAD - MUST happen after glfwMakeContextCurrent!
    std::cout << "[UI] Initializing GLAD OpenGL loader..." << std::endl;
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cerr << "[UI] Failed to initialize GLAD!" << std::endl;
        glfwDestroyWindow(window_);
        glfwTerminate();
        return false;
    }
    std::cout << "[UI] GLAD initialized successfully" << std::endl;

    // Query OpenGL context to see which GPU we got
    const GLubyte* vendor = glGetString(GL_VENDOR);
    const GLubyte* renderer = glGetString(GL_RENDERER);
    const GLubyte* version = glGetString(GL_VERSION);

    std::cout << "[UI] ========================================" << std::endl;
    std::cout << "[UI] OpenGL Context Info:" << std::endl;
    std::cout << "[UI]   Vendor:   " << (vendor ? (const char*)vendor : "Unknown") << std::endl;
    std::cout << "[UI]   Renderer: " << (renderer ? (const char*)renderer : "Unknown") << std::endl;
    std::cout << "[UI]   Version:  " << (version ? (const char*)version : "Unknown") << std::endl;
    std::cout << "[UI] ========================================" << std::endl;

    // Initialize ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;

    // Load Chinese font from Windows system fonts
    float font_size = static_cast<float>(Config::getInstance().getUIConfig().font_size);
    std::cout << "[UI] Loading Chinese font (size: " << font_size << ")..." << std::endl;
    ImFontConfig font_config;
    font_config.OversampleH = 2;
    font_config.OversampleV = 2;

    // Try common Chinese fonts on Windows
    const char* chinese_fonts[] = {
        "C:\\Windows\\Fonts\\msyh.ttc",      // Microsoft YaHei
        "C:\\Windows\\Fonts\\simhei.ttf",    // SimHei
        "C:\\Windows\\Fonts\\simsun.ttc",    // SimSun
        "C:\\Windows\\Fonts\\mingliub.ttc",  // MingLiU
    };

    ImFont* font = nullptr;
    for (const char* font_path : chinese_fonts) {
        font = io.Fonts->AddFontFromFileTTF(
            font_path,
            font_size,
            &font_config,
            io.Fonts->GetGlyphRangesChineseFull()
        );
        if (font) {
            std::cout << "[UI] Loaded font: " << font_path << std::endl;
            break;
        }
    }

    if (!font) {
        std::cout << "[UI] Warning: No Chinese font found, using default (Chinese chars won't display)" << std::endl;
        io.Fonts->AddFontDefault();
    }

    ImGui::StyleColorsDark();

    ImGui_ImplGlfw_InitForOpenGL(window_, true);

    // TEST: Compile a simple shader to see REAL error messages
    std::cout << "[UI] Testing shader compilation..." << std::endl;
    const char* vertexShaderSource = R"(
#version 130
in vec2 Position;
in vec2 UV;
in vec4 Color;
varying vec2 Frag_UV;
varying vec4 Frag_Color;
void main() {
    Frag_UV = UV;
    Frag_Color = Color;
    gl_Position = vec4(Position, 0, 1);
}
)";

    GLuint testShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(testShader, 1, &vertexShaderSource, NULL);
    glCompileShader(testShader);

    GLint success;
    glGetShaderiv(testShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[1024];
        glGetShaderInfoLog(testShader, 1024, NULL, infoLog);
        std::cerr << "[UI] ==================== SHADER COMPILATION ERROR ====================" << std::endl;
        std::cerr << infoLog << std::endl;
        std::cerr << "[UI] ====================================================================" << std::endl;
    } else {
        std::cout << "[UI] Test shader compiled successfully!" << std::endl;
    }
    glDeleteShader(testShader);

    // DEBUG: Check if GLAD loaded glCreateShader
    std::cout << "[UI] DEBUG: glCreateShader function pointer = " << (void*)glCreateShader << std::endl;
    if (glCreateShader == nullptr) {
        std::cerr << "[UI] ERROR: glCreateShader is NULL!" << std::endl;
        return false;
    }

    // Explicitly specify GLSL version for OpenGL 3.3 core profile
    // On Windows, auto-detection (nullptr) can fail, so we specify "#version 330"
    std::cout << "[UI] Initializing ImGui OpenGL3 backend with GLSL 330..." << std::endl;
    ImGui_ImplOpenGL3_Init("#version 330");

    // Context stays in main thread - no need to release

    return true;
}

void TranslationUI::makeContextCurrent() {
    if (window_) {
        std::cout << "[UI] Making OpenGL context current in thread: " << std::this_thread::get_id() << std::endl;
        glfwMakeContextCurrent(window_);
    }
}

void TranslationUI::render() {
    glfwPollEvents();

    // Start ImGui frame
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    // Main window (full viewport)
    ImGui::SetNextWindowPos(ImVec2(0, 0));
    ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);
    ImGui::Begin("SecondVoice", nullptr,
        ImGuiWindowFlags_NoTitleBar |
        ImGuiWindowFlags_NoResize |
        ImGuiWindowFlags_NoMove |
        ImGuiWindowFlags_NoCollapse);

    // Two-column layout: main content on left, audio panel on right
    float audio_panel_width = 280.0f;
    float main_width = ImGui::GetWindowWidth() - audio_panel_width - 20.0f;

    // Left column - main content
    ImGui::BeginChild("MainContent", ImVec2(main_width, -1), false);

    ImGui::Text("SecondVoice - Live Translation");
    ImGui::Separator();
    ImGui::Spacing();

    renderAccumulated();
    renderTranslations();
    renderControls();
    renderStatus();

    ImGui::EndChild();

    ImGui::SameLine();

    // Right column - audio panel
    ImGui::BeginChild("AudioPanel", ImVec2(audio_panel_width, -1), true);
    renderAudioPanel();
    ImGui::EndChild();

    ImGui::End();

    // Rendering
    ImGui::Render();
    int display_w, display_h;
    glfwGetFramebufferSize(window_, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    glfwSwapBuffers(window_);
}

bool TranslationUI::shouldClose() const {
    return glfwWindowShouldClose(window_);
}

void TranslationUI::addTranslation(const std::string& chinese, const std::string& french) {
    messages_.push_back({chinese, french});
}

void TranslationUI::setAccumulatedText(const std::string& chinese, const std::string& french) {
    accumulated_chinese_ = chinese;
    accumulated_french_ = french;
}

void TranslationUI::renderAccumulated() {
    if (accumulated_chinese_.empty() && accumulated_french_.empty()) {
        return;
    }

    ImGui::Text("Texte Recomposé");
    ImGui::SameLine();
    if (ImGui::SmallButton("Clear")) {
        clear_requested_ = true;
    }
    ImGui::Separator();

    ImGui::BeginChild("Accumulated", ImVec2(0, 150), true);

    // Chinese accumulated text
    ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.9f, 0.5f, 1.0f));  // Yellow
    ImGui::TextWrapped("%s", accumulated_chinese_.c_str());
    ImGui::PopStyleColor();

    ImGui::Spacing();

    // French accumulated text
    ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.8f, 1.0f));  // Cyan
    ImGui::TextWrapped("%s", accumulated_french_.c_str());
    ImGui::PopStyleColor();

    ImGui::EndChild();

    ImGui::Spacing();
}

void TranslationUI::renderTranslations() {
    ImGui::Text("Segments (détail)");
    ImGui::Separator();

    // Height depends on whether accumulated section is shown
    float height = (accumulated_chinese_.empty() && accumulated_french_.empty()) ? -120 : -120;
    ImGui::BeginChild("Translations", ImVec2(0, height), true);

    for (const auto& msg : messages_) {
        ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.8f, 1.0f, 1.0f));
        ImGui::TextWrapped("中文: %s", msg.chinese.c_str());
        ImGui::PopStyleColor();

        ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
        ImGui::TextWrapped("FR: %s", msg.french.c_str());
        ImGui::PopStyleColor();

        ImGui::Spacing();
        ImGui::Separator();
        ImGui::Spacing();
    }

    if (auto_scroll_ && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
        ImGui::SetScrollHereY(1.0f);
    }

    ImGui::EndChild();
}

void TranslationUI::renderControls() {
    ImGui::Spacing();

    // Center the stop button
    float button_width = 200.0f;
    float window_width = ImGui::GetWindowWidth();
    ImGui::SetCursorPosX((window_width - button_width) * 0.5f);

    if (ImGui::Button("STOP RECORDING", ImVec2(button_width, 40))) {
        stop_requested_ = true;
    }

    ImGui::Spacing();
}

void TranslationUI::renderStatus() {
    ImGui::Separator();

    // Format duration as MM:SS
    int minutes = recording_duration_ / 60;
    int seconds = recording_duration_ % 60;
    ImGui::Text("Recording... Duration: %02d:%02d", minutes, seconds);

    if (!processing_status_.empty()) {
        ImGui::SameLine();
        ImGui::Text(" | Status: %s", processing_status_.c_str());
    }
}

void TranslationUI::renderAudioPanel() {
    ImGui::Text("Audio Monitor");
    ImGui::Separator();
    ImGui::Spacing();

    // Current volume display
    ImGui::Text("Volume Level");

    // RMS meter (horizontal bar)
    float rms_normalized = std::min(current_rms_ * 10.0f, 1.0f);  // Scale for visibility
    ImVec4 rms_color = rms_normalized > vad_threshold_ * 10.0f ?
        ImVec4(0.2f, 0.8f, 0.2f, 1.0f) :  // Green if above threshold
        ImVec4(0.5f, 0.5f, 0.5f, 1.0f);   // Gray if below

    ImGui::PushStyleColor(ImGuiCol_PlotHistogram, rms_color);
    ImGui::ProgressBar(rms_normalized, ImVec2(-1, 20), "");
    ImGui::PopStyleColor();

    ImGui::Text("RMS: %.4f", current_rms_);

    ImGui::Spacing();

    // Peak meter
    ImGui::Text("Peak Level");
    float peak_normalized = std::min(current_peak_, 1.0f);
    ImVec4 peak_color = peak_normalized > vad_peak_threshold_ ?
        ImVec4(0.2f, 0.8f, 0.2f, 1.0f) :
        ImVec4(0.5f, 0.5f, 0.5f, 1.0f);

    ImGui::PushStyleColor(ImGuiCol_PlotHistogram, peak_color);
    ImGui::ProgressBar(peak_normalized, ImVec2(-1, 20), "");
    ImGui::PopStyleColor();

    ImGui::Text("Peak: %.4f", current_peak_);

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    // VAD Threshold sliders
    ImGui::Text("VAD Settings");
    ImGui::Spacing();

    ImGui::Text("RMS Threshold");
    ImGui::SliderFloat("##rms_thresh", &vad_threshold_, 0.001f, 0.1f, "%.3f");

    // Draw threshold line on the RMS meter area
    ImGui::Spacing();

    ImGui::Text("Peak Threshold");
    ImGui::SliderFloat("##peak_thresh", &vad_peak_threshold_, 0.01f, 0.3f, "%.3f");

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    // Status indicator
    bool is_active = (current_rms_ >= vad_threshold_) && (current_peak_ >= vad_peak_threshold_);
    if (is_active) {
        ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.2f, 1.0f, 0.2f, 1.0f));
        ImGui::Text(">> VOICE DETECTED <<");
        ImGui::PopStyleColor();
    } else {
        ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
        ImGui::Text("   (silence)");
        ImGui::PopStyleColor();
    }

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    // Cost tracking
    ImGui::Text("API Usage");
    ImGui::Spacing();

    // Audio sent to Whisper
    int minutes = static_cast<int>(total_audio_seconds_) / 60;
    int seconds = static_cast<int>(total_audio_seconds_) % 60;
    ImGui::Text("Audio: %d:%02d", minutes, seconds);
    ImGui::Text("Whisper calls: %d", whisper_calls_);
    ImGui::Text("Claude calls: %d", claude_calls_);

    ImGui::Spacing();

    // Estimated cost
    float cost = getEstimatedCost();
    ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.8f, 0.3f, 1.0f));  // Gold
    ImGui::Text("Est. cost: $%.4f", cost);
    ImGui::PopStyleColor();

    ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
    ImGui::Text("(Whisper $0.006/min)");
    ImGui::Text("(Haiku ~$0.001/call)");
    ImGui::PopStyleColor();
}

} // namespace secondvoice
