#!/usr/bin/env bash
#
# AI Stack Deployer - Automated Deployment Script
# Deploys the AI Stack Deployer application to Dokploy
#
# Usage: ./scripts/deploy-to-dokploy.sh [options]
# Options:
#   --registry REGISTRY   Docker registry to push to (default: local Docker)
#   --domain DOMAIN       Domain name for deployment (default: portal.ai.flexinit.nl)
#   --project-name NAME   Dokploy project name (default: ai-stack-deployer-portal)
#   --skip-build         Skip Docker build (use existing image)
#   --skip-test          Skip local testing
#

set -euo pipefail

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="${SCRIPT_DIR}/.."
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
LOG_FILE="${PROJECT_ROOT}/deployment-${TIMESTAMP}.log"

# Default values
REGISTRY=""
DOMAIN="portal.ai.flexinit.nl"
PROJECT_NAME="ai-stack-deployer-portal"
APP_NAME="ai-stack-deployer-web"
IMAGE_NAME="ai-stack-deployer"
SKIP_BUILD=false
SKIP_TEST=false

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

# Logging functions
log_info() {
    echo -e "${GREEN}[INFO]${NC} $*" | tee -a "${LOG_FILE}"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $*" | tee -a "${LOG_FILE}"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $*" | tee -a "${LOG_FILE}"
}

log_step() {
    echo -e "\n${GREEN}==>${NC} $*\n" | tee -a "${LOG_FILE}"
}

# Error handler
error_exit() {
    log_error "$1"
    exit 1
}

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --registry)
            REGISTRY="$2"
            shift 2
            ;;
        --domain)
            DOMAIN="$2"
            shift 2
            ;;
        --project-name)
            PROJECT_NAME="$2"
            shift 2
            ;;
        --skip-build)
            SKIP_BUILD=true
            shift
            ;;
        --skip-test)
            SKIP_TEST=true
            shift
            ;;
        *)
            echo "Unknown option: $1"
            exit 1
            ;;
    esac
done

log_info "Deployment started at ${TIMESTAMP}"
log_info "Target domain: ${DOMAIN}"
log_info "Project name: ${PROJECT_NAME}"

cd "${PROJECT_ROOT}"

# Load environment variables
if [ ! -f .env ]; then
    error_exit ".env file not found. Please create it from .env.example"
fi

source .env

if [ -z "${DOKPLOY_API_TOKEN}" ]; then
    error_exit "DOKPLOY_API_TOKEN not set in .env"
fi

if [ -z "${DOKPLOY_URL}" ]; then
    error_exit "DOKPLOY_URL not set in .env"
fi

# Phase 1: Pre-deployment checks
log_step "Phase 1: Pre-deployment Verification"

log_info "Checking Dokploy API connectivity..."
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
    -H "x-api-key: ${DOKPLOY_API_TOKEN}" \
    "${DOKPLOY_URL}/api/project.all" || echo "000")

if [ "${HTTP_CODE}" != "200" ]; then
    error_exit "Dokploy API unreachable or unauthorized (HTTP ${HTTP_CODE})"
fi

log_info "✓ Dokploy API accessible"

# Check Docker
if ! command -v docker &> /dev/null; then
    error_exit "Docker not installed"
fi

# Try docker with sg if needed
if ! docker ps &> /dev/null; then
    if sg docker -c "docker ps" &> /dev/null; then
        log_info "Using 'sg docker' for Docker commands"
        DOCKER_CMD="sg docker -c"
    else
        error_exit "Docker not accessible. Check permissions."
    fi
else
    DOCKER_CMD=""
fi

log_info "✓ Docker accessible"

# Phase 2: Build Docker image
if [ "${SKIP_BUILD}" = false ]; then
    log_step "Phase 2: Building Docker Image"

    log_info "Building image: ${IMAGE_NAME}:${TIMESTAMP}"

    ${DOCKER_CMD} docker build \
        -t "${IMAGE_NAME}:${TIMESTAMP}" \
        -t "${IMAGE_NAME}:latest" \
        . 2>&1 | tee -a "${LOG_FILE}" || error_exit "Docker build failed"

    # Get image info
    IMAGE_ID=$(${DOCKER_CMD} docker images -q "${IMAGE_NAME}:latest")
    IMAGE_SIZE=$(${DOCKER_CMD} docker images "${IMAGE_NAME}:latest" --format "{{.Size}}")

    log_info "✓ Image built successfully"
    log_info "  Image ID: ${IMAGE_ID}"
    log_info "  Size: ${IMAGE_SIZE}"
