#!/bin/bash

# 🚀 Production Environment Manager
# Manages production Docker deployment with organized structure

set -e

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
COMPOSE_FILE="${COMPOSE_FILE:-$PROJECT_ROOT/docker/prod/docker-compose.yml}"
ENV_FILE="$PROJECT_ROOT/.env"
PROJECT_NAME="portal-prod"

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

log() { echo -e "${GREEN}[PROD] $1${NC}"; }
warn() { echo -e "${YELLOW}[PROD] $1${NC}"; }
info() { echo -e "${BLUE}[PROD] $1${NC}"; }
error() { echo -e "${RED}[PROD] ERROR: $1${NC}"; exit 1; }

# Change to project root
cd "$PROJECT_ROOT"

# Check environment file
check_env() {
    if [ ! -f "$ENV_FILE" ]; then
        log "Creating environment file from template..."
        cp .env.example .env
        error "Environment file created at $ENV_FILE. Please edit it with your production values before deploying."
    fi
    
    # Check for required variables
    required_vars=("DATABASE_URL" "REDIS_URL" "JWT_SECRET" "POSTGRES_PASSWORD" "CORS_ORIGIN" "NEXT_PUBLIC_API_BASE" "BFF_PORT")
    for var in "${required_vars[@]}"; do
        if ! grep -q "^$var=" "$ENV_FILE" || grep -q "^$var=.*CHANGE_THIS" "$ENV_FILE"; then
            error "Required environment variable $var is not properly set in $ENV_FILE"
        fi
    done
}
issue_cert() {
    local domain="$1"
    local email="$2"
    if [ -z "$domain" ] || [ -z "$email" ]; then
        error "Usage: $0 issue-cert <domain> <email>"
    fi

    log "🔐 Issuing certificate for $domain ..."
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" run --rm -p 80:80 \
      -e CERTBOT_DOMAIN="$domain" -e CERTBOT_EMAIL="$email" certbot \
      certonly --webroot -w /var/www/certbot -d "$domain" --agree-tos --no-eff-email
    log "✅ Certificate issuance process completed"
}

# Build production images
build_images() {
    log "🔨 Building production images..."
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" build --no-cache
    log "✅ Images built successfully"
}

# Deploy production environment
deploy() {
    log "🚀 Deploying production environment..."
    
    check_env
    build_images
    
    # Start database and cache first
    log "🗄️ Starting database and cache..."
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" up -d database cache
    
    # Wait for database
    log "⏳ Waiting for database..."
    timeout=60
    while [ $timeout -gt 0 ]; do
        if docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" exec -T database pg_isready -U portal -d portal_prod 2>/dev/null; then
            log "✅ Database is ready"
            break
        fi
        sleep 2
        timeout=$((timeout - 2))
    done
    
    if [ $timeout -eq 0 ]; then
        error "Database failed to start within 60 seconds"
    fi
    
    # Run migrations
    log "🔄 Running database migrations..."
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" run --rm backend pnpm db:migrate || warn "Migration may have failed"
    
    # Start application services (apps only; Plesk handles proxy)
    log "🚀 Starting application services..."
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" up -d frontend backend
    
    # Health checks
    log "🏥 Performing health checks..."
    sleep 15
    
    if docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" ps | grep -q "unhealthy"; then
        warn "Some services may not be healthy - check logs"
    fi
    
    log "✅ Production deployment completed!"
    log "🔗 Frontend: http://localhost:3000"
    log "🔗 Backend API: http://localhost:4000"
}

# Stop production services
stop() {
    log "⏹️ Stopping production services..."
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" down
    log "✅ Services stopped"
}

# Update deployment
update() {
    log "🔄 Updating production deployment..."
    check_env
    build_images
    
    # Zero-downtime update
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" up -d --force-recreate --no-deps backend frontend
    
    log "✅ Production update completed"
}

# Show status with health checks
status() {
    log "📊 Production Services Status:"
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" ps
    
    log "🏥 Health Status:"
    # If proxy service exists (non-Plesk mode), check it; otherwise, check frontend directly
    if docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" ps proxy >/dev/null 2>&1; then
        docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" exec proxy wget --spider -q http://localhost/healthz && echo "✅ Proxy/Frontend healthy" || echo "❌ Proxy/Frontend unhealthy"
    else
        docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" exec frontend wget --spider -q http://localhost:3000/api/health && echo "✅ Frontend healthy" || echo "❌ Frontend unhealthy"
    fi
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" exec backend wget --spider -q http://localhost:4000/health && echo "✅ Backend healthy" || echo "❌ Backend unhealthy"
}

# Show logs
logs() {
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" logs -f "${@:2}"
}

# Backup database
backup() {
    log "💾 Creating database backup..."
    backup_file="backup_$(date +%Y%m%d_%H%M%S).sql"
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" exec -T database pg_dump -U portal portal_prod > "$backup_file"
    log "✅ Database backup created: $backup_file"
}

# Clean up
cleanup() {
    log "🧹 Cleaning up old containers and images..."
    docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" down --remove-orphans
    docker system prune -f
    docker image prune -f
    log "✅ Cleanup completed"
}

# Main function
case "${1:-help}" in
    "deploy") deploy ;;
    "start") 
        docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" up -d
        log "✅ Production services started"
        ;;
    "stop") stop ;;
    "restart")
        docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" -p "$PROJECT_NAME" restart
        log "✅ Services restarted"
        ;;
    "update") update ;;
    "build") build_images ;;
    "issue-cert") issue_cert "$2" "$3" ;;
    "status") status ;;
    "logs") logs "$@" ;;
    "backup") backup ;;
    "cleanup") cleanup ;;
    "help"|*)
        echo "🚀 Production Environment Manager"
        echo ""
        echo "Usage: $0 {command}"
        echo ""
        echo "Commands:"
        echo "  deploy    - Full deployment (build + start + migrate)"
        echo "  start     - Start all production services"
        echo "  stop      - Stop all production services"
        echo "  restart   - Restart all services"
        echo "  update    - Update deployment with new images"
        echo "  build     - Build production images"
        echo "  status    - Show service status and health"
        echo "  logs      - Show service logs"
        echo "  backup    - Create database backup"
        echo "  cleanup   - Clean up old containers and images"
        echo "  help      - Show this help"
        exit 0
        ;;
esac
