use chrono::Utc;
use regex::Regex;
use sqlx::PgPool;
use std::env;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("📋 Church API - Bulletin Format Standardization Tool");
    println!("===================================================");
    println!("Standardizing bulletin text formatting:");
    println!("• Ensures consistent section spacing (double line breaks between sections)");
    println!("• Removes extra spaces after colons");
    println!("• Standardizes line break patterns");
    println!("• Targets: sabbath_school, divine_worship, scripture_reading, sunset");
    println!();

    // Get database URL
    let database_url = env::var("DATABASE_URL")
        .unwrap_or_else(|_| "postgresql://localhost/church_api".to_string());

    // Connect to database
    println!("📡 Connecting to database...");
    let pool = PgPool::connect(&database_url).await?;
    println!("✅ Connected successfully!");
    println!();

    // Analyze current bulletin formatting
    println!("🔍 Analyzing bulletin formatting patterns...");
    let analysis = analyze_bulletin_formatting(&pool).await?;
    
    println!("📊 Bulletin Formatting Analysis:");
    println!("   • Total bulletins: {}", analysis.total_bulletins);
    println!("   • Bulletins with inconsistent spacing: {}", analysis.inconsistent_spacing);
    println!("   • Bulletins with extra spaces after colons: {}", analysis.extra_spaces_after_colons);
    println!("   • Bulletins needing format standardization: {}", analysis.bulletins_needing_formatting);
    
    if analysis.bulletins_needing_formatting == 0 {
        println!("✅ All bulletin formatting is already standardized! No changes needed.");
        return Ok(());
    }

    println!();
    println!("🚀 Starting bulletin format standardization...");
    println!();

    let start_time = Utc::now();
    
    // Standardize bulletin formatting
    let results = standardize_bulletin_formatting(&pool).await?;

    let duration = Utc::now() - start_time;
    
    println!();
    println!("🎉 Bulletin format standardization completed!");
    println!("📊 Standardization Results:");
    println!("   • Sabbath school sections formatted: {}", results.sabbath_school_formatted);
    println!("   • Divine worship sections formatted: {}", results.divine_worship_formatted);
    println!("   • Scripture readings formatted: {}", results.scripture_reading_formatted);
    println!("   • Sunset sections formatted: {}", results.sunset_formatted);
    println!("   • Total text fields formatted: {}", results.total_fields_formatted());
    println!("   • Bulletins modified: {}", results.bulletins_modified);
    println!("⏱️  Duration: {}ms", duration.num_milliseconds());
    
    // Final verification
    println!();
    println!("🔍 Verifying format consistency...");
    let final_analysis = analyze_bulletin_formatting(&pool).await?;
    
    if final_analysis.bulletins_needing_formatting == 0 {
        println!("✅ Success! All bulletin formatting is now consistent.");
        println!("📋 All bulletins now use standardized section spacing.");
    } else {
        println!("⚠️  Warning: {} bulletins still need formatting", final_analysis.bulletins_needing_formatting);
    }

    pool.close().await;
    Ok(())
}

#[derive(Debug)]
struct FormatAnalysis {
    total_bulletins: i64,
    inconsistent_spacing: i64,
    extra_spaces_after_colons: i64,
    bulletins_needing_formatting: i64,
}

#[derive(Debug, Default)]
struct FormattingResults {
    sabbath_school_formatted: u32,
    divine_worship_formatted: u32,
    scripture_reading_formatted: u32,
    sunset_formatted: u32,
    bulletins_modified: u32,
}

impl FormattingResults {
    fn total_fields_formatted(&self) -> u32 {
        self.sabbath_school_formatted + self.divine_worship_formatted + 
        self.scripture_reading_formatted + self.sunset_formatted
    }
}

