#!/bin/bash

# Content synchronization script for localized blog and recipe content
# Synchronizes content structure and metadata across languages while preserving translations

set -e

# Configuration
CONTENT_DIR="content"
SUPPORTED_LANGUAGES=("en" "es")
DEFAULT_LANGUAGE="en"
BACKUP_DIR="content_backup_$(date +%Y%m%d_%H%M%S)"

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

# Helper functions
log_error() {
    echo -e "${RED}❌ ERROR: $1${NC}"
}

log_warning() {
    echo -e "${YELLOW}⚠️  WARNING: $1${NC}"
}

log_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

log_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

log_step() {
    echo -e "${CYAN}🔧 $1${NC}"
}

log_sync() {
    echo -e "${PURPLE}🔄 $1${NC}"
}

# Display usage information
show_usage() {
    echo -e "${BLUE}🔄 Content Synchronization Tool${NC}"
    echo "=================================="
    echo ""
    echo "Usage: $0 [COMMAND] [OPTIONS]"
    echo ""
    echo "Commands:"
    echo "  sync-structure     Synchronize content structure across languages"
    echo "  sync-metadata      Synchronize metadata (keeping translations intact)"
    echo "  check-missing      Check for missing translations"
    echo "  generate-missing   Generate placeholder content for missing translations"
    echo "  backup             Create backup of current content"
    echo "  restore            Restore from backup"
    echo "  validate           Validate content synchronization"
    echo "  help               Show this help message"
    echo ""
    echo "Options:"
    echo "  --source-lang      Source language for synchronization (default: en)"
    echo "  --target-lang      Target language (default: all supported languages)"
    echo "  --content-type     Content type to sync (blog/recipes/all, default: all)"
    echo "  --dry-run          Show what would be done without making changes"
    echo "  --force            Force overwrite existing files"
    echo "  --backup           Create backup before changes"
    echo ""
    echo "Examples:"
    echo "  $0 sync-structure --source-lang en --target-lang es"
    echo "  $0 check-missing --content-type blog"
    echo "  $0 generate-missing --dry-run"
    echo "  $0 backup"
    echo ""
}

# Parse command line arguments
parse_args() {
    SOURCE_LANG="$DEFAULT_LANGUAGE"
    TARGET_LANG="all"
    CONTENT_TYPE="all"
    DRY_RUN=false
    FORCE=false
    CREATE_BACKUP=false

    while [[ $# -gt 0 ]]; do
        case $1 in
            --source-lang)
                SOURCE_LANG="$2"
                shift 2
                ;;
            --target-lang)
                TARGET_LANG="$2"
                shift 2
                ;;
            --content-type)
                CONTENT_TYPE="$2"
                shift 2
                ;;
            --dry-run)
                DRY_RUN=true
                shift
                ;;
            --force)
                FORCE=true
                shift
                ;;
            --backup)
                CREATE_BACKUP=true
                shift
                ;;
            *)
                log_error "Unknown option: $1"
                show_usage
                exit 1
                ;;
        esac
    done
}

# Check dependencies
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"
}

# Create backup
create_backup() {
    log_step "Creating backup of content..."

    if [[ -d "$CONTENT_DIR" ]]; then
        cp -r "$CONTENT_DIR" "$BACKUP_DIR"
        log_success "Backup created: $BACKUP_DIR"
    else
        log_warning "Content directory not found, no backup created"
    fi
}

# Restore from backup
restore_backup() {
    local backup_path="$1"

    if [[ -z "$backup_path" ]]; then
        # Find most recent backup
        backup_path=$(ls -1d content_backup_* 2>/dev/null | sort | tail -1)
        if [[ -z "$backup_path" ]]; then
            log_error "No backup found"
            exit 1
        fi
    fi

    if [[ ! -d "$backup_path" ]]; then
        log_error "Backup directory not found: $backup_path"
        exit 1
    fi

    log_step "Restoring from backup: $backup_path"

    if [[ "$DRY_RUN" == "true" ]]; then
        log_info "[DRY RUN] Would restore content from $backup_path"
        return
    fi

    if [[ -d "$CONTENT_DIR" ]]; then
        rm -rf "${CONTENT_DIR}.old" 2>/dev/null || true
        mv "$CONTENT_DIR" "${CONTENT_DIR}.old"
    fi

    cp -r "$backup_path" "$CONTENT_DIR"
    log_success "Content restored from backup"
}

