#!/bin/bash
set -e

# Database Import Script for MotoVaultPro
# Imports PostgreSQL database from export file
# Usage: ./scripts/import-database.sh [options] <export-file>

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

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
DATABASE_NAME="motovaultpro"

# Environment-based container names
CONTAINER_NAME=""  # Will be set based on environment selection
ENVIRONMENT=""     # production or staging

# Default values
BACKUP_EXISTING=true
DROP_EXISTING=false
CREATE_DATABASE=false
FORCE=false

# Function to print colored output
print_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

print_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

print_env() {
    echo -e "${BLUE}[ENV]${NC} $1"
}

# Function to select environment
select_environment() {
    if [ -n "$ENVIRONMENT" ]; then
        # Environment already set via command line
        return
    fi

    echo ""
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}  MotoVaultPro Database Import${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    echo "Select environment to import to:"
    echo ""
    echo "  1) Production  (mvp-postgres)"
    echo "  2) Staging     (mvp-postgres-staging)"
    echo ""
    read -p "Enter choice [1-2]: " ENV_CHOICE

    case $ENV_CHOICE in
        1)
            ENVIRONMENT="production"
            CONTAINER_NAME="mvp-postgres"
            ;;
        2)
            ENVIRONMENT="staging"
            CONTAINER_NAME="mvp-postgres-staging"
            ;;
        *)
            print_error "Invalid choice. Please enter 1 or 2."
            exit 1
            ;;
    esac

    echo ""
    print_env "Selected environment: ${ENVIRONMENT}"
    print_env "Container: ${CONTAINER_NAME}"
    echo ""
}

# Function to set container name based on environment
set_container_from_environment() {
    case $ENVIRONMENT in
        production|prod)
            ENVIRONMENT="production"
            CONTAINER_NAME="mvp-postgres"
            ;;
        staging|stage)
            ENVIRONMENT="staging"
            CONTAINER_NAME="mvp-postgres-staging"
            ;;
        *)
            print_error "Invalid environment: $ENVIRONMENT"
            print_error "Valid options: production, staging"
            exit 1
            ;;
    esac
}

# Function to show usage
show_usage() {
    cat << EOF
Database Import Script for MotoVaultPro

Usage: $0 [options] <export-file>

Options:
    -h, --help              Show this help message
    -e, --env ENV           Environment: production or staging (prompts if not specified)
    -c, --container NAME    Override container name (ignores environment selection)
    -d, --database NAME     Database name (default: motovaultpro)
    --create-db             Create database if it doesn't exist
    --drop-existing         Drop existing database before import (DANGER!)
    --no-backup             Skip backup of existing database
    --force                 Skip confirmation prompts
    -f, --format FORMAT     Import format: sql, custom, directory (auto-detected if not specified)

Environments:
    production (prod)       Uses container: mvp-postgres
    staging (stage)         Uses container: mvp-postgres-staging

Examples:
    # Interactive environment selection
    $0 database-exports/backup.sql.gz

    # Import to production
    $0 --env production database-exports/backup.sql.gz

    # Import to staging
    $0 --env staging database-exports/backup.sql.gz

    # Import with database recreation to staging
    $0 -e staging --drop-existing --create-db backup.sql

    # Import custom format to production
    $0 --env prod --format custom backup.dump

Safety Features:
    - Creates backup of existing database by default
    - Requires confirmation before destructive operations
    - Validates export file before import
    - Supports rollback on failure

EOF
    exit 0
}

# Parse command line arguments
CONTAINER_OVERRIDE=""

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            show_usage
            ;;
        -e|--env)
            ENVIRONMENT="$2"
            shift 2
            ;;
        -c|--container)
            CONTAINER_OVERRIDE="$2"
            shift 2
            ;;
        -d|--database)
            DATABASE_NAME="$2"
            shift 2
            ;;
        --create-db)
            CREATE_DATABASE=true
            shift
            ;;
        --drop-existing)
            DROP_EXISTING=true
            shift
            ;;
        --no-backup)
            BACKUP_EXISTING=false
            shift
            ;;
        --force)
            FORCE=true
            shift
            ;;
        -f|--format)
            IMPORT_FORMAT="$2"
            shift 2
            ;;
        -*)
            print_error "Unknown option: $1"
            show_usage
            ;;
        *)
            IMPORT_FILE="$1"
            shift
            ;;
    esac
done

# Validate import file
if [ -z "$IMPORT_FILE" ]; then
    print_error "No import file specified"
    show_usage
fi

if [ ! -e "$IMPORT_FILE" ]; then
    print_error "Import file does not exist: $IMPORT_FILE"
    exit 1
fi

# Handle environment selection
if [ -n "$CONTAINER_OVERRIDE" ]; then
    # Container explicitly specified, use it directly
    CONTAINER_NAME="$CONTAINER_OVERRIDE"
    ENVIRONMENT="custom"
    print_info "Using custom container: $CONTAINER_NAME"
elif [ -n "$ENVIRONMENT" ]; then
    # Environment specified via command line
    set_container_from_environment
else
    # No environment specified, prompt user
    select_environment
fi

# Auto-detect format if not specified
if [ -z "$IMPORT_FORMAT" ]; then
    if [[ "$IMPORT_FILE" == *.sql.gz ]]; then
        IMPORT_FORMAT="sql-compressed"
    elif [[ "$IMPORT_FILE" == *.sql ]]; then
        IMPORT_FORMAT="sql"
    elif [[ "$IMPORT_FILE" == *.dump ]]; then
        IMPORT_FORMAT="custom"
    elif [ -d "$IMPORT_FILE" ]; then
        IMPORT_FORMAT="directory"
    else
        print_error "Cannot auto-detect format. Please specify with --format"
        exit 1
    fi
    print_info "Auto-detected format: $IMPORT_FORMAT"