/// Standardize bulletin text formatting for consistency
/// - Ensures double line breaks between sections
/// - Removes extra spaces after colons
/// - Normalizes section headers
fn standardize_bulletin_text_format(input: &str) -> String {
    if input.is_empty() {
        return String::new();
    }

    // Step 1: Remove extra spaces after colons (": \n" becomes ":\n")
    let colon_space_regex = Regex::new(r":[ ]+\n").unwrap();
    let cleaned_colons = colon_space_regex.replace_all(input, ":\n");
    
    // Step 2: Define section patterns that should have double spacing before them
    let section_patterns = vec![
        "Lesson Study:",
        "Leadership:",
        "Mission Story:",
        "Closing Hymn:",
        "Call To Worship:",
        "Opening Hymn:",
        "Prayer & Praises:",
        "Prayer Song:",
        "Offering:",
        "Children's Story:",
        "Special Music:",
        "Scripture Reading:",
        "Sermon:",
    ];
    
    let mut result = cleaned_colons.to_string();
    
    // Step 3: Ensure proper spacing before each section (except first ones)
    for pattern in section_patterns {
        // Look for pattern that doesn't have double newline before it
        // Replace single newline + pattern with double newline + pattern
        let single_break_pattern = format!("\n{}", pattern);
        let double_break_replacement = format!("\n\n{}", pattern);
        
        // Only replace if it's not already double-spaced and not at the start
        if result.contains(&single_break_pattern) && !result.contains(&double_break_replacement) {
            result = result.replace(&single_break_pattern, &double_break_replacement);
        }
    }
    
    // Step 4: Clean up excessive newlines (more than 2 consecutive become 2)
    let excessive_newlines_regex = Regex::new(r"\n{3,}").unwrap();
    let normalized_newlines = excessive_newlines_regex.replace_all(&result, "\n\n");
    
    // Step 5: Trim and return
    normalized_newlines.trim().to_string()
}

