#!/bin/bash

# Content validation script for all localized content types
# Validates JSON structure, required fields, and content integrity

set -e

# Set bash mode for associative arrays
if [ -n "$BASH_VERSION" ]; then
    set +h  # Disable hash table to allow associative arrays
fi

# Configuration
CONTENT_DIR="content"
SUPPORTED_LANGUAGES=("en" "es")
# Dynamically discover content types from content-kinds.toml
get_content_types() {
    if [ -f "content/content-kinds.toml" ]; then
        # Extract content type names from TOML file
        grep '^\[' content/content-kinds.toml | sed 's/\[//g' | sed 's/\]//g' | sort -u
    else
        # Fallback: discover from directory structure
        find content -maxdepth 1 -type d -not -name "locales" -not -name "themes" -not -name "menus" -not -name "footer" -not -name "tmp" -printf '%f\n' | sort
    fi
}

# Get content types dynamically
mapfile -t CONTENT_TYPES < <(get_content_types)

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Counters
TOTAL_FILES=0
VALID_FILES=0
ERROR_COUNT=0
WARNING_COUNT=0

echo -e "${BLUE}🔍 Content Validation Report${NC}"
echo "==============================="

# Function to log errors
log_error() {
    echo -e "${RED}❌ ERROR: $1${NC}"
    ((ERROR_COUNT++))
}

# Function to log warnings
log_warning() {
    echo -e "${YELLOW}⚠️  WARNING: $1${NC}"
    ((WARNING_COUNT++))
}

# Function to log success
log_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

# Function to log info
log_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

# Check if jq is available
check_dependencies() {
    if ! command -v jq >/dev/null 2>&1; then
        log_error "jq is required but not installed. Please install jq to continue."
        exit 1
    fi
    log_success "Dependencies check passed"
}

# Validate JSON syntax
validate_json_syntax() {
    local file="$1"

    if ! jq empty "$file" 2>/dev/null; then
        log_error "Invalid JSON syntax in $file"
        return 1
    fi
    return 0
}

