#!/bin/bash

# convert-diff - Batch diff converter for markdown files
# Compares pairs of files and outputs HTML diffs using the same template as convert script

# ===== Configuration and variables =====
CUSTOM_TEMPLATE=""
NO_TOC=false

# Function to show help
show_help() {
    echo "Batch Markdown Diff Converter"
    echo "Compares pairs of markdown files and outputs HTML diffs using the same template as convert script"
    echo "Usage: $0 [-f] [-o outputdir] [-T template] [--no-toc] file1_rev_a.md file1_rev_b.md [file2_rev_a.md file2_rev_b.md ...]"
    echo "  -f: Force overwrite existing output files"
    echo "  -o: Output directory (default: same as first input file)"
    echo "  -T: Template file path (default: templates/report.html)"
    echo "  --no-toc: Skip table of contents generation"
    echo ""
    echo "Arguments:"
    echo "  Files must be provided in pairs (revision A, revision B)"
    echo "  Total number of files must be even"
    echo "  Output files will be named: basename_diff.html"
}

# Function to source ZDDC config files if they exist
source_config_file() {
    local config_file="$1"
    if [ -f "$config_file" ]; then
        echo "  → Loading ZDDC configuration from: $config_file"
        set -a  # automatically export all variables
        . "$config_file"
        set +a  # turn off automatic export
        return 0
    fi
    return 1
}

# Load ZDDC configuration file
load_zddc_config() {
    local search_dir="$1"
    
    # Search for zddc.conf then .zddc.conf in the search directory
    if source_config_file "$search_dir/zddc.conf"; then
        return 0
    elif source_config_file "$search_dir/.zddc.conf"; then
        return 0
    fi
    
    # No config file found - continue with defaults
    return 1
}

