#!/usr/bin/env bash
set -euo pipefail

# Andoza self-hosted (one command). Official installers live on https://andoza.app
#   curl -fsSL https://andoza.app/install.sh | bash
#   curl -fsSL https://andoza.app/install.sh | bash -s -- --force
#
# Optional environment variables:
#   ANDOZA_BASE_URL   — source for docker-compose.yml (default https://andoza.app)
#   ANDOZA_GIT_URL    — application Git remote (default GitHub andoza-app)
#   ANDOZA_DIR        — install directory (default $HOME/andoza-app)
#   API_PUBLIC_URL    — sets BETTER_AUTH_URL (default http://127.0.0.1:7051)

ANDOZA_BASE_URL="${ANDOZA_BASE_URL:-https://andoza.app}"
ANDOZA_GIT_URL="${ANDOZA_GIT_URL:-https://github.com/OgabekYuldoshev/andoza-app.git}"
ANDOZA_DIR="${ANDOZA_DIR:-$HOME/andoza-app}"

FORCE=0
while [[ ${1:-} ]]; do
  case "$1" in
    --force) FORCE=1 ;;
    -h|--help)
      echo "Usage: curl -fsSL ${ANDOZA_BASE_URL}/install.sh | bash"
      echo "       $0 [--force]"
      echo "Env: ANDOZA_BASE_URL, ANDOZA_GIT_URL, ANDOZA_DIR, API_PUBLIC_URL, ANDOZA_*_IMAGE"
      exit 0
      ;;
    *) echo "Unknown option: $1" >&2; exit 1 ;;
  esac
  shift
done

need_cmd() {
  command -v "$1" >/dev/null 2>&1 || {
    echo "Required command not found: $1" >&2
    exit 1
  }
}

need_cmd docker
need_cmd git
need_cmd curl

if docker compose version >/dev/null 2>&1; then
  COMPOSE=(docker compose)
elif command -v docker-compose >/dev/null 2>&1; then
  COMPOSE=(docker-compose)
else
  echo "Docker Compose is required (docker compose or docker-compose)." >&2
  exit 1
fi

mkdir -p "$(dirname "$ANDOZA_DIR")"

if [[ -e "$ANDOZA_DIR" && ! -d "$ANDOZA_DIR/.git" ]]; then
  echo "Path exists and is not a git repo: $ANDOZA_DIR" >&2
  echo "Use another path: ANDOZA_DIR=/path ... or clear the directory." >&2
  exit 1
fi

if [[ ! -d "$ANDOZA_DIR/.git" ]]; then
  echo "Cloning $ANDOZA_GIT_URL -> $ANDOZA_DIR"
  git clone --depth 1 "$ANDOZA_GIT_URL" "$ANDOZA_DIR"
else
  echo "Repository found, updating: $ANDOZA_DIR"
  git -C "$ANDOZA_DIR" pull --ff-only || true
fi

ROOT="$ANDOZA_DIR"
cd "$ROOT"

echo "Downloading docker-compose.yml from ${ANDOZA_BASE_URL}/docker-compose.yml"
curl -fsSL "${ANDOZA_BASE_URL}/docker-compose.yml" -o docker-compose.yml

ENV_FILE="${ROOT}/.env"

if [[ -f "$ENV_FILE" && "$FORCE" -ne 1 ]]; then
  echo ".env already exists: $ENV_FILE"
  echo "Recreate: curl -fsSL ${ANDOZA_BASE_URL}/install.sh | bash -s -- --force"
  echo "Start stack: (cd \"$ROOT\" && ${COMPOSE[*]} --env-file \"$ENV_FILE\" up -d)"
  exit 0
fi

rand_hex() {
  if command -v openssl >/dev/null 2>&1; then
    openssl rand -hex "$1"
  else
    head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c "$1" || true
  fi
}