# Get content indices for a language
get_content_indices() {
    local lang="$1"
    local content_type="$2"

    case "$content_type" in
        "blog")
            echo "${CONTENT_DIR}/blog/${lang}/index.json"
            ;;
        "recipes")
            echo "${CONTENT_DIR}/recipes/${lang}/index.json"
            ;;
        *)
            echo "${CONTENT_DIR}/blog/${lang}/index.json ${CONTENT_DIR}/recipes/${lang}/index.json"
            ;;
    esac
}

# Get target languages
get_target_languages() {
    if [[ "$TARGET_LANG" == "all" ]]; then
        echo "${SUPPORTED_LANGUAGES[@]}"
    else
        echo "$TARGET_LANG"
    fi
}

# Check for missing content
check_missing_content() {
    log_step "Checking for missing translations..."

    local missing_count=0
    local source_indices

    if [[ "$CONTENT_TYPE" == "all" ]] || [[ "$CONTENT_TYPE" == "blog" ]]; then
        local source_blog="${CONTENT_DIR}/blog/${SOURCE_LANG}/index.json"

        if [[ -f "$source_blog" ]]; then
            log_info "Checking blog translations..."

            local blog_ids=$(jq -r '.blog[].id' "$source_blog" 2>/dev/null || echo "")

            for lang in $(get_target_languages); do
                if [[ "$lang" == "$SOURCE_LANG" ]]; then
                    continue
                fi

                local target_blog="${CONTENT_DIR}/blog/${lang}/index.json"

                if [[ ! -f "$target_blog" ]]; then
                    log_warning "Missing blog index for language: $lang"
                    ((missing_count++))
                    continue
                fi

                while IFS= read -r id; do
                    if [[ -n "$id" && "$id" != "null" ]]; then
                        local exists=$(jq -r ".blog[] | select(.id == \"$id\") | .id" "$target_blog" 2>/dev/null || echo "")
                        if [[ -z "$exists" ]]; then
                            log_warning "Missing blog post translation: '$id' in language '$lang'"
                            ((missing_count++))
                        fi
                    fi
                done <<< "$blog_ids"
            done
        fi
    fi

    if [[ "$CONTENT_TYPE" == "all" ]] || [[ "$CONTENT_TYPE" == "recipes" ]]; then
        local source_recipes="${CONTENT_DIR}/recipes/${SOURCE_LANG}/index.json"

        if [[ -f "$source_recipes" ]]; then
            log_info "Checking recipe translations..."

            local recipe_ids=$(jq -r '.recipes[].id' "$source_recipes" 2>/dev/null || echo "")

            for lang in $(get_target_languages); do
                if [[ "$lang" == "$SOURCE_LANG" ]]; then
                    continue
                fi

                local target_recipes="${CONTENT_DIR}/recipes/${lang}/index.json"

                if [[ ! -f "$target_recipes" ]]; then
                    log_warning "Missing recipe index for language: $lang"
                    ((missing_count++))
                    continue
                fi

                while IFS= read -r id; do
                    if [[ -n "$id" && "$id" != "null" ]]; then
                        local exists=$(jq -r ".recipes[] | select(.id == \"$id\") | .id" "$target_recipes" 2>/dev/null || echo "")
                        if [[ -z "$exists" ]]; then
                            log_warning "Missing recipe translation: '$id' in language '$lang'"
                            ((missing_count++))
                        fi
                    fi
                done <<< "$recipe_ids"
            done
        fi
    fi

    if [[ $missing_count -eq 0 ]]; then
        log_success "No missing translations found!"
    else
        log_warning "Found $missing_count missing translations"
    fi

    return $missing_count
}

