#!/usr/bin/env nu
# Display graph statistics and health metrics
#
# Usage: nu kogral-stats.nu [--format <table|json|summary>] [--kogral-dir <path>]

def main [
    --format: string = "summary"  # Output format: table, json, or summary
    --kogral-dir: string = ".kogral"      # KOGRAL directory
    --show-tags                   # Show top tags
    --show-orphans                # Show orphaned nodes (no relationships)
] {
    print $"(ansi green_bold)KOGRAL Statistics(ansi reset)"
    print $"KOGRAL Directory: ($kogral_dir)\n"

    # Check if .kogral directory exists
    if not ($kogral_dir | path exists) {
        print $"(ansi red)Error: KOGRAL directory not found: ($kogral_dir)(ansi reset)"
        exit 1
    }

    # Collect statistics
    print $"(ansi cyan)Collecting statistics...(ansi reset)"

    let stats = collect_stats $kogral_dir

    # Display based on format
    match $format {
        "json" => {
            $stats | to json
        },
        "table" => {
            display_table $stats
        },
        "summary" => {
            display_summary $stats $show_tags $show_orphans
        },
        _ => {
            print $"(ansi red)Error: Invalid format. Use: table, json, or summary(ansi reset)"
            exit 1
        }
    }
}

def collect_stats [kogral_dir: string] -> record {
    # Count files by type
    let notes_files = glob $"($kogral_dir)/notes/**/*.md"
    let decisions_files = glob $"($kogral_dir)/decisions/**/*.md"
    let guidelines_files = glob $"($kogral_dir)/guidelines/**/*.md"
    let patterns_files = glob $"($kogral_dir)/patterns/**/*.md"
    let journal_files = glob $"($kogral_dir)/journal/**/*.md"

    let notes_count = $notes_files | length
    let decisions_count = $decisions_files | length
    let guidelines_count = $guidelines_files | length
    let patterns_count = $patterns_files | length
    let journal_count = $journal_files | length

    let total_files = $notes_count + $decisions_count + $guidelines_count + $patterns_count + $journal_count

    # Calculate sizes
    let notes_size = if $notes_count > 0 { ls $notes_files | get size | math sum } else { 0 }
    let decisions_size = if $decisions_count > 0 { ls $decisions_files | get size | math sum } else { 0 }
    let guidelines_size = if $guidelines_count > 0 { ls $guidelines_files | get size | math sum } else { 0 }
    let patterns_size = if $patterns_count > 0 { ls $patterns_files | get size | math sum } else { 0 }
    let journal_size = if $journal_count > 0 { ls $journal_files | get size | math sum } else { 0 }

    let total_size = $notes_size + $decisions_size + $guidelines_size + $patterns_size + $journal_size

    # Collect tags
    let all_files = $notes_files | append $decisions_files | append $guidelines_files | append $patterns_files | append $journal_files
    let tags = collect_tags $all_files

    # Load config
    let config_path = $"($kogral_dir)/config.toml"
    let config = if ($config_path | path exists) {
        open $config_path | from toml
    } else {
        { graph: { name: "unknown", version: "unknown" } }
    }

    # Health metrics
    let health = calculate_health $total_files $tags

    {
        graph: {
            name: $config.graph.name,
            version: $config.graph.version
        },
        counts: {
            notes: $notes_count,
            decisions: $decisions_count,
            guidelines: $guidelines_count,
            patterns: $patterns_count,
            journal: $journal_count,
            total: $total_files
        },
        sizes: {
            notes: $notes_size,
            decisions: $decisions_size,
            guidelines: $guidelines_size,
            patterns: $patterns_size,
            journal: $journal_size,
            total: $total_size
        },
        tags: $tags,
        health: $health
    }
}

