# Git commit message generator
# Generates a commit message file based on current changes without creating a commit

# Generate commit message file based on staged and unstaged changes
export def "generate-commit-message" [
    --file (-f): string = "COMMIT_MSG.txt"  # Output file for commit message
    --staged (-s): bool = false              # Only consider staged changes
    --unstaged (-u): bool = false            # Only consider unstaged changes
] {
    # Determine what changes to analyze
    let analyze_staged = if $staged or (not $unstaged) { true } else { false }
    let analyze_unstaged = if $unstaged or (not $staged) { true } else { false }

    # Get git status
    let git_status = (git status --porcelain | lines | where { $in | str length > 0 })

    if ($git_status | is-empty) {
        print "No changes to commit"
        return
    }

    # Analyze changes
    mut changes = []
    mut files_modified = []
    mut files_added = []
    mut files_deleted = []

    for line in $git_status {
        let status_code = ($line | str substring 0..2)
        let file_path = ($line | str substring 3..)

        # Parse git status codes
        match $status_code {
            " M" => { if $analyze_unstaged { $files_modified = ($files_modified | append $file_path) } }
            "M " => { if $analyze_staged { $files_modified = ($files_modified | append $file_path) } }
            "MM" => { $files_modified = ($files_modified | append $file_path) }
            "A " => { if $analyze_staged { $files_added = ($files_added | append $file_path) } }
            "??" => { if $analyze_unstaged { $files_added = ($files_added | append $file_path) } }
            " D" => { if $analyze_unstaged { $files_deleted = ($files_deleted | append $file_path) } }
            "D " => { if $analyze_staged { $files_deleted = ($files_deleted | append $file_path) } }
            _ => {}
        }
    }

    # Get recent commit messages for style reference
    let log_result = (do { git log --oneline -5 | lines } | complete)
    let recent_commits = if $log_result.exit_code != 0 {
        []
    } else {
        $log_result.stdout | lines
    }

    # Analyze file types and changes
    let config_files = ($files_modified | where { $in | str ends-with ".toml" or $in | str ends-with ".nu" or $in | str ends-with ".yaml" })
    let core_files = ($files_modified | where { $in | str contains "core/" })
    let provider_files = ($files_modified | where { $in | str contains "provider" })

    # Generate commit message based on changes
    mut commit_type = "chore"
    mut commit_scope = ""
    mut commit_description = ""

    # Determine commit type and scope
    if (not ($files_added | is-empty)) {
        $commit_type = "feat"
        $commit_description = "add new functionality"
    } else if (not ($files_deleted | is-empty)) {
        $commit_type = "refactor"
        $commit_description = "remove unused components"
    } else if (not ($config_files | is-empty)) {
        $commit_type = "config"
        $commit_scope = "system"
        $commit_description = "update configuration settings"
    } else if (not ($core_files | is-empty)) {
        $commit_type = "refactor"
        $commit_scope = "core"
        $commit_description = "improve core functionality"
    } else if (not ($provider_files | is-empty)) {
        $commit_type = "feat"
        $commit_scope = "providers"
        $commit_description = "enhance provider capabilities"
    } else {
        $commit_type = "chore"
        $commit_description = "update project files"
    }

    # Build commit message
    mut commit_message = if ($commit_scope | is-empty) {
        $"($commit_type): ($commit_description)"
    } else {
        $"($commit_type)\(($commit_scope)\): ($commit_description)"
    }

    # Add details section
    mut details = []

    if (not ($files_added | is-empty)) {
        $details = ($details | append $"- Add: ($files_added | str join ', ')")
    }

    if (not ($files_modified | is-empty)) {
        $details = ($details | append $"- Update: ($files_modified | str join ', ')")
    }

    if (not ($files_deleted | is-empty)) {
        $details = ($details | append $"- Remove: ($files_deleted | str join ', ')")
    }

    # Create full commit message
    let full_message = if ($details | is-empty) {
        $commit_message
    } else {
        $"($commit_message)\n\n($details | str join '\n')"
    }

    # Write to file
    $full_message | save $file

    print $"Commit message generated and saved to: ($file)"
    print "\nGenerated message:"
    print "=================="
    print $full_message
}

# Show current git changes that would be included in commit message
export def "show-commit-changes" [] {
    let status_output = (git status --porcelain | lines | where { $in | str length > 0 })

    $status_output | each { |line|
        let status_code = ($line | str substring 0..2)
        let file_path = ($line | str substring 3..)

        let change_type = match $status_code {
            " M" => "Modified (unstaged)"
            "M " => "Modified (staged)"
            "MM" => "Modified (both)"
            "A " => "Added (staged)"
            "??" => "Untracked"
            " D" => "Deleted (unstaged)"
            "D " => "Deleted (staged)"
            _ => $status_code
        }

        {
            file: $file_path,
            status: $change_type,
            code: $status_code
        }
    }
}