# Synchronize content structure
sync_content_structure() {
    log_step "Synchronizing content structure from $SOURCE_LANG..."

    if [[ "$CREATE_BACKUP" == "true" ]]; then
        create_backup
    fi

    for lang in $(get_target_languages); do
        if [[ "$lang" == "$SOURCE_LANG" ]]; then
            continue
        fi

        log_sync "Synchronizing structure for language: $lang"

        # Sync blog structure
        if [[ "$CONTENT_TYPE" == "all" ]] || [[ "$CONTENT_TYPE" == "blog" ]]; then
            local source_blog="${CONTENT_DIR}/blog/${SOURCE_LANG}/index.json"
            local target_blog_dir="${CONTENT_DIR}/blog/${lang}"
            local target_blog="${target_blog_dir}/index.json"

            if [[ -f "$source_blog" ]]; then
                if [[ "$DRY_RUN" == "true" ]]; then
                    log_info "[DRY RUN] Would sync blog structure for $lang"
                else
                    mkdir -p "$target_blog_dir"

                    if [[ ! -f "$target_blog" ]]; then
                        # Create new index with proper language
                        jq --arg lang "$lang" '.language = $lang | .blog = []' "$source_blog" > "$target_blog"
                        log_success "Created blog index for $lang"
                    else
                        log_info "Blog index already exists for $lang"
                    fi
                fi
            fi
        fi

        # Sync recipe structure
        if [[ "$CONTENT_TYPE" == "all" ]] || [[ "$CONTENT_TYPE" == "recipes" ]]; then
            local source_recipes="${CONTENT_DIR}/recipes/${SOURCE_LANG}/index.json"
            local target_recipes_dir="${CONTENT_DIR}/recipes/${lang}"
            local target_recipes="${target_recipes_dir}/index.json"

            if [[ -f "$source_recipes" ]]; then
                if [[ "$DRY_RUN" == "true" ]]; then
                    log_info "[DRY RUN] Would sync recipe structure for $lang"
                else
                    mkdir -p "$target_recipes_dir"

                    if [[ ! -f "$target_recipes" ]]; then
                        # Create new index with proper language
                        jq --arg lang "$lang" '.language = $lang | .recipes = []' "$source_recipes" > "$target_recipes"
                        log_success "Created recipe index for $lang"
                    else
                        log_info "Recipe index already exists for $lang"
                    fi
                fi
            fi
        fi
    done

    log_success "Content structure synchronization completed"
}