def collect_tags [files: list] -> record {
    mut tag_counts = {}

    for file in $files {
        try {
            let content = open $file
            let has_frontmatter = $content | str starts-with "---"

            if $has_frontmatter {
                # Extract tags from frontmatter
                let frontmatter_end = $content | str index-of "---\n" --end 1
                if $frontmatter_end != -1 {
                    let frontmatter = $content | str substring 0..$frontmatter_end

                    # Look for tags line
                    let tags_line = $frontmatter | lines | find -r "^tags:" | first | default ""

                    if ($tags_line | str length) > 0 {
                        # Parse tags array [tag1, tag2, ...]
                        let tags = $tags_line | str replace "tags:" "" | str trim | str replace -a "[" "" | str replace -a "]" "" | str replace -a "\"" "" | split row ","

                        for tag in $tags {
                            let tag_clean = $tag | str trim
                            if ($tag_clean | str length) > 0 {
                                $tag_counts = ($tag_counts | upsert $tag_clean {|old| ($old | default 0) + 1 })
                            }
                        }
                    }
                }
            }
        }
    }

    let total_tags = $tag_counts | values | math sum
    let unique_tags = $tag_counts | columns | length

    let top_tags = $tag_counts | transpose tag count | sort-by count --reverse | first 10

    {
        total: $total_tags,
        unique: $unique_tags,
        top: $top_tags
    }
}

def calculate_health [total_files: int, tags: record] -> record {
    # Health metrics
    let has_content = $total_files > 0
    let has_diversity = $total_files > 10
    let well_tagged = $tags.total > ($total_files * 0.5)

    let score = if $has_content and $has_diversity and $well_tagged {
        "Excellent"
    } else if $has_content and $has_diversity {
        "Good"
    } else if $has_content {
        "Fair"
    } else {
        "Poor"
    }

    {
        score: $score,
        has_content: $has_content,
        has_diversity: $has_diversity,
        well_tagged: $well_tagged
    }
}

def display_summary [stats: record, show_tags: bool, show_orphans: bool] {
    print $"(ansi cyan_bold)═══ Graph Information ═══(ansi reset)"
    print $"Name:    ($stats.graph.name)"
    print $"Version: ($stats.graph.version)"

    print $"\n(ansi cyan_bold)═══ Node Counts ═══(ansi reset)"
    print $"Notes:      ($stats.counts.notes)"
    print $"Decisions:  ($stats.counts.decisions)"
    print $"Guidelines: ($stats.counts.guidelines)"
    print $"Patterns:   ($stats.counts.patterns)"
    print $"Journal:    ($stats.counts.journal)"
    print $"(ansi green_bold)Total:      ($stats.counts.total)(ansi reset)"

    print $"\n(ansi cyan_bold)═══ Storage ═══(ansi reset)"
    print $"Total size: ($stats.sizes.total)"

    print $"\n(ansi cyan_bold)═══ Tags ═══(ansi reset)"
    print $"Total tags:  ($stats.tags.total)"
    print $"Unique tags: ($stats.tags.unique)"

    if $show_tags and ($stats.tags.top | length) > 0 {
        print $"\nTop tags:"
        for tag in $stats.tags.top {
            print $"  ($tag.tag): ($tag.count)"
        }
    }

    print $"\n(ansi cyan_bold)═══ Health Score ═══(ansi reset)"
    let health_color = match $stats.health.score {
        "Excellent" => "green_bold",
        "Good" => "green",
        "Fair" => "yellow",
        "Poor" => "red",
        _ => "white"
    }
    print $"Overall: (ansi $health_color)($stats.health.score)(ansi reset)"
    print $"Has content:   ($stats.health.has_content)"
    print $"Has diversity: ($stats.health.has_diversity)"
    print $"Well tagged:   ($stats.health.well_tagged)"
}

def display_table [stats: record] {
    let table_data = [
        { metric: "Notes", value: $stats.counts.notes },
        { metric: "Decisions", value: $stats.counts.decisions },
        { metric: "Guidelines", value: $stats.counts.guidelines },
        { metric: "Patterns", value: $stats.counts.patterns },
        { metric: "Journal", value: $stats.counts.journal },
        { metric: "Total Files", value: $stats.counts.total },
        { metric: "Total Size", value: $stats.sizes.total },
        { metric: "Unique Tags", value: $stats.tags.unique },
        { metric: "Health", value: $stats.health.score }
    ]

    $table_data
}