else
    log_warn "Skipping build (--skip-build specified)"
fi

# Phase 3: Local testing
if [ "${SKIP_TEST}" = false ]; then
    log_step "Phase 3: Local Container Testing"

    log_info "Starting test container..."

    # Stop existing test container if any
    ${DOCKER_CMD} docker stop ai-stack-deployer-test 2>/dev/null || true
    ${DOCKER_CMD} docker rm ai-stack-deployer-test 2>/dev/null || true

    # Start test container
    ${DOCKER_CMD} docker run -d \
        --name ai-stack-deployer-test \
        -p 3001:3000 \
        --env-file .env \
        "${IMAGE_NAME}:latest" || error_exit "Failed to start test container"

    log_info "Waiting for container to be healthy..."
    sleep 5

    # Test health endpoint
    if ! curl -sf http://localhost:3001/health > /dev/null; then
        ${DOCKER_CMD} docker logs ai-stack-deployer-test | tail -20
        ${DOCKER_CMD} docker stop ai-stack-deployer-test
        ${DOCKER_CMD} docker rm ai-stack-deployer-test
        error_exit "Health check failed"
    fi

    log_info "✓ Container healthy"

    # Cleanup
    ${DOCKER_CMD} docker stop ai-stack-deployer-test
    ${DOCKER_CMD} docker rm ai-stack-deployer-test

    log_info "✓ Local testing complete"
else
    log_warn "Skipping local test (--skip-test specified)"
fi

# Phase 4: Registry push (if specified)
if [ -n "${REGISTRY}" ]; then
    log_step "Phase 4: Pushing to Registry"

    FULL_IMAGE_NAME="${REGISTRY}/${IMAGE_NAME}:latest"

    log_info "Tagging image for registry: ${FULL_IMAGE_NAME}"
    ${DOCKER_CMD} docker tag "${IMAGE_NAME}:latest" "${FULL_IMAGE_NAME}"

    log_info "Pushing to registry..."
    ${DOCKER_CMD} docker push "${FULL_IMAGE_NAME}" || error_exit "Failed to push to registry"

    log_info "✓ Image pushed to registry"
    IMAGE_FOR_DOKPLOY="${FULL_IMAGE_NAME}"
else
    log_warn "No registry specified - Dokploy must have access to local Docker"
    IMAGE_FOR_DOKPLOY="${IMAGE_NAME}:latest"
fi

# Phase 5: Deploy to Dokploy
log_step "Phase 5: Deploying to Dokploy"

# Check if project exists
log_info "Checking for existing project..."
EXISTING_PROJECT=$(curl -s \
    -H "x-api-key: ${DOKPLOY_API_TOKEN}" \
    "${DOKPLOY_URL}/api/project.all" | \
    jq -r ".[]? | select(.name==\"${PROJECT_NAME}\") | .projectId" || echo "")

if [ -n "${EXISTING_PROJECT}" ]; then
    log_info "✓ Found existing project: ${EXISTING_PROJECT}"
    PROJECT_ID="${EXISTING_PROJECT}"
else
    log_info "Creating new project..."

    CREATE_PROJECT_RESPONSE=$(curl -s -X POST \
        -H "x-api-key: ${DOKPLOY_API_TOKEN}" \
        -H "Content-Type: application/json" \
        "${DOKPLOY_URL}/api/project.create" \
        -d "{
            \"name\": \"${PROJECT_NAME}\",
            \"description\": \"Self-service portal for deploying AI stacks\"
        }") || error_exit "Failed to create project"

    PROJECT_ID=$(echo "${CREATE_PROJECT_RESPONSE}" | jq -r '.project.projectId // empty')

    if [ -z "${PROJECT_ID}" ]; then
        log_error "API Response: ${CREATE_PROJECT_RESPONSE}"
        error_exit "Failed to extract project ID"
    fi

    log_info "✓ Created project: ${PROJECT_ID}"
fi

# Create/Update application
log_info "Creating application..."

# Prepare environment variables
ENV_VARS="DOKPLOY_URL=${DOKPLOY_URL}
DOKPLOY_API_TOKEN=${DOKPLOY_API_TOKEN}
PORT=3000
HOST=0.0.0.0
STACK_DOMAIN_SUFFIX=${STACK_DOMAIN_SUFFIX:-ai.flexinit.nl}
STACK_IMAGE=${STACK_IMAGE:-git.app.flexinit.nl/flexinit/agent-stack:latest}
RESERVED_NAMES=${RESERVED_NAMES:-admin,api,www,root,system,test,demo,portal}"