# Generate missing translations as placeholders
generate_missing_translations() {
    log_step "Generating placeholder content for missing translations..."

    if [[ "$CREATE_BACKUP" == "true" ]]; then
        create_backup
    fi

    # Generate missing blog posts
    if [[ "$CONTENT_TYPE" == "all" ]] || [[ "$CONTENT_TYPE" == "blog" ]]; then
        local source_blog="${CONTENT_DIR}/blog/${SOURCE_LANG}/index.json"

        if [[ -f "$source_blog" ]]; then
            local blog=$(jq -c '.blog[]' "$source_blog")

            while IFS= read -r post; do
                local post_id=$(echo "$post" | jq -r '.id')

                for lang in $(get_target_languages); do
                    if [[ "$lang" == "$SOURCE_LANG" ]]; then
                        continue
                    fi

                    local target_blog="${CONTENT_DIR}/blog/${lang}/index.json"

                    if [[ -f "$target_blog" ]]; then
                        local exists=$(jq -r ".blog[] | select(.id == \"$post_id\") | .id" "$target_blog" 2>/dev/null || echo "")

                        if [[ -z "$exists" ]]; then
                            log_sync "Generating placeholder blog post: $post_id ($lang)"

                            if [[ "$DRY_RUN" == "true" ]]; then
                                log_info "[DRY RUN] Would create placeholder for blog post '$post_id' in $lang"
                            else
                                # Create placeholder post with translated metadata
                                local placeholder=$(echo "$post" | jq --arg lang "$lang" '
                                    .language = $lang |
                                    .title = .title + " [NEEDS TRANSLATION]" |
                                    .excerpt = .excerpt + " [This content needs to be translated to " + $lang + "]" |
                                    .source_file = "content/blog/" + $lang + "/" + .id + ".md" |
                                    .html_file = "/blog/" + $lang + "/" + .id + ".html" |
                                    .published = false
                                ')

                                # Add to target index
                                local temp_file="/tmp/blog_sync_${lang}.json"
                                jq --argjson new_post "$placeholder" '.blog += [$new_post]' "$target_blog" > "$temp_file"
                                mv "$temp_file" "$target_blog"

                                log_success "Created placeholder blog post: $post_id ($lang)"
                            fi
                        fi
                    fi
                done
            done <<< "$blog"
        fi
    fi

    # Generate missing recipes
    if [[ "$CONTENT_TYPE" == "all" ]] || [[ "$CONTENT_TYPE" == "recipes" ]]; then
        local source_recipes="${CONTENT_DIR}/recipes/${SOURCE_LANG}/index.json"

        if [[ -f "$source_recipes" ]]; then
            local recipes=$(jq -c '.recipes[]' "$source_recipes")

            while IFS= read -r recipe; do
                local recipe_id=$(echo "$recipe" | jq -r '.id')

                for lang in $(get_target_languages); do
                    if [[ "$lang" == "$SOURCE_LANG" ]]; then
                        continue
                    fi

                    local target_recipes="${CONTENT_DIR}/recipes/${lang}/index.json"

                    if [[ -f "$target_recipes" ]]; then
                        local exists=$(jq -r ".recipes[] | select(.id == \"$recipe_id\") | .id" "$target_recipes" 2>/dev/null || echo "")

                        if [[ -z "$exists" ]]; then
                            log_sync "Generating placeholder recipe: $recipe_id ($lang)"

                            if [[ "$DRY_RUN" == "true" ]]; then
                                log_info "[DRY RUN] Would create placeholder for recipe '$recipe_id' in $lang"
                            else
                                # Create placeholder recipe with translated metadata
                                local placeholder=$(echo "$recipe" | jq --arg lang "$lang" '
                                    .language = $lang |
                                    .title = .title + " [NEEDS TRANSLATION]" |
                                    .excerpt = .excerpt + " [This content needs to be translated to " + $lang + "]" |
                                    .source_file = "content/recipes/" + $lang + "/" + .id + ".md" |
                                    .html_file = "/recipes/" + $lang + "/" + .id + ".html"
                                ')

                                # Add to target index
                                local temp_file="/tmp/recipe_sync_${lang}.json"
                                jq --argjson new_recipe "$placeholder" '.recipes += [$new_recipe]' "$target_recipes" > "$temp_file"
                                mv "$temp_file" "$target_recipes"

                                log_success "Created placeholder recipe: $recipe_id ($lang)"
                            fi
                        fi
                    fi
                done
            done <<< "$recipes"
        fi
    fi

    log_success "Placeholder generation completed"
}

# Synchronize metadata while preserving translations
sync_metadata() {
    log_step "Synchronizing metadata from $SOURCE_LANG while preserving translations..."

    if [[ "$CREATE_BACKUP" == "true" ]]; then
        create_backup
    fi

    # Sync blog metadata
    if [[ "$CONTENT_TYPE" == "all" ]] || [[ "$CONTENT_TYPE" == "blog" ]]; then
        local source_blog="${CONTENT_DIR}/blog/${SOURCE_LANG}/index.json"

        if [[ -f "$source_blog" ]]; then
            for lang in $(get_target_languages); do
                if [[ "$lang" == "$SOURCE_LANG" ]]; then
                    continue
                fi

                local target_blog="${CONTENT_DIR}/blog/${lang}/index.json"

                if [[ -f "$target_blog" ]]; then
                    log_sync "Synchronizing blog metadata for: $lang"

                    if [[ "$DRY_RUN" == "true" ]]; then
                        log_info "[DRY RUN] Would sync blog metadata for $lang"
                    else
                        # Preserve existing translations while updating metadata
                        local temp_file="/tmp/blog_meta_sync_${lang}.json"

                        jq --slurpfile source "$source_blog" --arg lang "$lang" '
                            .language = $lang |
                            .blog = [
                                .blog[] as $target |
                                ($source[0].blog[] | select(.id == $target.id)) as $source_post |
                                if $source_post then
                                    $target |
                                    .author = $source_post.author |
                                    .date = $source_post.date |
                                    .read_time = $source_post.read_time |
                                    .tags = $source_post.tags |
                                    .featured = $source_post.featured |
                                    .published = $source_post.published |
                                    .source_file = ("content/blog/" + $lang + "/" + .id + ".md") |
                                    .html_file = ("/blog/" + $lang + "/" + .id + ".html")
                                else
                                    $target
                                end
                            ]
                        ' "$target_blog" > "$temp_file"

                        mv "$temp_file" "$target_blog"
                        log_success "Synchronized blog metadata for: $lang"
                    fi
                fi
            done
        fi
    fi

    # Sync recipe metadata
    if [[ "$CONTENT_TYPE" == "all" ]] || [[ "$CONTENT_TYPE" == "recipes" ]]; then
        local source_recipes="${CONTENT_DIR}/recipes/${SOURCE_LANG}/index.json"

        if [[ -f "$source_recipes" ]]; then
            for lang in $(get_target_languages); do
                if [[ "$lang" == "$SOURCE_LANG" ]]; then
                    continue
                fi

                local target_recipes="${CONTENT_DIR}/recipes/${lang}/index.json"

                if [[ -f "$target_recipes" ]]; then
                    log_sync "Synchronizing recipe metadata for: $lang"

                    if [[ "$DRY_RUN" == "true" ]]; then
                        log_info "[DRY RUN] Would sync recipe metadata for $lang"
                    else
                        # Preserve existing translations while updating metadata
                        local temp_file="/tmp/recipe_meta_sync_${lang}.json"

                        jq --slurpfile source "$source_recipes" --arg lang "$lang" '
                            .language = $lang |
                            .recipes = [
                                .recipes[] as $target |
                                ($source[0].recipes[] | select(.id == $target.id)) as $source_recipe |
                                if $source_recipe then
                                    $target |
                                    .category = $source_recipe.category |
                                    .difficulty = $source_recipe.difficulty |
                                    .prep_time = $source_recipe.prep_time |
                                    .tags = $source_recipe.tags |
                                    .featured = $source_recipe.featured |
                                    .source_file = ("content/recipes/" + $lang + "/" + .id + ".md") |
                                    .html_file = ("/recipes/" + $lang + "/" + .id + ".html")
                                else
                                    $target
                                end
                            ]
                        ' "$target_recipes" > "$temp_file"

                        mv "$temp_file" "$target_recipes"
                        log_success "Synchronized recipe metadata for: $lang"
                    fi
                fi
            done
        fi
    fi

    log_success "Metadata synchronization completed"
}

# Validate synchronization
validate_sync() {
    log_step "Validating content synchronization..."

    local validation_errors=0

    # Validate that all languages have the same structure
    for lang in "${SUPPORTED_LANGUAGES[@]}"; do
        log_info "Validating structure for language: $lang"

        # Check blog structure
        local blog_index="${CONTENT_DIR}/blog/${lang}/index.json"
        if [[ ! -f "$blog_index" ]]; then
            log_warning "Missing blog index for language: $lang"
            ((validation_errors++))
        else
            # Validate JSON syntax
            if ! jq empty "$blog_index" 2>/dev/null; then
                log_error "Invalid JSON in blog index for language: $lang"
                ((validation_errors++))
            fi

            # Check language field
            local file_lang=$(jq -r '.language' "$blog_index" 2>/dev/null || echo "")
            if [[ "$file_lang" != "$lang" ]]; then
                log_error "Language mismatch in blog index for $lang: expected '$lang', found '$file_lang'"
                ((validation_errors++))
            fi
        fi

        # Check recipe structure
        local recipe_index="${CONTENT_DIR}/recipes/${lang}/index.json"
        if [[ ! -f "$recipe_index" ]]; then
            log_warning "Missing recipe index for language: $lang"
            ((validation_errors++))
        else
            # Validate JSON syntax
            if ! jq empty "$recipe_index" 2>/dev/null; then
                log_error "Invalid JSON in recipe index for language: $lang"
                ((validation_errors++))
            fi

            # Check language field
            local file_lang=$(jq -r '.language' "$recipe_index" 2>/dev/null || echo "")
            if [[ "$file_lang" != "$lang" ]]; then
                log_error "Language mismatch in recipe index for $lang: expected '$lang', found '$file_lang'"
                ((validation_errors++))
            fi
        fi
    done

    if [[ $validation_errors -eq 0 ]]; then
        log_success "Content synchronization validation passed!"
    else
        log_error "Validation failed with $validation_errors errors"
        return 1
    fi
}

# Main function
main() {
    local command="$1"
    shift

    echo -e "${BLUE}🔄 Content Synchronization Tool${NC}"
    echo "=================================="
    echo ""

    check_dependencies

    case "$command" in
        "sync-structure")
            parse_args "$@"
            sync_content_structure
            ;;
        "sync-metadata")
            parse_args "$@"
            sync_metadata
            ;;
        "check-missing")
            parse_args "$@"
            check_missing_content
            ;;
        "generate-missing")
            parse_args "$@"
            generate_missing_translations
            ;;
        "backup")
            create_backup
            ;;
        "restore")
            parse_args "$@"
            restore_backup "$2"
            ;;
        "validate")
            validate_sync
            ;;
        "help"|"")
            show_usage
            ;;
        *)
            log_error "Unknown command: $command"
            show_usage
            exit 1
            ;;
    esac
}

# Run main function
main "$@"
