#include "font_system.h"

#include <ranges>

#include "emoji_detector.h"

void font_manager::destroy() {
    fonts_.clear();
    emoji_font_ids_.clear();
    atlas_manager_.clear();
    primary_font_id_ = -1;
    next_font_id_ = 0;
    destroy_font_system();
}

void font_manager::load_default_font() {
#if MIRAGE_PLATFORM_WINDOWS
    add_font(L"C:/Windows/Fonts/msyh.ttc");
    add_font(L"C:/Windows/Fonts/seguiemj.ttf");
#else
	static_assert(false, "暂时不支持当前平台的默认字体加载");
#endif
}

int font_manager::add_font(const std::filesystem::path& in_font_path, const std::string& in_font_type) {
    const auto font = create_font_face(in_font_path);
    if (!font) {
        return -1;
    }

    const auto font_id = next_font_id_++;
    fonts_[font_id] = font;

    // 如果支持彩色表情或明确指定为表情字体，添加到表情字体列表
    if (font->supports_color_emoji() || in_font_type == "emoji") {
        emoji_font_ids_.push_back(font);
    }

    // 如果是第一个添加的字体，自动设为主字体
    if (primary_font_id_ == -1) {
        primary_font_id_ = font_id;
    }

    return font_id;
}

std::shared_ptr<font_face_interface> font_manager::get_font_for_code_point(
    const std::shared_ptr<font_face_interface>& in_custom_primary_font, const uint32_t in_code_point,
    uint32_t* out_glyph_index) {
    // **辅助 Lambda：检查字体并更新字形索引**
    auto check_font = [&](const std::shared_ptr<font_face_interface>& font) -> std::shared_ptr<font_face_interface> {
        if (!font)
            return nullptr; // 跳过空指针

        // **调用字体接口查找字形索引 (Assuming 0 means 'not found')**
        const uint32_t glyph_id = font->find_glyph_index(in_code_point);
        if (glyph_id > 0) {
            // **如果找到字形，设置输出参数并返回字体**
            if (out_glyph_index) {
                *out_glyph_index = glyph_id;
            }
            return font; // 找到字形
        }
        return nullptr; // 在此字体中未找到字形
    };

    // **1. 尝试自定义主字体 (如果提供了)**
    if (auto found_font = check_font(in_custom_primary_font)) {
        return found_font; // 在主字体中找到，直接返回
    }

    // 确定字符类型
    const bool is_emoji = emoji_detector::is_emoji(in_code_point);

    // **2. 定义字体过滤器**
    //    此过滤器排除了空指针字体和已检查过的主字体。
    //    注意: 更复杂的过滤器可以基于 is_emoji 和字体元数据 (例如 is_emoji_font())
    //    来优先选择特定类型的字体（例如，为表情符号优先选择表情字体）。
    auto font_filter = [&](const std::shared_ptr<font_face_interface>& font) {
        // **确保字体有效且不是我们已经检查过的主字体**
        if (is_emoji) {
            return std::ranges::contains(emoji_font_ids_, font);
        }
        return font != nullptr && font != in_custom_primary_font;
    };

    // **3. 遍历字体管理器中所有其他适用的字体**
    for (const auto& font : std::views::values(fonts_) | std::views::filter(font_filter)) {
        // **检查当前遍历到的字体**
        if (auto found_font = check_font(font)) {
            return found_font; // 在其他受管字体中找到，返回
        }
    }

    // **4. 最终回退逻辑**
    //    如果代码执行到这里，表示在主字体（如果提供）和所有其他过滤后的字体中都未找到该字形。
    //    (可选) 在这里可以尝试一个全局默认回退字体：
    //    if (m_global_fallback_font) {
    //        if (auto found_font = check_font(m_global_fallback_font)) {
    //            return found_font;
    //        }
    //    }

    // **未能找到任何包含该字形的字体**
    // **将输出字形索引设置为 0 (表示未找到)**
    if (out_glyph_index) {
        *out_glyph_index = 0;
    }
    // **返回 nullptr，表示没有找到合适的字体**
    return nullptr;
}

