#!/bin/bash
# Monaco USA Portal - Production Deployment Script
# For Debian/Ubuntu Linux servers
#
# Usage: ./deploy.sh [command]
# Commands:
#   setup     - First-time setup (install Docker, configure firewall)
#   deploy    - Build and start all services
#   update    - Pull latest changes and rebuild portal
#   logs      - View logs
#   status    - Check service status
#   backup    - Backup database
#   restore   - Restore database from backup

set -e

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

# Configuration
COMPOSE_FILE="docker-compose.yml"
PROJECT_NAME="monacousa"
REGISTRY="code.letsbe.solutions/letsbe"

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

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

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

# Check if running as root
check_root() {
    if [ "$EUID" -ne 0 ]; then
        log_error "Please run as root (sudo ./deploy.sh)"
        exit 1
    fi
}

# Install Docker and Docker Compose on Debian
install_docker() {
    log_info "Installing Docker..."

    # Remove old versions
    apt-get remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true

    # Install dependencies
    apt-get update
    apt-get install -y \
        apt-transport-https \
        ca-certificates \
        curl \
        gnupg \
        lsb-release

    # Add Docker's official GPG key
    install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    chmod a+r /etc/apt/keyrings/docker.gpg

    # Add repository
    echo \
        "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
        $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
        tee /etc/apt/sources.list.d/docker.list > /dev/null

    # Install Docker
    apt-get update
    apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    # Start and enable Docker
    systemctl start docker
    systemctl enable docker

    log_info "Docker installed successfully"
}

# Configure firewall
configure_firewall() {
    log_info "Configuring firewall..."

    # Install ufw if not present
    apt-get install -y ufw

    # Allow SSH, HTTP, HTTPS
    ufw allow ssh
    ufw allow http
    ufw allow https

    # Enable firewall
    ufw --force enable

    log_info "Firewall configured (SSH, HTTP, HTTPS allowed)"
}

# First-time setup
setup() {
    check_root
    log_info "Starting first-time setup..."

    # Update system
    apt-get update && apt-get upgrade -y

    # Install Docker
    install_docker

    # Configure firewall
    configure_firewall

    # Install useful tools
    apt-get install -y htop nano git apache2-utils

    # Check for .env file
    if [ ! -f .env ]; then
        log_warn ".env file not found!"
        log_info "Copy .env.production.example to .env and configure it:"
        echo "  cp .env.production.example .env"
        echo "  nano .env"
    fi

    log_info "Setup complete! Next steps:"
    echo "  1. Configure .env file: nano .env"
    echo "  2. Deploy: ./deploy.sh deploy"
}

# Generate secrets helper
generate_secrets() {
    log_info "Generating secrets..."
    echo ""
    echo "JWT_SECRET=$(openssl rand -base64 32)"
    echo "POSTGRES_PASSWORD=$(openssl rand -base64 32)"
    echo "SECRET_KEY_BASE=$(openssl rand -base64 64)"
    echo ""
    log_info "Copy these values to your .env file"
}

# Build custom Docker images (run from dev machine)
build_images() {
    log_info "Building custom Docker images..."

    # Sync latest SQL files into build contexts
    cp supabase/docker/00-init-schemas.sql docker/db/00-init-schemas.sql
    cp supabase/docker/migrate.sh docker/db/migrate.sh
    cp deploy/init.sql docker/migrate/init.sql
    cp deploy/post-deploy.sql docker/migrate/post-deploy.sql

    docker build -t ${REGISTRY}/monacousa-db:latest docker/db/
    docker build -t ${REGISTRY}/monacousa-kong:latest docker/kong/
    docker build -t ${REGISTRY}/monacousa-migrate:latest docker/migrate/

    log_info "All images built successfully"
}

# Push custom Docker images to registry
push_images() {
    log_info "Pushing images to ${REGISTRY}..."

    docker push ${REGISTRY}/monacousa-db:latest
    docker push ${REGISTRY}/monacousa-kong:latest
    docker push ${REGISTRY}/monacousa-migrate:latest

    log_info "All images pushed successfully"
}

# Deploy/start services
deploy() {
    log_info "Deploying Monaco USA Portal..."

    # Check for .env file
    if [ ! -f .env ]; then
        log_error ".env file not found! Create .env with required variables first."
        exit 1
    fi

    # Pull latest images and start all services
    # Kong config is generated at startup from env vars
    # Migrations run automatically via the migrate container
    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME pull
    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME up -d

    log_info "Waiting for services to start..."
    sleep 10

    # Show status
    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME ps

    log_info "Migrations run automatically via the migrate container."
    log_info "Check migrate logs: docker compose -f $COMPOSE_FILE -p $PROJECT_NAME logs migrate"
    log_info "Portal should be available at https://\$(grep DOMAIN .env | cut -d '=' -f2)"
}

