use regex::Regex;
use serde::Serialize;

#[derive(Debug, Clone, Serialize)]
pub struct SabbathSchoolItem {
    pub label: String,
    pub details: String,
    pub time: String,
}

#[derive(Debug, Clone, Serialize)]
pub struct DivineWorshipItem {
    pub label: String,
    pub item_type: String,
    pub title: Option<String>,
    pub speaker: Option<String>,
    pub details: Option<String>,
}

pub fn strip_html_tags(text: &str) -> String {
    if text.is_empty() {
        return String::new();
    }
    
    let tag_regex = Regex::new(r"<[^>]+>").unwrap();
    let no_tags = tag_regex.replace_all(text, "");
    
    html_escape::decode_html_entities(&no_tags)
        .replace('\u{00A0}', " ")
        .trim()
        .to_string()
}

pub fn parse_sabbath_school(ss_text: &str) -> Vec<SabbathSchoolItem> {
    let sabbath_school_times = [
        "9:15 AM", "9:30 AM", "10:30 AM", "10:35 AM", "10:45 AM"
    ];
    
    let clean_text = strip_html_tags(ss_text);
    if clean_text.trim().is_empty() {
        return Vec::new();
    }
    
    let mut items = Vec::new();
    let lines: Vec<&str> = clean_text.lines().collect();
    let mut i = 0;
    
    while i < lines.len() {
        let line = lines[i].trim();
        if line.is_empty() {
            i += 1;
            continue;
        }
        
        if line.ends_with(':') {
            let label = line.trim_end_matches(':').trim().to_string();
            let mut details_parts = Vec::new();
            
            // Collect all non-empty lines until we hit another label or end of text
            let mut j = i + 1;
            while j < lines.len() {
                let next_line = lines[j].trim();
                if next_line.is_empty() {
                    j += 1;
                    continue;
                }
                if next_line.ends_with(':') {
                    break; // Found next label
                }
                details_parts.push(next_line.to_string());
                j += 1;
            }
            i = j - 1; // Set i to the last line we processed
            
            let details = details_parts.join(" ").trim().to_string();
            
            let time = if items.len() < sabbath_school_times.len() {
                sabbath_school_times[items.len()].to_string()
            } else {
                "Time TBD".to_string()
            };
            
            items.push(SabbathSchoolItem {
                label,
                details,
                time,
            });
        }
        i += 1;
    }
    
    items
}

pub fn parse_divine_worship(dw_text: &str) -> Vec<DivineWorshipItem> {
    let clean_text = strip_html_tags(dw_text);
    if clean_text.trim().is_empty() {
        return Vec::new();
    }
    
    let mut items = Vec::new();
    let lines: Vec<&str> = clean_text.lines().collect();
    let mut i = 0;
    let mut current_label: Option<String> = None;
    let mut detail_lines = Vec::new();
    
    while i < lines.len() {
        let line = lines[i].trim();
        if line.is_empty() {
            i += 1;
            continue;
        }
        
        if line.ends_with(':') {
            if let Some(label) = current_label.take() {
                items.push(process_dw_item(&label, &detail_lines));
            }
            current_label = Some(line.trim_end_matches(':').trim().to_string());
            detail_lines.clear();
        } else {
            detail_lines.push(lines[i].to_string());
        }
        i += 1;
    }
    
    if let Some(label) = current_label {
        items.push(process_dw_item(&label, &detail_lines));
    }
    
    items
}

fn process_dw_item(label: &str, detail_lines: &[String]) -> DivineWorshipItem {
    let normalized_label = label.to_lowercase();
    let details_text = detail_lines.iter()
        .map(|line| line.trim())
        .collect::<Vec<_>>()
        .join("\n");
    
    let mut item = DivineWorshipItem {
        label: label.to_string(),
        item_type: "Default".to_string(),
        title: None,
        speaker: None,
        details: if details_text.is_empty() { None } else { Some(details_text.clone()) },
    };
    
    if normalized_label.contains("sermon") {
        item.item_type = "Sermon".to_string();
        if !detail_lines.is_empty() {
            item.title = Some(detail_lines[0].trim().to_string());
        }
        if detail_lines.len() >= 2 {
            item.speaker = Some(detail_lines[1].trim().to_string());
        }
        if detail_lines.len() > 2 {
            item.details = Some(detail_lines[2..].iter()
                .map(|line| line.trim())
                .collect::<Vec<_>>()
                .join("\n"));
        } else {
            item.details = None;
        }
    } else if normalized_label.contains("scripture reading") {
        item.item_type = "Scripture Reading".to_string();
        if !detail_lines.is_empty() {
            item.title = Some(detail_lines[0].trim().to_string());
        }
        if detail_lines.len() >= 2 {
            item.speaker = Some(detail_lines[1].trim().to_string());
        }
        if detail_lines.len() > 2 {
            item.details = Some(detail_lines[2..].iter()
                .map(|line| line.trim())
                .collect::<Vec<_>>()
                .join("\n"));
        } else {
            item.details = None;
        }
    } else if normalized_label.contains("hymn") || normalized_label.contains("song") {
        item.item_type = "Hymn".to_string();
        item.title = Some(detail_lines.iter()
            .map(|line| line.trim())
            .collect::<Vec<_>>()
            .join(" "));
        item.details = None;
    } else if normalized_label.contains("call to worship") {
        item.item_type = "Call to Worship".to_string();
        item.title = Some(detail_lines.iter()
            .map(|line| line.trim())
            .collect::<Vec<_>>()
            .join(" "));
        item.details = None;
    } else if normalized_label.contains("prayer") {
        item.item_type = "Prayer".to_string();
        if detail_lines.len() == 1 {
            item.speaker = Some(detail_lines[0].trim().to_string());
            item.details = None;
        }
    } else if normalized_label.contains("offering") {
        item.item_type = "Offering".to_string();
        if !detail_lines.is_empty() {
            item.title = Some(detail_lines[0].trim().to_string());
        }
        if detail_lines.len() >= 2 {
            item.speaker = Some(detail_lines[1].trim().to_string());
        }
        if detail_lines.len() > 2 {
            item.details = Some(detail_lines[2..].iter()
                .map(|line| line.trim())
                .collect::<Vec<_>>()
                .join("\n"));
        } else {
            item.details = None;
        }
    } else if normalized_label.contains("children's story") || normalized_label.contains("childrens story") {
        item.item_type = "Childrens Story".to_string();
        if detail_lines.len() == 1 {
            item.speaker = Some(detail_lines[0].trim().to_string());
            item.details = None;
        }
    } else if normalized_label.contains("special music") {
        item.item_type = "Special Music".to_string();
        if detail_lines.len() == 1 {
            let detail = detail_lines[0].trim();
            if detail.to_lowercase() == "tba" {
                item.title = Some("TBA".to_string());
                item.speaker = None;
            } else {
                item.speaker = Some(detail.to_string());
            }
        }
        item.details = None;
    } else if normalized_label.contains("announcements") {
        item.item_type = "Announcement DW".to_string();
        if detail_lines.len() == 1 {
            item.speaker = Some(detail_lines[0].trim().to_string());
            item.details = None;
        }
    }
    
    if item.details.as_ref().map_or(false, |d| d.is_empty()) {
        item.details = None;
    }
    
    item
}