text_layout_t font_manager::layout_text(
    const std::u32string& text,
    const std::shared_ptr<font_face_interface>& in_font,
    float font_size,
    float max_width,
    float line_spacing) {
    text_layout_t layout;

    const auto& primary_font = in_font ? in_font : get_primary_font();
    assert(primary_font && "No valid font available");

    float cursor_y     = 0.0f;
    float total_width  = 0.0f;
    float total_height = 0.0f;
    // 临时存储待处理字形的信息
    struct pending_glyph_t {
        uint32_t                             glyph_index;               // 字形索引
        uint32_t                             prev_glyph_id_for_kerning; // 用于字距调整的上一个字形ID
        float                                start_x;                   // 该字形开始绘制的相对X坐标（应用字距调整前）
        glyph_shaped_t                       metrics;                   // 字形度量信息
        atlas_region_t                       region;                    // 字形在图集中的区域
        bool                                 is_emoji;                  // 是否为表情符号
        std::shared_ptr<font_face_interface> font;                      // 使用的字体
    };

    struct line_info {
        float                        max_ascent      = 0.0f;
        float                        max_descent     = 0.0f; // 正值
        float                        max_line_height = 0.0f;
        float                        current_width   = 0.0f;
        bool                         has_content     = false;
        std::vector<pending_glyph_t> glyphs;
    };

    line_info current_line;
    float     line_cursor_x = 0.0f;
    uint32_t  prev_glyph_id = 0;

    std::map<std::shared_ptr<font_face_interface>, font_v_metrics_t> font_metrics_cache;

    // 设置所有可能用到的字体大小
    for (const auto& font : fonts_ | std::views::values) {
        if (font)
            font->set_font_size(font_size);
    }
    if (primary_font) {
        primary_font->set_font_size(font_size);
    }

    /**
     * @brief 完成当前行的布局并将字形添加到最终布局中
     */
    auto finish_line = [&] {
        // --- 处理空行 ---
        if (!current_line.has_content) {
            if (primary_font) {
                // 需要参考字体确定空行高度
                if (!font_metrics_cache.contains(primary_font)) {
                    font_metrics_cache[primary_font] = primary_font->get_metrics();
                }
                // 如果主字体有效，则增加由主字体确定的行高
                if (font_metrics_cache.contains(primary_font)) {
                    total_height += font_metrics_cache[primary_font].line_height * line_spacing;
                    cursor_y = total_height;
                }
            }
            // 重置行信息 (即使是空行也要重置)
            current_line  = line_info{};
            line_cursor_x = 0.0f;
            prev_glyph_id = 0;
            return; // 空行处理完毕
        }

        // --- 计算行垂直居中的基线 ---
        // **1. 计算该行分配的总高度**
        const float actual_line_height = current_line.max_line_height * line_spacing;
        // **2. 计算该行内容的实际高度**
        const float content_height = current_line.max_ascent + current_line.max_descent;
        // **3. 计算垂直居中对齐的基线 Y 坐标**
        //    目标是将 content_height 放在 actual_line_height 的中间。
        //    行空间的中心点 Y = cursor_y + actual_line_height / 2.0f
        //    内容空间的中心点相对于基线的偏移 = (max_ascent - max_descent) / 2.0f
        //    所以 baseline_y + (max_ascent - max_descent) / 2.0f = cursor_y + actual_line_height / 2.0f
        //    baseline_y = cursor_y + (actual_line_height - max_ascent + max_descent) / 2.0f
        //    (注意：这里假设 ascent 为正, descent 为正)
        const float baseline_y = cursor_y + current_line.max_ascent + (actual_line_height - content_height) / 2.f;

        // --- 处理当前行的所有字形，计算最终位置 ---
        for (const auto& pending_glyph : current_line.glyphs) {
            const auto& metrics = pending_glyph.metrics;
            const auto& region  = pending_glyph.region;

            // 计算Y轴差异 (确保从位图数据的实际顶部开始绘制)
            const float size_y_diff = metrics.rect.size().y() - static_cast<float>(region.rect.size().y());

            // 计算最终字形绘制坐标 (使用新的 baseline_y)
            float final_x = pending_glyph.start_x + metrics.offset.x();
            // **final_y = baseline_y + 字形相对于基线的偏移 + 高度差异**
            float final_y = baseline_y + metrics.offset.y() + size_y_diff;

            // 添加字形位置信息到最终布局
            auto& glyph_position       = layout.glyphs.emplace_back();
            glyph_position.is_emoji    = pending_glyph.is_emoji;
            glyph_position.glyph_index = pending_glyph.glyph_index;
            glyph_position.position    = { final_x, final_y };
            glyph_position.size        = metrics.rect.size();
            glyph_position.region      = region;
        }

        // --- 更新总体尺寸和下一行位置 ---
        total_width = std::max(total_width, current_line.current_width);
        // **总高度增加的是该行分配的高度**
        total_height += actual_line_height;

        // 移到下一行的顶部
        cursor_y      = total_height;
        line_cursor_x = 0.0f;

        // 重置行信息和上一个字形ID
        current_line  = line_info{};
        prev_glyph_id = 0;
    };

    /**
     * @brief 处理单个字符的布局（第一阶段：收集信息和换行判断）
     * (此函数逻辑基本不变，主要负责收集信息给 finish_line 使用)
     */
    auto process_character = [&](const char32_t c) {
        if (c == U'\n') {
            finish_line();
            return;
        }

        const bool  is_emoji    = emoji_detector::is_emoji(c);
        uint32_t    glyph_index = 0;
        const auto& using_font  = get_font_for_code_point(primary_font, c, &glyph_index);

        if (glyph_index == 0) {
            prev_glyph_id = 0;
            return;
        }

        if (!font_metrics_cache.contains(using_font)) {
            // 确保获取度量前字体大小已设置 (已在循环开始前完成)
            font_metrics_cache[using_font] = using_font->get_metrics();
        }
        const auto& current_font_metrics = font_metrics_cache[using_font];

        const auto& glyph_metrics = using_font->shape_glyph(glyph_index);
        const auto& region_opt    = get_or_create_glyph_by_index(glyph_metrics.glyph_index, using_font, font_size,
                                                                 is_emoji);

        if (!region_opt) {
            prev_glyph_id = 0;
            return;
        }
        const auto& region = *region_opt;

        float kerning = 0.0f;
        if (prev_glyph_id != 0) {
            kerning = using_font->get_kerning(prev_glyph_id, glyph_index);
        }

        float estimated_next_x = line_cursor_x + kerning + glyph_metrics.advance.x();

        // 检查自动换行
        if (max_width > 0 &&
            estimated_next_x > max_width &&
            current_line.has_content) {
            finish_line();
            // !! 继续处理当前字符 c 在新行上 !!
            kerning = 0.0f; // 新行首字符无 kerning
            // line_cursor_x 和 prev_glyph_id 已在 finish_line 中重置为 0
        }

        current_line.has_content = true;

        // **更新当前行的最大度量信息** (保持不变)
        current_line.max_ascent = std::max(current_line.max_ascent, current_font_metrics.ascent);
        // **确保 descent 是正值**
        current_line.max_descent     = std::max(current_line.max_descent, std::abs(current_font_metrics.descent));
        current_line.max_line_height = std::max(current_line.max_line_height, current_font_metrics.line_height);

        line_cursor_x += kerning;

        pending_glyph_t pending_glyph;
        pending_glyph.glyph_index               = glyph_index;
        pending_glyph.prev_glyph_id_for_kerning = prev_glyph_id;
        pending_glyph.start_x                   = line_cursor_x;
        pending_glyph.metrics                   = glyph_metrics;
        pending_glyph.region                    = region;
        pending_glyph.is_emoji                  = is_emoji;
        pending_glyph.font                      = using_font;

        current_line.glyphs.push_back(pending_glyph);

        // 更新行宽度
        current_line.current_width = line_cursor_x + glyph_metrics.advance.x();

        // 更新光标 X 位置
        line_cursor_x += glyph_metrics.advance.x();

        // 更新上一个字形索引
        prev_glyph_id = glyph_index;
    };

    // --- 主处理循环 ---
    for (const char32_t c : text) {
        process_character(c);
    }

    // --- 处理文本末尾的最后一行 ---
    finish_line();

    // --- 设置最终布局尺寸 ---
    layout.total_size = { total_width, total_height };

    return layout;
}


/**
 * @brief 获取或创建字形在图集中的区域
 */
std::optional<atlas_region_t> font_manager::get_or_create_glyph_by_index(
    int32_t in_glyph_id,
    const std::shared_ptr<font_face_interface>& in_font,
    float in_font_size,
    bool is_emoji) {
    // 验证字体有效性
    if (!in_font) {
        return std::nullopt;
    }

    return atlas_manager_.get_or_create_glyph(in_glyph_id, in_font, in_font_size, is_emoji);
}

font_manager::font_manager() {
    // 初始化字体系统
    if (!init_font_system()) {
        throw std::runtime_error("无法初始化字体系统");
    }
}
