#!/usr/bin/env nu

# Blog Post Creator / Editor
#
# Orchestrates the typedialog-web nickel-roundtrip workflow for creating
# or editing post metadata (.ncl files).
#
# Modes:
#   new   — load form defaults → typedialog-web → write to target .ncl
#   edit  -- load existing .ncl → typedialog-web → overwrite in place
#   agent — write prescribed values directly to .ncl (no browser, no TUI)
#
# Usage:
#   nu new-post.nu --type blog --lang en --category devops --slug my-post
#   nu new-post.nu --edit site/content/blog/en/devops/my-post.ncl
#   nu new-post.nu --type blog --lang en --slug my-post --agent values.json

def main [
    --type:     string = "blog"   # Content type
    --lang:     string = "en"     # Language directory
    --category: string = ""       # Category slug (matches parent dir)
    --slug:     string = ""       # Post slug (becomes filename stem)
    --edit:     string = ""       # Path to existing .ncl to edit (skips new)
    --agent:    string = ""       # JSON file with prescribed field values (agent mode)
    --form:     string = ""       # Override form template path
    --content-dir: string = ""    # Override SITE_CONTENT_PATH
    --dry-run                     # Print resolved paths without opening typedialog
    --verbose
] {
    let content_root = resolve_env "SITE_CONTENT_PATH" $content_dir "site/content"
    let form_base    = if $form != "" { $form } else {
        $"rustelo/forms/content/($type)/post.ncl"
    }

    if not ($form_base | path exists) {
        error make { msg: $"Form template not found: ($form_base)" }
    }

    # Determine mode
    let mode = if $edit != "" { "edit" } else if $agent != "" { "agent" } else { "new" }

    # Resolve working .ncl path
    let ncl_path = if $mode == "edit" {
        $edit
    } else {
        if $slug == "" { error make { msg: "--slug is required for new posts" } }
        if $category != "" {
            $"($content_root)/($type)/($lang)/($category)/($slug).ncl"
        } else {
            $"($content_root)/($type)/($lang)/($slug).ncl"
        }
    }

    if $verbose or $dry_run {
        print $"  mode     : ($mode)"
        print $"  form     : ($form_base)"
        print $"  output   : ($ncl_path)"
    }
    if $dry_run { return }

    # Prepare working copy for typedialog
    let work_ncl = if $mode == "edit" {
        $ncl_path
    } else {
        # Copy form template to a temp file — typedialog edits it in place
        let tmp = $"/tmp/new-post-(random chars).ncl"
        cp ($form_base | path expand) $tmp
        $tmp
    }

    match $mode {
        "new" | "edit" => {
            print $"(ansi cyan)Opening typedialog form(ansi reset) — ($work_ncl)"
            let result = do {
                typedialog-web nickel-roundtrip ($work_ncl | path expand)
            } | complete

            if $result.exit_code != 0 {
                error make { msg: $"typedialog failed: ($result.stderr)" }
            }

            if $mode == "new" {
                mkdir ($ncl_path | path dirname)
                cp $work_ncl $ncl_path
                rm $work_ncl
                print $"(ansi green)Created(ansi reset) → ($ncl_path)"
            } else {
                print $"(ansi green)Updated(ansi reset) → ($ncl_path)"
            }
        }

        "agent" => {
            # Agent mode: merge prescribed JSON values into the form template
            if not ($agent | path exists) {
                error make { msg: $"Agent values file not found: ($agent)" }
            }
            let values = open $agent
            let base   = open ($form_base | path expand)

            # Render filled .ncl by patching fields in the base form
            mut ncl_lines = $base | lines
            for entry in ($values | items { |k, v| { key: $k, val: $v } }) {
                let pat = $"  ($entry.key) ="
                let replacement = $"  ($entry.key) = ($entry.val | to nuon),"
                $ncl_lines = $ncl_lines | each { |l|
                    if ($l | str starts-with $pat) { $replacement } else { $l }
                }
            }
            mkdir ($ncl_path | path dirname)
            $ncl_lines | str join "\n" | save --force $ncl_path
            print $"(ansi green)Agent wrote(ansi reset) → ($ncl_path)"
        }

        _ => { error make { msg: $"Unknown mode: ($mode)" } }
    }

    # Validate the result
    print "  validating .ncl..."
    let validate = do { nickel-export ($ncl_path | path expand) } | complete
    if $validate.exit_code != 0 {
        print $"(ansi yellow)WARNING(ansi reset) .ncl validation failed — check fields before publishing"
        print $validate.stderr
    } else {
        print $"  (ansi green)✓(ansi reset) valid"
    }
}

def resolve_env [var_name: string, cli_arg: string, fallback: string] {
    if $cli_arg != "" { return $cli_arg }
    try { $env | get $var_name } catch { $fallback }
}