SECRET="$(rand_hex 32)"
GEN_TOKEN="$(rand_hex 24)"
if [[ -z "$SECRET" || ${#SECRET} -lt 16 ]]; then
  SECRET='dev-better-auth-secret-change-me'
fi
if [[ -z "$GEN_TOKEN" || ${#GEN_TOKEN} -lt 16 ]]; then
  GEN_TOKEN='dev-generator-token-change-me'
fi

API_PUBLIC_URL="${API_PUBLIC_URL:-http://127.0.0.1:7051}"

POSTGRES_USER="${POSTGRES_USER:-postgres}"
POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-andoza}"
POSTGRES_DB="${POSTGRES_DB:-andoza}"
MINIO_ROOT_USER="${MINIO_ROOT_USER:-minioadmin}"
MINIO_ROOT_PASSWORD="${MINIO_ROOT_PASSWORD:-andoza}"
DEFAULT_USER_EMAIL="${DEFAULT_USER_EMAIL:-admin@andoza.local}"
DEFAULT_USER_PASSWORD="${DEFAULT_USER_PASSWORD:-andoza}"
DEFAULT_USER_NAME="${DEFAULT_USER_NAME:-Admin}"
S3_BUCKET="${S3_BUCKET:-andoza}"

UPSERT_LINES=$(
  cat <<EOF
# Generated by ${ANDOZA_BASE_URL}/install.sh — change all default passwords for production

POSTGRES_USER=${POSTGRES_USER}
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
POSTGRES_DB=${POSTGRES_DB}

MINIO_ROOT_USER=${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
S3_BUCKET=${S3_BUCKET}

BETTER_AUTH_SECRET=${SECRET}
BETTER_AUTH_URL=${API_PUBLIC_URL}
GENERATOR_SERVICE_TOKEN=${GEN_TOKEN}

DEFAULT_USER_EMAIL=${DEFAULT_USER_EMAIL}
DEFAULT_USER_PASSWORD=${DEFAULT_USER_PASSWORD}
DEFAULT_USER_NAME=${DEFAULT_USER_NAME}

API_HOST_PORT=${API_HOST_PORT:-7050}
WEB_HOST_PORT=${WEB_HOST_PORT:-7051}
MINIO_API_HOST_PORT=${MINIO_API_HOST_PORT:-9000}
MINIO_CONSOLE_HOST_PORT=${MINIO_CONSOLE_HOST_PORT:-9001}
CORS_ORIGIN=${CORS_ORIGIN:-*}

# Registry images — set all three for: docker compose pull
# ANDOZA_API_IMAGE=ghcr.io/org/repo/api:latest
# ANDOZA_GENERATOR_IMAGE=ghcr.io/org/repo/generator:latest
# ANDOZA_WEB_IMAGE=ghcr.io/org/repo/web:latest
EOF
)

if [[ -f "$ENV_FILE" && "$FORCE" -eq 1 ]]; then
  BACKUP="${ENV_FILE}.bak.$(date +%Y%m%d%H%M%S)"
  cp "$ENV_FILE" "$BACKUP"
  echo "Backed up previous .env to $BACKUP"
fi

printf '%s\n' "$UPSERT_LINES" >"$ENV_FILE"
chmod 600 "$ENV_FILE" || true

echo "Wrote $ENV_FILE"
echo ""
echo "-------- Andoza Docker (default credentials) --------"
echo "PostgreSQL:  user=$POSTGRES_USER  password=$POSTGRES_PASSWORD  database=$POSTGRES_DB"
echo "MinIO S3:    user=$MINIO_ROOT_USER  password=$MINIO_ROOT_PASSWORD  bucket=$S3_BUCKET"
echo "MinIO UI:    http://127.0.0.1:${MINIO_CONSOLE_HOST_PORT:-9001}"
echo "Web UI:      http://127.0.0.1:${WEB_HOST_PORT:-7051}"
echo "API:         http://127.0.0.1:${API_HOST_PORT:-7050}"
echo "BETTER_AUTH_URL: ${API_PUBLIC_URL}"
echo "Admin user:  $DEFAULT_USER_EMAIL / $DEFAULT_USER_PASSWORD"
echo "--------------------------------------------------"
echo "Replace default passwords before production."
echo ""

registry_images_configured() {
  local api gen web
  api="$(grep -E '^[[:space:]]*ANDOZA_API_IMAGE=' "$ENV_FILE" 2>/dev/null | grep -Ev '^[[:space:]]*#' | head -1 | cut -d= -f2- | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr -d '"' || true)"
  gen="$(grep -E '^[[:space:]]*ANDOZA_GENERATOR_IMAGE=' "$ENV_FILE" 2>/dev/null | grep -Ev '^[[:space:]]*#' | head -1 | cut -d= -f2- | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr -d '"' || true)"
  web="$(grep -E '^[[:space:]]*ANDOZA_WEB_IMAGE=' "$ENV_FILE" 2>/dev/null | grep -Ev '^[[:space:]]*#' | head -1 | cut -d= -f2- | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr -d '"' || true)"
  [[ -n "$api" && -n "$gen" && -n "$web" ]]
}

if registry_images_configured; then
  echo "Registry images configured in .env — pulling..."
  "${COMPOSE[@]}" --env-file "$ENV_FILE" pull
  "${COMPOSE[@]}" --env-file "$ENV_FILE" up -d
else
  echo "Starting with local build (docker compose up -d --build)..."
  "${COMPOSE[@]}" --env-file "$ENV_FILE" up -d --build
fi

echo ""
echo "Status: ${COMPOSE[*]} ps"
"${COMPOSE[@]}" --env-file "$ENV_FILE" ps
