use crate::error::Result;
use crate::font::FontRegistry;
use crate::normalize::NormalizedList;
use crate::text::TextMeasurer;
use super::{ListItemMarker, MeasuredList};

pub(super) fn measure_list_block(
    list: &NormalizedList,
    available_width: f32,
    measurer: &mut TextMeasurer,
    fonts: &FontRegistry,
) -> Result<MeasuredList> {
    let item_count = list.items.len();
    let font_size = list.style.font_size;
    let font_family = list.style.font_family.as_deref();

    // 构建完整标记文本（计数器 + separator）
    let make_marker = |counter: usize| -> String {
        if list.marker_type == "none" {
            String::new()
        } else {
            let counter_text = format_list_counter(counter, &list.marker_type);
            format!("{}{} ", counter_text, list.separator)
        }
    };

    // 计算 counter 值序列（考虑 reversed）
    // 当 reversed 且未显式设置 start 时（list.start == 1），以 item_count 为起始值
    let counter_values: Vec<usize> = if list.reversed {
        let effective_start = if list.start == 1 { item_count } else { list.start };
        (0..item_count).map(|i| effective_start.saturating_sub(i).max(1)).collect()
    } else {
        (0..item_count).map(|i| i + list.start).collect()
    };

    let (gap_size, max_text_width) = if list.ordered {
        if list.marker_type == "none" {
            (0.0, 0.0)
        } else {
            let mut max_text_w = 0.0f32;
            let mut max_full_w = 0.0f32;
            for &counter in &counter_values {
                let counter_text = format_list_counter(counter, &list.marker_type);
                let full = make_marker(counter);
                let tw = measurer.measure_with_font(&counter_text, font_family, font_size, fonts)?;
                let fw = measurer.measure_with_font(&full, font_family, font_size, fonts)?;
                if tw > max_text_w { max_text_w = tw; }
                if fw > max_full_w { max_full_w = fw; }
            }
            (max_full_w + 4.0, max_text_w)
        }
    } else {
        if list.marker_type == "none" {
            (0.0, 0.0)
        } else {
            (font_size * 0.6 + 8.0, 0.0)
        }
    };

    let content_width = (available_width - gap_size).max(0.0);

    let mut measured_items = Vec::new();
    let mut item_markers = Vec::new();
    let mut total_height = 0.0f32;

    for (i, item_blocks) in list.items.iter().enumerate() {
        let mut measured_blocks = Vec::new();
        let mut item_height = 0.0f32;

        for block in item_blocks {
            let measured = super::measure_one_block(block, measurer, fonts, content_width)?;
            let block_height = super::measured_block_height(&measured);
            item_height += block_height;
            measured_blocks.push(measured);
        }

        let marker = if list.ordered {
            if list.marker_type == "none" {
                ListItemMarker::Bullet { width: 0.0, height: item_height }
            } else {
                let counter = counter_values[i];
                let text = format_list_counter(counter, &list.marker_type);
                let full = make_marker(counter);
                let tw = measurer.measure_with_font(&text, font_family, font_size, fonts)?;
                let fw = measurer.measure_with_font(&full, font_family, font_size, fonts)?;
                ListItemMarker::Number { text: full, text_width: tw, width: fw, height: item_height }
            }
        } else {
            ListItemMarker::Bullet { width: gap_size, height: item_height }
        };

        item_markers.push(marker);
        total_height += item_height;
        measured_items.push(measured_blocks);
    }

    Ok(MeasuredList {
        items: measured_items,
        ordered: list.ordered,
        marker_type: list.marker_type.clone(),
        gap_size,
        max_text_width,
        width: available_width,
        height: total_height,
        item_markers,
        font_size: list.style.font_size,
        font_family: list.style.font_family.clone(),
        marker_color: list.color.clone(),
        origin_node_idx: list.origin_node_idx,
    })
}

fn format_list_counter(counter: usize, marker_type: &str) -> String {
    match marker_type {
        "lower-alpha" | "lower-latin" => {
            let c = ((counter - 1) % 26) as u8 + b'a';
            format!("{}", c as char)
        }
        "upper-alpha" | "upper-latin" => {
            let c = ((counter - 1) % 26) as u8 + b'A';
            format!("{}", c as char)
        }
        "lower-roman" => {
            format!("{}", to_roman(counter).to_lowercase())
        }
        "upper-roman" => {
            format!("{}", to_roman(counter))
        }
        _ => {
            format!("{}", counter)
        }
    }
}

fn to_roman(mut n: usize) -> String {
    let pairs = [
        (1000, "M"), (900, "CM"), (500, "D"), (400, "CD"),
        (100, "C"), (90, "XC"), (50, "L"), (40, "XL"),
        (10, "X"), (9, "IX"), (5, "V"), (4, "IV"),
        (1, "I"),
    ];
    let mut result = String::new();
    for &(value, symbol) in &pairs {
        while n >= value {
            result.push_str(symbol);
            n -= value;
        }
    }
    result
}