# Generic validate content item structure
validate_content_item() {
    local file="$1"
    local content_type="$2"
    local index="$3"

    # Determine content array key based on content type (blog -> blog_posts, recipes -> recipes)
    local array_key="${content_type}"
    if [[ "$content_type" == "blog" ]]; then
        array_key="blog"
    fi

    local required_fields=("id" "title" "excerpt" "tags" "featured" "language" "source_file" "html_file" "translations")

    # Add content-type specific required fields
    if [[ "$content_type" == "blog" ]]; then
        required_fields+=("author" "date" "read_time" "published")
    elif [[ "$content_type" == "recipes" ]]; then
        required_fields+=("category" "difficulty" "prep_time")
    fi

    for field in "${required_fields[@]}"; do
        if ! jq -e ".${array_key}[$index] | has(\"$field\")" "$file" >/dev/null 2>&1; then
            log_error "Missing required field '$field' in $content_type item at index $index in $file"
            return 1
        fi
    done

    # Validate specific field types and constraints
    local id=$(jq -r ".${array_key}[$index].id" "$file")
    local title=$(jq -r ".${array_key}[$index].title" "$file")
    local language=$(jq -r ".${array_key}[$index].language" "$file")
    local tags=$(jq -r ".${array_key}[$index].tags | length" "$file")

    # Check if ID is non-empty
    if [[ -z "$id" || "$id" == "null" ]]; then
        log_error "$content_type item ID cannot be empty at index $index in $file"
        return 1
    fi

    # Check if title is non-empty
    if [[ -z "$title" || "$title" == "null" ]]; then
        log_error "$content_type item title cannot be empty at index $index in $file"
        return 1
    fi

    # Extract content type from file path dynamically
    local expected_lang=$(echo "$file" | sed -n "s|.*${content_type}/\([^/]*\)/.*|\1|p")
    if [[ "$language" != "$expected_lang" ]]; then
        log_warning "Language mismatch in $file: expected '$expected_lang', found '$language'"
    fi

    # Content-type specific validations
    if [[ "$content_type" == "blog" ]]; then
        local date=$(jq -r ".${array_key}[$index].date" "$file")
        # Check date format (YYYY-MM-DD)
        if ! [[ "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
            log_warning "Invalid date format in $content_type item '$id': expected YYYY-MM-DD, found '$date'"
        fi
    elif [[ "$content_type" == "recipes" ]]; then
        local difficulty=$(jq -r ".${array_key}[$index].difficulty" "$file")
        # Validate difficulty levels (allow translations)
        local valid_difficulties=("Beginner" "Intermediate" "Advanced" "Expert" "Principiante" "Intermedio" "Avanzado" "Experto")
        local difficulty_valid=false
        for valid_diff in "${valid_difficulties[@]}"; do
            if [[ "$difficulty" == "$valid_diff" ]]; then
                difficulty_valid=true
                break
            fi
        done
        if [[ "$difficulty_valid" == "false" ]]; then
            log_warning "Invalid difficulty level '$difficulty' in $content_type item '$id'. Valid levels: ${valid_difficulties[*]}"
        fi
    fi

    # Check if tags array has at least one item
    if [[ "$tags" == "0" ]]; then
        log_warning "$content_type item '$id' has no tags"
    fi

    return 0
}


# Generic validate content index file
validate_content_index() {
    local file="$1"
    local content_type="$2"
    local language="$3"

    log_info "Validating $content_type index: $file"
    ((TOTAL_FILES++))

    # Check if file exists
    if [[ ! -f "$file" ]]; then
        log_error "$content_type index file not found: $file"
        return 1
    fi

    # Validate JSON syntax
    if ! validate_json_syntax "$file"; then
        return 1
    fi

    # Determine array key based on content type
    local array_key="${content_type}"
    if [[ "$content_type" == "blog" ]]; then
        array_key="blog_posts"
    fi

    # Check required top-level fields
    if ! jq -e "has(\"$array_key\")" "$file" >/dev/null 2>&1; then
        log_error "Missing '$array_key' field in $file"
        return 1
    fi

    if ! jq -e 'has("language")' "$file" >/dev/null 2>&1; then
        log_error "Missing 'language' field in $file"
        return 1
    fi

    # Check if content array is an array
    if ! jq -e ".$array_key | type == \"array\"" "$file" >/dev/null 2>&1; then
        log_error "'$array_key' must be an array in $file"
        return 1
    fi

    # Check language field matches directory
    local file_language=$(jq -r '.language' "$file")
    if [[ "$file_language" != "$language" ]]; then
        log_error "Language mismatch in $file: expected '$language', found '$file_language'"
        return 1
    fi

    # Validate each content item
    local item_count=$(jq ".$array_key | length" "$file")
    local valid_items=0

    for ((i=0; i<item_count; i++)); do
        if validate_content_item "$file" "$content_type" "$i"; then
            ((valid_items++))
        fi
    done

    log_info "Validated $valid_items/$item_count $content_type items in $file"
    ((VALID_FILES++))
    return 0
}


# Check for duplicate IDs across languages
check_duplicate_ids() {
    log_info "Checking for duplicate IDs..."

    # Simple approach: collect all IDs and check for duplicates
    local temp_dir="/tmp/content_validation_$$"
    mkdir -p "$temp_dir"

    # Collect blog IDs
    for lang in "${SUPPORTED_LANGUAGES[@]}"; do
        local blog_file="${CONTENT_DIR}/blog/${lang}/index.json"
        if [[ -f "$blog_file" ]]; then
            jq -r '.blog_posts[].id' "$blog_file" 2>/dev/null | while read -r id; do
                if [[ -n "$id" && "$id" != "null" ]]; then
                    echo "$id" >> "$temp_dir/blog_ids"
                fi
            done
        fi
    done

    # Check for duplicate blog IDs
    if [[ -f "$temp_dir/blog_ids" ]]; then
        local duplicates=$(sort "$temp_dir/blog_ids" | uniq -d)
        if [[ -n "$duplicates" ]]; then
            while read -r dup_id; do
                log_warning "Duplicate blog post ID found: '$dup_id'"
            done <<< "$duplicates"
        fi
    fi

    # Collect recipe IDs
    for lang in "${SUPPORTED_LANGUAGES[@]}"; do
        local recipe_file="${CONTENT_DIR}/recipes/${lang}/index.json"
        if [[ -f "$recipe_file" ]]; then
            jq -r '.recipes[].id' "$recipe_file" 2>/dev/null | while read -r id; do
                if [[ -n "$id" && "$id" != "null" ]]; then
                    echo "$id" >> "$temp_dir/recipe_ids"
                fi
            done
        fi
    done

    # Check for duplicate recipe IDs
    if [[ -f "$temp_dir/recipe_ids" ]]; then
        local duplicates=$(sort "$temp_dir/recipe_ids" | uniq -d)
        if [[ -n "$duplicates" ]]; then
            while read -r dup_id; do
                log_warning "Duplicate recipe ID found: '$dup_id'"
            done <<< "$duplicates"
        fi
    fi

    # Cleanup
    rm -rf "$temp_dir"
}

# Validate translation references
validate_translations() {
    log_info "Validating translation references..."

    # Simple translation validation - check if any content claims translations
    for lang in "${SUPPORTED_LANGUAGES[@]}"; do
        local blog_file="${CONTENT_DIR}/blog/${lang}/index.json"
        if [[ -f "$blog_file" ]]; then
            local posts_with_translations=$(jq -r '.blog_posts[] | select(.translations | length > 0) | .id' "$blog_file" 2>/dev/null || echo "")
            if [[ -n "$posts_with_translations" ]]; then
                log_info "Blog posts in '$lang' claiming translations: $(echo "$posts_with_translations" | tr '\n' ' ')"
            fi
        fi

        local recipe_file="${CONTENT_DIR}/recipes/${lang}/index.json"
        if [[ -f "$recipe_file" ]]; then
            local recipes_with_translations=$(jq -r '.recipes[] | select(.translations | length > 0) | .id' "$recipe_file" 2>/dev/null || echo "")
            if [[ -n "$recipes_with_translations" ]]; then
                log_info "Recipes in '$lang' claiming translations: $(echo "$recipes_with_translations" | tr '\n' ' ')"
            fi
        fi
    done
}

# Main validation function
main() {
    echo "Starting content validation..."
    echo "Content directory: $CONTENT_DIR"
    echo "Supported languages: ${SUPPORTED_LANGUAGES[*]}"
    echo ""

    # Check dependencies
    check_dependencies

    # Validate each language and content type
    for lang in "${SUPPORTED_LANGUAGES[@]}"; do
        log_info "Validating content for language: $lang"

        # Validate content for each discovered content type
        for content_type in "${CONTENT_TYPES[@]}"; do
            local content_index="${CONTENT_DIR}/${content_type}/${lang}/index.json"
            if [[ -f "$content_index" ]]; then
                validate_content_index "$content_index" "$content_type" "$lang"
            else
                log_info "Content index not found (skipping): $content_index"
            fi
        done
    done

    # Cross-validation checks
    check_duplicate_ids
    validate_translations

    # Summary
    echo ""
    echo "==============================="
    echo -e "${BLUE}📊 Validation Summary${NC}"
    echo "==============================="
    echo "Total files validated: $TOTAL_FILES"
    echo "Valid files: $VALID_FILES"
    echo -e "${RED}Errors: $ERROR_COUNT${NC}"
    echo -e "${YELLOW}Warnings: $WARNING_COUNT${NC}"

    if [[ $ERROR_COUNT -eq 0 ]]; then
        if [[ $WARNING_COUNT -eq 0 ]]; then
            log_success "All content validation passed! 🎉"
        else
            echo -e "${YELLOW}Validation completed with warnings. Please review the warnings above.${NC}"
        fi

        exit 0
    else
        log_error "Validation failed with $ERROR_COUNT errors. Please fix the errors above."

        exit 1
    fi
}

# Run main function
main "$@"
