use super::super::super::*;
use super::rows::PayloadEnvelopeRow;
use std::collections::BTreeMap;

pub(crate) fn build_short_profile_flag_pair_summary(
    payload_envelope_rows: &[PayloadEnvelopeRow],
) -> Option<SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary> {
    let short_profile_flag_rows = payload_envelope_rows
        .iter()
        .filter(|row| row.profile_chunk_len_to_next_name_or_end == Some(6))
        .filter_map(|row| {
            Some((
                row.name_tag_relative_offset,
                row.primary_name.clone(),
                row.secondary_name.clone(),
                row.short_profile_first_flag_byte?,
                row.short_profile_second_flag_byte?,
            ))
        })
        .collect::<Vec<_>>();
    let mut short_profile_flag_pair_counts = BTreeMap::<(u8, u8), usize>::new();
    let mut short_profile_first_flag_counts = BTreeMap::<u8, usize>::new();
    let mut short_profile_second_flag_counts = BTreeMap::<u8, usize>::new();
    for (_, _, _, first_flag_byte, second_flag_byte) in &short_profile_flag_rows {
        *short_profile_flag_pair_counts
            .entry((*first_flag_byte, *second_flag_byte))
            .or_default() += 1;
        *short_profile_first_flag_counts
            .entry(*first_flag_byte)
            .or_default() += 1;
        *short_profile_second_flag_counts
            .entry(*second_flag_byte)
            .or_default() += 1;
    }
    let dominant_short_profile_flag_pair = short_profile_flag_pair_counts
        .iter()
        .max_by(|(left_pair, left_count), (right_pair, right_count)| {
            left_count
                .cmp(right_count)
                .then_with(|| right_pair.cmp(left_pair))
        })
        .map(|((first_flag_byte, second_flag_byte), count)| {
            SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPair {
                first_flag_byte: *first_flag_byte,
                first_flag_byte_hex: format!("0x{first_flag_byte:02x}"),
                second_flag_byte: *second_flag_byte,
                second_flag_byte_hex: format!("0x{second_flag_byte:02x}"),
                count: *count,
            }
        });
    let dominant_short_profile_first_flag = short_profile_first_flag_counts
        .iter()
        .max_by(|(left_byte, left_count), (right_byte, right_count)| {
            left_count
                .cmp(right_count)
                .then_with(|| right_byte.cmp(left_byte))
        })
        .map(|(byte, count)| (*byte, *count));
    let dominant_short_profile_second_flag = short_profile_second_flag_counts
        .iter()
        .max_by(|(left_byte, left_count), (right_byte, right_count)| {
            left_count
                .cmp(right_count)
                .then_with(|| right_byte.cmp(left_byte))
        })
        .map(|(byte, count)| (*byte, *count));
    Some(
        SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary {
            row_count_with_0x06_profile_span: short_profile_flag_rows.len(),
            unique_flag_pair_count: short_profile_flag_pair_counts.len(),
            dominant_first_flag_byte: dominant_short_profile_first_flag.map(|(byte, _)| byte),
            dominant_first_flag_byte_hex: dominant_short_profile_first_flag
                .map(|(byte, _)| format!("0x{byte:02x}")),
            dominant_first_flag_byte_count: dominant_short_profile_first_flag
                .map(|(_, count)| count)
                .unwrap_or_default(),
            dominant_second_flag_byte: dominant_short_profile_second_flag.map(|(byte, _)| byte),
            dominant_second_flag_byte_hex: dominant_short_profile_second_flag
                .map(|(byte, _)| format!("0x{byte:02x}")),
            dominant_second_flag_byte_count: dominant_short_profile_second_flag
                .map(|(_, count)| count)
                .unwrap_or_default(),
            dominant_flag_pair: dominant_short_profile_flag_pair,
            sample_rows: short_profile_flag_rows
                .iter()
                .take(8)
                .enumerate()
                .map(
                    |(
                        sample_index,
                        (
                            name_tag_relative_offset,
                            primary_name,
                            secondary_name,
                            first_flag_byte,
                            second_flag_byte,
                        ),
                    )| {
                        SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSample {
                            sample_index,
                            name_tag_relative_offset: *name_tag_relative_offset,
                            primary_name: primary_name.clone(),
                            secondary_name: secondary_name.clone(),
                            first_flag_byte: *first_flag_byte,
                            first_flag_byte_hex: format!("0x{first_flag_byte:02x}"),
                            second_flag_byte: *second_flag_byte,
                            second_flag_byte_hex: format!("0x{second_flag_byte:02x}"),
                        }
                    },
                )
                .collect(),
        },
    )
}