# Function to inject diff controls and styling into HTML
inject_diff_controls() {
    local html_file="$1"
    
    if [ ! -f "$html_file" ]; then
        echo "Error: HTML file not found: $html_file"
        return 1
    fi
    
    # Create temporary files for each component
    local temp_dir=$(mktemp -d)
    local css_file="$temp_dir/diff.css"
    local controls_file="$temp_dir/controls.html"
    local js_file="$temp_dir/diff.js"
    
    # Write CSS to file
    cat > "$css_file" << 'EOF'
/* Diff element styling */
del {
  background-color: #f8d7da;
  color: #721c24;
  text-decoration: line-through;
  padding: 0.1em 0.2em;
  border-radius: 0.2em;
}

u {
  background-color: #d4edda;
  color: #155724;
  text-decoration: none;
  padding: 0.1em 0.2em;
  border-radius: 0.2em;
}

/* Dark mode diff styling */
@media (prefers-color-scheme: dark) {
  u {
    background-color: #1e4620;
    color: #75dd79;
  }
  
  del {
    background-color: #4a1e1e;
    color: #f97583;
  }
}

/* View mode controls */
.diff-controls {
  position: fixed;
  top: 20px;
  right: 20px;
  background: var(--bg-secondary, #ffffff);
  border: 1px solid var(--border-color, #e1e5e9);
  border-radius: 8px;
  padding: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  font-size: 0.875rem;
}

.diff-controls h4 {
  margin: 0 0 8px 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary, #333);
}

.view-mode-buttons {
  display: flex;
  gap: 4px;
}

.view-mode-btn {
  padding: 6px 12px;
  border: 1px solid var(--border-color, #e1e5e9);
  background: var(--bg-primary, #ffffff);
  color: var(--text-color, #333);
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.75rem;
  transition: all 0.2s;
}

.view-mode-btn:hover {
  background: var(--hover-bg, #f8f9fa);
}

.view-mode-btn.active {
  background: var(--primary-color, #007bff);
  color: white;
  border-color: var(--primary-color, #007bff);
}

/* View mode states */
body.view-original u {
  display: none;
}

body.view-original del {
  text-decoration: none;
}

body.view-final del {
  display: none;
}
EOF

    # Write controls HTML to file
    cat > "$controls_file" << 'EOF'
        <!-- Diff View Controls -->
        <div class="diff-controls">
          <h4>View Mode</h4>
          <div class="view-mode-buttons">
            <button class="view-mode-btn active" data-mode="diff">Diff</button>
            <button class="view-mode-btn" data-mode="original">Original</button>
            <button class="view-mode-btn" data-mode="final">Final</button>
          </div>
        </div>
EOF

    # Write JavaScript to file
    cat > "$js_file" << 'EOF'
<script>
    // View mode toggle functionality
    document.addEventListener("DOMContentLoaded", function() {
      var buttons = document.querySelectorAll(".view-mode-btn");
      var body = document.body;
      
      buttons.forEach(function(button) {
        button.addEventListener("click", function() {
          // Remove active class from all buttons
          buttons.forEach(function(btn) { btn.classList.remove("active"); });
          
          // Add active class to clicked button
          this.classList.add("active");
          
          // Update body class for view mode
          body.className = body.className.replace(/view-\w+/g, "");
          if (this.dataset.mode !== "diff") {
            body.classList.add("view-" + this.dataset.mode);
          }
        });
      });
    });
</script>
EOF
    
    # Create working copy
    local temp_html="$temp_dir/temp.html"
    cp "$html_file" "$temp_html"
    
    # Insert CSS before </head>
    sed -i '/<\/head>/r '"$css_file" "$temp_html"
    
    # Insert controls after opening <body> tag
    sed -i '/<body[^>]*>/r '"$controls_file" "$temp_html"
    
    # Insert JavaScript before </body>
    sed -i '/<\/body>/r '"$js_file" "$temp_html"
    
    # Replace original file
    mv "$temp_html" "$html_file"
    
    # Cleanup
    rm -rf "$temp_dir"
    
    echo "  ✓ Diff controls injected successfully"
}

# Source global ZDDC config from current working directory
load_zddc_config "$(pwd)"

# Resolve script directory for template discovery
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
# Resolve symlink if needed
if [ -L "$0" ]; then
    SCRIPT_TARGET=$(readlink -f "$0")
    SCRIPT_TARGET_DIR=$(dirname "$SCRIPT_TARGET")
else
    SCRIPT_TARGET_DIR="$SCRIPT_DIR"
fi

# Parse arguments
FORCE_OVERWRITE=false
OUTPUT_DIR=""

while [ $# -gt 0 ]; do
    case $1 in
        -h|--help)
            show_help
            exit 0
            ;;
        -f)
            FORCE_OVERWRITE=true
            echo "Force overwrite mode: ON"
            shift
            ;;
        -o)
            OUTPUT_DIR="$2"
            echo "Output directory: $OUTPUT_DIR"
            shift 2
            ;;
        -T)
            CUSTOM_TEMPLATE="$2"
            echo "Custom template: $CUSTOM_TEMPLATE"
            shift 2
            ;;
        --no-toc)
            NO_TOC=true
            echo "Table of contents: DISABLED"
            shift
            ;;
        -*)
            echo "Unknown option: $1"
            show_help
            exit 1
            ;;
        *)
            break
            ;;
    esac
done

if [ "$FORCE_OVERWRITE" = "false" ]; then
    echo "Force overwrite mode: OFF (will skip existing output files)"
fi

if [ -z "$OUTPUT_DIR" ]; then
    echo "Output directory: same as input files"
fi

# Validate file count
if [ $# -eq 0 ]; then
    echo "Error: No input files specified"
    show_help
    exit 1
fi

if [ $(($# % 2)) -ne 0 ]; then
    echo "Error: Number of files must be even (pairs of files for comparison)"
    echo "Provided $# files, but need pairs"
    show_help
    exit 1
fi

TOTAL_PAIRS=$(($# / 2))
echo "Processing $TOTAL_PAIRS file pairs..."

SUCCESSFUL=0
FAILED=0
SKIPPED=0

# Process files in pairs
while [ $# -gt 0 ]; do
    FILE1="$1"
    FILE2="$2"
    shift 2
    
    echo ""
    echo "Processing pair: $(basename "$FILE1") vs $(basename "$FILE2")"
    
    # Validate input files exist
    if [ ! -f "$FILE1" ]; then
        echo "  ✗ First file not found: $FILE1"
        FAILED=$((FAILED + 1))
        continue
    fi
    
    if [ ! -f "$FILE2" ]; then
        echo "  ✗ Second file not found: $FILE2"
        FAILED=$((FAILED + 1))
        continue
    fi
    
    # Extract base filename for output
    BASENAME1=$(basename "$FILE1" .md)
    BASENAME2=$(basename "$FILE2" .md)
    
    # Generate output filename with _diff suffix (ZDDC compliant)
    OUTPUT_BASENAME="${BASENAME1}_diff.html"
    
    if [ -n "$OUTPUT_DIR" ]; then
        OUTPUT_FILE="$OUTPUT_DIR/${OUTPUT_BASENAME}"
    else
        FILE1_DIR=$(dirname "$FILE1")
        OUTPUT_FILE="$FILE1_DIR/${OUTPUT_BASENAME}"
    fi
    
    echo "  → Output file: $OUTPUT_FILE"
    
    # Check if output file already exists and skip if not forcing overwrite
    if [ -f "$OUTPUT_FILE" ] && [ "$FORCE_OVERWRITE" = "false" ]; then
        echo "  → Output file already exists, skipping (use -f to overwrite)"
        SKIPPED=$((SKIPPED + 1))
        continue
    fi
    
    # Load ZDDC configuration from first file's directory
    # (load_zddc_config logs the path itself, but only when a config is found)
    FILE1_DIR=$(dirname "$FILE1")
    load_zddc_config "$FILE1_DIR"

    # Determine template to use. Diffs render with the report template (its
    # _head/_doc/_scripts partials live alongside it in templates/, so pandoc
    # resolves them from the template's own directory).
    TEMPLATE_ABS=""
    if [ -n "$CUSTOM_TEMPLATE" ]; then
        if [ -f "$CUSTOM_TEMPLATE" ]; then
            TEMPLATE_ABS="$CUSTOM_TEMPLATE"
            echo "  → Using custom template: $TEMPLATE_ABS"
        else
            echo "  → Custom template not found: $CUSTOM_TEMPLATE; falling back to default"
        fi
    fi
    if [ -z "$TEMPLATE_ABS" ]; then
        for _tdir in "$SCRIPT_DIR/templates" "$SCRIPT_TARGET_DIR/templates"; do
            if [ -f "$_tdir/report.html" ]; then
                TEMPLATE_ABS="$_tdir/report.html"
                break
            fi
        done
    fi
    
    # Create temp file for pandiff output
    TEMP_DIFF=$(mktemp)
    
    # Create temp files for metadata extraction (unique per invocation)
    TEMP_METADATA_REV1=$(mktemp)
    TEMP_METADATA_REV2=$(mktemp)
    
    echo "Stage 1: Generating diff with pandiff..."
    
    # Run pandiff to generate HTML diff
    if ! pandiff --to html "$FILE1" "$FILE2" > "$TEMP_DIFF"; then
        echo "  ✗ Failed to generate diff"
        rm -f "$TEMP_DIFF" "$TEMP_METADATA_REV1" "$TEMP_METADATA_REV2"
        FAILED=$((FAILED + 1))
        continue
    fi
    
    echo "  ✓ Diff generated successfully"
    echo "Stage 2: Adding TOC and styling with pandoc..."

    # Extract metadata from both files (safe - no eval, uses heredoc)
    {
        # Extract YAML frontmatter and parse fields safely
        awk '/^---$/{if(NR==1){p=1}else{p=0}} p && !/^---$/{print}' "$FILE1" > "$TEMP_METADATA_REV1"
        rev1_tracking_number=$(grep '^tracking_number:' "$TEMP_METADATA_REV1" | sed 's/^tracking_number: *"\(.*\)"$/\1/' | head -1)
        rev1_title=$(grep '^title:' "$TEMP_METADATA_REV1" | sed 's/^title: *"\(.*\)"$/\1/' | head -1)
        rev1_revision=$(grep '^revision:' "$TEMP_METADATA_REV1" | sed 's/^revision: *"\(.*\)"$/\1/' | head -1)
        rev1_status=$(grep '^status:' "$TEMP_METADATA_REV1" | sed 's/^status: *"\(.*\)"$/\1/' | head -1)
        rev1_project=$(grep '^project:' "$TEMP_METADATA_REV1" | sed 's/^project: *"\(.*\)"$/\1/' | head -1)
    }
    {
        awk '/^---$/{if(NR==1){p=1}else{p=0}} p && !/^---$/{print}' "$FILE2" > "$TEMP_METADATA_REV2"
        rev2_tracking_number=$(grep '^tracking_number:' "$TEMP_METADATA_REV2" | sed 's/^tracking_number: *"\(.*\)"$/\1/' | head -1)
        rev2_title=$(grep '^title:' "$TEMP_METADATA_REV2" | sed 's/^title: *"\(.*\)"$/\1/' | head -1)
        rev2_revision=$(grep '^revision:' "$TEMP_METADATA_REV2" | sed 's/^revision: *"\(.*\)"$/\1/' | head -1)
        rev2_status=$(grep '^status:' "$TEMP_METADATA_REV2" | sed 's/^status: *"\(.*\)"$/\1/' | head -1)
        rev2_project=$(grep '^project:' "$TEMP_METADATA_REV2" | sed 's/^project: *"\(.*\)"$/\1/' | head -1)
    }
    
    # Clean up metadata temp files
    rm -f "$TEMP_METADATA_REV1" "$TEMP_METADATA_REV2"
    
    # Generate diff-aware header HTML with view mode classes
    generate_diff_header() {
        local header_html=""
        
        # Project title (should be same for both). Append the project number from
        # zddc.conf when set, e.g. "Project Name (AR 28088)"; omit the parens otherwise.
        header_html="<div class=\"header-line client-project\">${rev2_project}${project_number:+ ($project_number)}</div>"
        
        # Document title with diff
        if [ "$rev1_title" != "$rev2_title" ]; then
            header_html="$header_html<div class=\"header-line document-title\"><del>$rev1_title</del><ins>$rev2_title</ins></div>"
        else
            header_html="$header_html<div class=\"header-line document-title\">$rev2_title</div>"
        fi
        
        # Tracking number and revision with diff
        local tracking_rev_line=""
        if [ "$rev1_tracking_number" != "$rev2_tracking_number" ]; then
            tracking_rev_line="<del>$rev1_tracking_number</del><ins>$rev2_tracking_number</ins>"
        else
            tracking_rev_line="$rev1_tracking_number"
        fi
        
        if [ "$rev1_revision" != "$rev2_revision" ]; then
            tracking_rev_line="$tracking_rev_line Revision: <del>$rev1_revision</del><ins>$rev2_revision</ins>"
        else
            tracking_rev_line="$tracking_rev_line Revision: $rev1_revision"
        fi
        
        if [ "$rev1_status" != "$rev2_status" ]; then
            tracking_rev_line="$tracking_rev_line Status: <del>$rev1_status</del><ins>$rev2_status</ins>"
        else
            tracking_rev_line="$tracking_rev_line Status: $rev1_status"
        fi
        
        header_html="$header_html<div class=\"header-line\">$tracking_rev_line</div>"
        
        # Add draft marker if revision contains ~
        if echo "$rev2_revision" | grep -q "~"; then
            header_html="$header_html<div class=\"header-line metadata-line draft-line\"><span class=\"draft-status\">[DRAFT Generated at $(LC_TIME=C date '+%B %d, %Y at %I:%M:%S %p %Z')]</span></div>"
        fi
        
        echo "$header_html"
    }
    
    DIFF_HEADER_HTML=$(generate_diff_header)
    
    # Generate timestamp for conversion (force English locale, matching convert)
    GENERATION_TIME=$(LC_TIME=C date '+%B %d, %Y at %I:%M:%S %p %Z')

    # Set resource path to second file directory for resource resolution
    FILE2_DIR=$(dirname "$FILE2")

    # Build pandoc command as array (not string with eval). Header HTML is passed
    # as a single array element below, so no shell escaping is needed — escaping the
    # quotes here would leak backslashes into the rendered output.
    PANDOC_ARGS=(
        "pandoc" "$TEMP_DIFF" "-o" "$OUTPUT_FILE"
        "--from" "html"
        "--standalone"
    )

    # Only pass --template when one was actually found; pandoc errors on an empty
    # --template= value, so fall back to its default template otherwise.
    if [ -n "$TEMPLATE_ABS" ]; then
        PANDOC_ARGS+=("--template=$TEMPLATE_ABS")
    else
        echo "  ⚠ Warning: templates/report.html not found, using pandoc default template"
    fi

    # Add TOC args if not disabled
    if [ "$NO_TOC" != "true" ]; then
        PANDOC_ARGS+=("--toc" "--toc-depth=3")
    fi
    
    PANDOC_ARGS+=(
        "--resource-path=$FILE2_DIR"
        "--metadata" "title=$rev2_title"
        "--metadata" "generation_time=$GENERATION_TIME"
        "--metadata" "diff_mode=true"
        "--metadata" "custom_header=$DIFF_HEADER_HTML"
    )
    
    # Add ZDDC configuration variables from zddc.conf (only once)
    if [ -n "$client" ]; then
        PANDOC_ARGS+=("--variable" "client=$client")
    fi
    if [ -n "$project" ]; then
        PANDOC_ARGS+=("--variable" "project=$project")
    fi
    if [ -n "$contractor" ]; then
        PANDOC_ARGS+=("--variable" "contractor=$contractor")
    fi
    if [ -n "$project_number" ]; then
        PANDOC_ARGS+=("--variable" "project_number=$project_number")
    fi
    
    # Pass TOC status to template
    if [ "$NO_TOC" = "true" ]; then
        PANDOC_ARGS+=("--variable" "no-toc=true")
    fi
    
    PANDOC_ARGS+=("--section-divs" "--html-q-tags")
    
    # Execute pandoc via array (no eval)
    if "${PANDOC_ARGS[@]}"; then
        echo "  ✓ HTML generated successfully"
        
        echo "Stage 3: Adding diff view controls..."
        inject_diff_controls "$OUTPUT_FILE"
        
        echo "  ✓ Successfully created diff HTML: $(basename "$OUTPUT_FILE")"
        SUCCESSFUL=$((SUCCESSFUL + 1))
    else
        echo "  ✗ Failed to convert diff to HTML"
        FAILED=$((FAILED + 1))
    fi
    
    # Clean up temp file
    rm -f "$TEMP_DIFF"
done

echo ""
echo "=========================================="
echo "DIFF CONVERSION SUMMARY"
echo "=========================================="
echo "Total pairs processed: $TOTAL_PAIRS"
echo "Successful conversions: $SUCCESSFUL"
echo "Failed conversions: $FAILED"
echo "Skipped (existing files): $SKIPPED"
echo "=========================================="