# Update all services (pull latest images and restart)
update() {
    log_info "Updating Monaco USA Portal..."

    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME pull
    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME up -d

    log_info "Update complete!"
}

# View logs
logs() {
    local service=${1:-""}
    if [ -z "$service" ]; then
        docker compose -f $COMPOSE_FILE -p $PROJECT_NAME logs -f --tail=100
    else
        docker compose -f $COMPOSE_FILE -p $PROJECT_NAME logs -f --tail=100 $service
    fi
}

# Check status
status() {
    log_info "Service Status:"
    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME ps
    echo ""
    log_info "Resource Usage:"
    docker stats --no-stream $(docker compose -f $COMPOSE_FILE -p $PROJECT_NAME ps -q)
}

# Backup database
backup() {
    local backup_file="backup_$(date +%Y%m%d_%H%M%S).sql"
    log_info "Backing up database to $backup_file..."

    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME exec -T db \
        pg_dump -U postgres postgres > "$backup_file"

    # Compress
    gzip "$backup_file"

    log_info "Backup complete: ${backup_file}.gz"
}

# Restore database
restore() {
    local backup_file=$1
    if [ -z "$backup_file" ]; then
        log_error "Usage: ./deploy.sh restore <backup_file.sql.gz>"
        exit 1
    fi

    log_warn "This will overwrite the current database!"
    read -p "Are you sure? (y/N) " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        exit 1
    fi

    log_info "Restoring database from $backup_file..."

    # Decompress if needed
    if [[ "$backup_file" == *.gz ]]; then
        gunzip -c "$backup_file" | docker compose -f $COMPOSE_FILE -p $PROJECT_NAME exec -T db \
            psql -U postgres postgres
    else
        cat "$backup_file" | docker compose -f $COMPOSE_FILE -p $PROJECT_NAME exec -T db \
            psql -U postgres postgres
    fi

    log_info "Restore complete!"
}

# Stop all services
stop() {
    log_info "Stopping all services..."
    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME down
    log_info "All services stopped"
}

# Restart all services
restart() {
    log_info "Restarting all services..."
    docker compose -f $COMPOSE_FILE -p $PROJECT_NAME restart
    log_info "All services restarted"
}

# Clean up unused Docker resources
cleanup() {
    log_info "Cleaning up unused Docker resources..."
    docker system prune -af --volumes
    log_info "Cleanup complete"
}

# Show help
help() {
    echo "Monaco USA Portal - Deployment Script"
    echo ""
    echo "Usage: ./deploy.sh [command]"
    echo ""
    echo "Server Commands (only need .env + docker-compose.yml):"
    echo "  setup           First-time server setup (install Docker, firewall)"
    echo "  generate-secrets Generate random secrets for .env"
    echo "  deploy          Pull images and start all services"
    echo "  update          Pull latest images and restart"
    echo "  stop            Stop all services"
    echo "  restart         Restart all services"
    echo "  status          Show service status and resource usage"
    echo "  logs [service]  View logs (optionally for specific service)"
    echo "  backup          Backup database to file"
    echo "  restore <file>  Restore database from backup"
    echo "  cleanup         Remove unused Docker resources"
    echo ""
    echo "Dev Commands (run from the repo with docker/ directory):"
    echo "  build-images    Build custom Docker images (db, kong, migrate)"
    echo "  push-images     Push custom images to registry"
    echo ""
    echo "Examples:"
    echo "  sudo ./deploy.sh setup        # First-time setup"
    echo "  ./deploy.sh deploy            # Deploy the portal"
    echo "  ./deploy.sh logs portal       # View portal logs"
    echo "  ./deploy.sh build-images      # Build custom images (dev)"
    echo "  ./deploy.sh push-images       # Push images to registry (dev)"
}

# Main command handler
case "${1:-help}" in
    setup)
        setup
        ;;
    generate-secrets)
        generate_secrets
        ;;
    build-images)
        build_images
        ;;
    push-images)
        push_images
        ;;
    deploy)
        deploy
        ;;
    update)
        update
        ;;
    stop)
        stop
        ;;
    restart)
        restart
        ;;
    status)
        status
        ;;
    logs)
        logs $2
        ;;
    backup)
        backup
        ;;
    restore)
        restore $2
        ;;
    cleanup)
        cleanup
        ;;
    help|--help|-h)
        help
        ;;
    *)
        log_error "Unknown command: $1"
        help
        exit 1
        ;;
esac