CREATE_APP_RESPONSE=$(curl -s -X POST \
    -H "x-api-key: ${DOKPLOY_API_TOKEN}" \
    -H "Content-Type: application/json" \
    "${DOKPLOY_URL}/api/application.create" \
    -d "{
        \"name\": \"${APP_NAME}\",
        \"projectId\": \"${PROJECT_ID}\",
        \"dockerImage\": \"${IMAGE_FOR_DOKPLOY}\",
        \"env\": \"${ENV_VARS}\"
    }") || error_exit "Failed to create application"

APP_ID=$(echo "${CREATE_APP_RESPONSE}" | jq -r '.application.applicationId // .applicationId // empty')

if [ -z "${APP_ID}" ]; then
    log_error "API Response: ${CREATE_APP_RESPONSE}"
    error_exit "Failed to extract application ID"
fi

log_info "✓ Created application: ${APP_ID}"

# Configure domain
log_info "Configuring domain: ${DOMAIN}"

curl -s -X POST \
    -H "x-api-key: ${DOKPLOY_API_TOKEN}" \
    -H "Content-Type: application/json" \
    "${DOKPLOY_URL}/api/domain.create" \
    -d "{
        \"domain\": \"${DOMAIN}\",
        \"applicationId\": \"${APP_ID}\",
        \"https\": true,
        \"port\": 3000
    }" || log_warn "Domain configuration may have failed (might already exist)"

log_info "✓ Domain configured"

# Deploy application
log_info "Triggering deployment..."

DEPLOY_RESPONSE=$(curl -s -X POST \
    -H "x-api-key: ${DOKPLOY_API_TOKEN}" \
    -H "Content-Type: application/json" \
    "${DOKPLOY_URL}/api/application.deploy" \
    -d "{
        \"applicationId\": \"${APP_ID}\"
    }") || error_exit "Failed to trigger deployment"

DEPLOY_ID=$(echo "${DEPLOY_RESPONSE}" | jq -r '.deploymentId // "unknown"')

log_info "✓ Deployment triggered: ${DEPLOY_ID}"
log_info "Monitor at: ${DOKPLOY_URL}/project/${PROJECT_ID}"

# Phase 6: Verification
log_step "Phase 6: Deployment Verification"

log_info "Waiting for deployment (60 seconds)..."
sleep 60

log_info "Testing health endpoint..."
if curl -sf "https://${DOMAIN}/health" > /dev/null 2>&1; then
    log_info "✓ Application is healthy at https://${DOMAIN}"

    # Get health status
    HEALTH_RESPONSE=$(curl -s "https://${DOMAIN}/health")
    echo "${HEALTH_RESPONSE}" | jq . || echo "${HEALTH_RESPONSE}"
else
    log_warn "Health check failed - deployment may still be in progress"
    log_info "Check status at: ${DOKPLOY_URL}/project/${PROJECT_ID}"
fi

# Save deployment record
log_step "Deployment Summary"

cat > "deployment-record-${TIMESTAMP}.txt" << EOF
Deployment Completed: $(date -Iseconds)
===========================================

Configuration:
- Project Name: ${PROJECT_NAME}
- Application Name: ${APP_NAME}
- Domain: https://${DOMAIN}
- Image: ${IMAGE_FOR_DOKPLOY}

Dokploy IDs:
- Project ID: ${PROJECT_ID}
- Application ID: ${APP_ID}
- Deployment ID: ${DEPLOY_ID}

Management:
- Dokploy Console: ${DOKPLOY_URL}/project/${PROJECT_ID}
- Application URL: https://${DOMAIN}
- Health Check: https://${DOMAIN}/health

Build Info:
- Timestamp: ${TIMESTAMP}
- Image ID: ${IMAGE_ID:-N/A}
- Image Size: ${IMAGE_SIZE:-N/A}

Status: SUCCESS
EOF

log_info "Deployment record saved: deployment-record-${TIMESTAMP}.txt"
log_info "Deployment log saved: ${LOG_FILE}"

echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}   Deployment Completed Successfully!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo -e "  🌐 Application URL: ${GREEN}https://${DOMAIN}${NC}"
echo -e "  ⚙️  Dokploy Console: ${DOKPLOY_URL}/project/${PROJECT_ID}"
echo -e "  📊 Health Check: https://${DOMAIN}/health"
echo ""

exit 0