fi

# Check if container is running
print_info "Checking if PostgreSQL container is running..."
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
    print_error "PostgreSQL container '${CONTAINER_NAME}' is not running"
    print_info "Start it with: docker compose up -d mvp-postgres"
    exit 1
fi

# Check if database exists
print_info "Checking if database exists..."
DB_EXISTS=$(docker exec "$CONTAINER_NAME" psql -U postgres -tAc "SELECT 1 FROM pg_database WHERE datname='$DATABASE_NAME'" 2>/dev/null || echo "0")

if [ "$DB_EXISTS" = "1" ]; then
    print_warn "Database '$DATABASE_NAME' already exists"

    if [ "$BACKUP_EXISTING" = true ] && [ "$DROP_EXISTING" = false ]; then
        BACKUP_FILE="${PROJECT_ROOT}/database-exports/${DATABASE_NAME}_backup_$(date +%Y%m%d_%H%M%S).sql.gz"
        print_info "Creating backup: $BACKUP_FILE"
        mkdir -p "$(dirname "$BACKUP_FILE")"
        docker exec "$CONTAINER_NAME" pg_dump -U postgres -d "$DATABASE_NAME" | gzip > "$BACKUP_FILE"
        print_info "Backup created successfully"
    fi

    if [ "$DROP_EXISTING" = true ]; then
        if [ "$FORCE" = false ]; then
            echo ""
            print_warn "WARNING: This will DROP the existing database '$DATABASE_NAME'"
            print_warn "All data will be permanently deleted!"
            echo ""
            read -p "Are you sure you want to continue? (type 'yes' to confirm): " CONFIRM
            if [ "$CONFIRM" != "yes" ]; then
                print_info "Import cancelled"
                exit 0
            fi
        fi

        print_info "Dropping existing database..."
        docker exec "$CONTAINER_NAME" psql -U postgres -c "DROP DATABASE IF EXISTS $DATABASE_NAME" || {
            print_error "Failed to drop database"
            exit 1
        }
        CREATE_DATABASE=true
    fi
elif [ "$CREATE_DATABASE" = false ]; then
    print_error "Database '$DATABASE_NAME' does not exist. Use --create-db to create it"
    exit 1
fi

# Create database if needed
if [ "$CREATE_DATABASE" = true ]; then
    print_info "Creating database '$DATABASE_NAME'..."
    docker exec "$CONTAINER_NAME" psql -U postgres -c "CREATE DATABASE $DATABASE_NAME" || {
        print_error "Failed to create database"
        exit 1
    }
fi

# Import based on format
print_info "Starting database import..."
print_info "Environment: $ENVIRONMENT"
print_info "Container: $CONTAINER_NAME"
print_info "File: $IMPORT_FILE"
print_info "Format: $IMPORT_FORMAT"
print_info "Database: $DATABASE_NAME"

case $IMPORT_FORMAT in
    sql)
        print_info "Importing SQL dump..."
        docker exec -i "$CONTAINER_NAME" psql -U postgres -d "$DATABASE_NAME" < "$IMPORT_FILE" || {
            print_error "Import failed"
            exit 1
        }
        ;;

    sql-compressed)
        print_info "Importing compressed SQL dump..."
        gunzip -c "$IMPORT_FILE" | docker exec -i "$CONTAINER_NAME" psql -U postgres -d "$DATABASE_NAME" || {
            print_error "Import failed"
            exit 1
        }
        ;;

    custom)
        print_info "Importing custom format dump..."
        # Copy file into container
        docker cp "$IMPORT_FILE" "${CONTAINER_NAME}:/tmp/restore.dump" || {
            print_error "Failed to copy file to container"
            exit 1
        }
        # Restore
        docker exec "$CONTAINER_NAME" pg_restore -U postgres -d "$DATABASE_NAME" -c /tmp/restore.dump || {
            print_error "Import failed"
            docker exec "$CONTAINER_NAME" rm -f /tmp/restore.dump
            exit 1
        }
        # Cleanup
        docker exec "$CONTAINER_NAME" rm -f /tmp/restore.dump
        ;;

    directory)
        print_info "Importing directory format dump..."
        # Copy directory into container
        docker cp "$IMPORT_FILE" "${CONTAINER_NAME}:/tmp/restore_dir" || {
            print_error "Failed to copy directory to container"
            exit 1
        }
        # Restore
        docker exec "$CONTAINER_NAME" pg_restore -U postgres -d "$DATABASE_NAME" -c /tmp/restore_dir || {
            print_error "Import failed"
            docker exec "$CONTAINER_NAME" rm -rf /tmp/restore_dir
            exit 1
        }
        # Cleanup
        docker exec "$CONTAINER_NAME" rm -rf /tmp/restore_dir
        ;;

    *)
        print_error "Unknown import format: $IMPORT_FORMAT"
        exit 1
        ;;
esac

# Verify import
print_info "Verifying import..."
TABLE_COUNT=$(docker exec "$CONTAINER_NAME" psql -U postgres -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public'")
print_info "Imported $TABLE_COUNT tables"

# Summary
echo ""
print_info "==============================================="
print_info "Database Import Complete!"
print_info "==============================================="
print_info "Environment: $ENVIRONMENT"
print_info "Container: $CONTAINER_NAME"
print_info "Database: $DATABASE_NAME"
print_info "Tables: $TABLE_COUNT"
if [ "$BACKUP_EXISTING" = true ] && [ -n "$BACKUP_FILE" ]; then
    print_info "Backup: $BACKUP_FILE"
fi
echo ""
print_info "Database is ready to use!"
echo ""