async fn analyze_bulletin_formatting(pool: &PgPool) -> Result<FormatAnalysis, sqlx::Error> {
    // Count total bulletins
    let total_bulletins = sqlx::query_scalar!(
        "SELECT COUNT(*) FROM bulletins"
    ).fetch_one(pool).await?;

    // Count bulletins with inconsistent spacing (single breaks between sections)
    let inconsistent_spacing = sqlx::query_scalar!(r#"
        SELECT COUNT(*) FROM bulletins 
        WHERE 
            -- Look for section patterns followed by single line break instead of double
            sabbath_school ~ 'Song Service:\n[A-Za-z].*\nLesson Study:' OR
            sabbath_school ~ 'Lesson Study:\n[A-Za-z].*\nLeadership:' OR
            divine_worship ~ 'Announcements:\n[A-Za-z].*\nCall To Worship:' OR
            divine_worship ~ 'Opening Hymn:\n[^:]*\nPrayer & Praises:' OR
            divine_worship ~ 'Prayer Song:\n[^:]*\nOffering:'
    "#).fetch_one(pool).await?;

    // Count bulletins with extra spaces after colons
    let extra_spaces_after_colons = sqlx::query_scalar!(r#"
        SELECT COUNT(*) FROM bulletins 
        WHERE 
            sabbath_school ~ ': \n' OR
            divine_worship ~ ': \n' OR
            scripture_reading ~ ': \n' OR
            sunset ~ ': \n'
    "#).fetch_one(pool).await?;

    // Count bulletins needing any formatting standardization
    let bulletins_needing_formatting = sqlx::query_scalar!(r#"
        SELECT COUNT(*) FROM bulletins 
        WHERE 
            -- Inconsistent spacing patterns
            sabbath_school ~ 'Song Service:\n[A-Za-z].*\nLesson Study:' OR
            sabbath_school ~ 'Lesson Study:\n[A-Za-z].*\nLeadership:' OR
            divine_worship ~ 'Announcements:\n[A-Za-z].*\nCall To Worship:' OR
            divine_worship ~ 'Opening Hymn:\n[^:]*\nPrayer & Praises:' OR
            divine_worship ~ 'Prayer Song:\n[^:]*\nOffering:' OR
            -- Extra spaces after colons
            sabbath_school ~ ': \n' OR
            divine_worship ~ ': \n' OR
            scripture_reading ~ ': \n' OR
            sunset ~ ': \n'
    "#).fetch_one(pool).await?;

    Ok(FormatAnalysis {
        total_bulletins: total_bulletins.unwrap_or(0),
        inconsistent_spacing: inconsistent_spacing.unwrap_or(0),
        extra_spaces_after_colons: extra_spaces_after_colons.unwrap_or(0),
        bulletins_needing_formatting: bulletins_needing_formatting.unwrap_or(0),
    })
}

async fn standardize_bulletin_formatting(pool: &PgPool) -> Result<FormattingResults, sqlx::Error> {
    println!("🧹 Processing bulletin formatting...");
    
    // Get all bulletins that need formatting
    let rows = sqlx::query!(r#"
        SELECT id, sabbath_school, divine_worship, scripture_reading, sunset 
        FROM bulletins 
        WHERE 
            -- Inconsistent spacing patterns
            sabbath_school ~ 'Song Service:\n[A-Za-z].*\nLesson Study:' OR
            sabbath_school ~ 'Lesson Study:\n[A-Za-z].*\nLeadership:' OR
            divine_worship ~ 'Announcements:\n[A-Za-z].*\nCall To Worship:' OR
            divine_worship ~ 'Opening Hymn:\n[^:]*\nPrayer & Praises:' OR
            divine_worship ~ 'Prayer Song:\n[^:]*\nOffering:' OR
            -- Extra spaces after colons
            sabbath_school ~ ': \n' OR
            divine_worship ~ ': \n' OR
            scripture_reading ~ ': \n' OR
            sunset ~ ': \n'
    "#)
    .fetch_all(pool)
    .await?;

    let mut results = FormattingResults::default();
    
    println!("   📝 Found {} bulletins needing format standardization", rows.len());
    
    for (index, row) in rows.iter().enumerate() {
        let mut fields_formatted_in_bulletin = 0;

        // Process sabbath_school
        let mut formatted_sabbath_school = None;
        if let Some(ref original_sabbath) = row.sabbath_school {
            let formatted = standardize_bulletin_text_format(original_sabbath);
            if formatted != *original_sabbath {
                formatted_sabbath_school = Some(formatted);
                results.sabbath_school_formatted += 1;
                fields_formatted_in_bulletin += 1;
            }
        }

        // Process divine_worship
        let mut formatted_divine_worship = None;
        if let Some(ref original_worship) = row.divine_worship {
            let formatted = standardize_bulletin_text_format(original_worship);
            if formatted != *original_worship {
                formatted_divine_worship = Some(formatted);
                results.divine_worship_formatted += 1;
                fields_formatted_in_bulletin += 1;
            }
        }

        // Process scripture_reading
        let mut formatted_scripture_reading = None;
        if let Some(ref original_scripture) = row.scripture_reading {
            let formatted = standardize_bulletin_text_format(original_scripture);
            if formatted != *original_scripture {
                formatted_scripture_reading = Some(formatted);
                results.scripture_reading_formatted += 1;
                fields_formatted_in_bulletin += 1;
            }
        }

        // Process sunset
        let mut formatted_sunset = None;
        if let Some(ref original_sunset) = row.sunset {
            let formatted = standardize_bulletin_text_format(original_sunset);
            if formatted != *original_sunset {
                formatted_sunset = Some(formatted);
                results.sunset_formatted += 1;
                fields_formatted_in_bulletin += 1;
            }
        }

        // Update the bulletin if any fields were formatted
        if fields_formatted_in_bulletin > 0 {
            sqlx::query!(r#"
                UPDATE bulletins 
                SET 
                    sabbath_school = COALESCE($2, sabbath_school),
                    divine_worship = COALESCE($3, divine_worship),
                    scripture_reading = COALESCE($4, scripture_reading),
                    sunset = COALESCE($5, sunset),
                    updated_at = NOW()
                WHERE id = $1
            "#, 
                row.id,
                formatted_sabbath_school.as_ref().or(row.sabbath_school.as_ref()),
                formatted_divine_worship.as_ref().or(row.divine_worship.as_ref()),
                formatted_scripture_reading.as_ref().or(row.scripture_reading.as_ref()),
                formatted_sunset.as_ref().or(row.sunset.as_ref())
            )
            .execute(pool)
            .await?;
            
            results.bulletins_modified += 1;
            
            println!("   📄 Bulletin {} ({}/{}): {} fields formatted",
                index + 1,
                index + 1,
                rows.len(),
                fields_formatted_in_bulletin
            );
        }
    }
    
    Ok(results)
}