#!/bin/bash
# deploy.sh – Bygg och starta om recipe-app
# Kör från: /opt/containers/recipe-app/
# Kräver: .env-fil i samma mapp
#
# Användning:
#   ./deploy.sh                  – bygg allt (backend + flutter + importer)
#   ./deploy.sh --backend        – bygg bara backend (snabbast, ~2-3 min)
#   ./deploy.sh --flutter        – bygg bara flutter web-app
#   ./deploy.sh --importer       – bygg bara importer-microservice
#   ./deploy.sh --seed           – kör full seed på databasen (opt-in)
#   ./deploy.sh --skip-migration – hoppa över automatisk startup-migrering i recipe-api
#   ./deploy.sh --clean-database – kör migration och därefter underhålls-SQL som rensar data men behåller kategorier
#   ./deploy.sh --pull-always    – kontrollera uppdateringar för basimages
#   ./deploy.sh --backend --seed – kombinera flaggor fritt (git pull körs alltid)

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
START_TS="$(date +%s)"

# ── Flaggor ──────────────────────────────────────────────────────────────────
BUILD_BACKEND=false
BUILD_FLUTTER=false
BUILD_IMPORTER=false
RUN_SEED=false
RUN_CLEAN_DATABASE=false
SKIP_MIGRATION=false
PULL_IMAGES=false   # --pull=false är standard (snabbt)
BUILD_ALL=true      # om inga specifika tjänster anges, bygg allt

# ── Hjälpfunktioner ───────────────────────────────────────────────────────────
info() { echo "[INFO] $*"; }
warn() { echo "[WARN] $*"; }
fatal() { echo "[ERROR] $*"; exit 1; }

require_cmd() {
  command -v "$1" >/dev/null 2>&1 || fatal "Kommando saknas: $1"
}

read_env_value() {
  local key="$1"
  local line
  line=$(grep -E "^${key}=" .env | tail -n 1 || true)
  line="${line#*=}"
  line="${line%\"}"
  line="${line#\"}"
  line="${line%\'}"
  line="${line#\'}"
  printf '%s' "$line"
}

wait_for_backend_prisma() {
  info "Väntar på att backend är redo för Prisma-kommandon..."
  for i in $(seq 1 30); do
    if docker exec recipe-api sh -lc "test -f /app/prisma/schema.prisma" >/dev/null 2>&1; then
      return 0
    fi
    info "  ...försök $i/30"
    sleep 2
  done
  return 1
}

wait_for_db() {
  local root_password="$1"
  info "Väntar på att databasen är redo..."
  for i in $(seq 1 30); do
    if docker exec recipe-db mariadb-admin ping -h 127.0.0.1 -uroot -p"$root_password" --silent 2>/dev/null; then
      return 0
    fi
    info "  ...försök $i/30"
    sleep 2
  done
  return 1
}

run_prisma_migrate_deploy() {
  local output
  info "Kör Prisma-migrationer (deploy)..."
  info "  ▶ Kör: npx prisma migrate deploy"

  if ! output=$(docker exec recipe-api sh -lc "cd /app && npx prisma migrate deploy --schema prisma/schema.prisma" 2>&1); then
    echo "$output"
    fatal "Prisma migration misslyckades."
  fi

  echo "$output"

  if echo "$output" | grep -qi "No pending migrations"; then
    info "Migration-status: inga väntande migrationer."
  elif echo "$output" | grep -qi "Applying migration"; then
    info "Migration-status: minst en migration applicerades."
  else
    warn "Migration-status: kunde inte avgöra om nya migrationer applicerades."
  fi

  info "Migrationer slutförda utan fel."
}

run_prisma_generate() {
  info "Uppdaterar Prisma Client..."
  docker exec recipe-api sh -lc "cd /app && npx prisma generate --schema prisma/schema.prisma"
}

for arg in "$@"; do
  case "$arg" in
    --backend)         BUILD_BACKEND=true;  BUILD_ALL=false ;;
    --flutter)         BUILD_FLUTTER=true;  BUILD_ALL=false ;;
    --importer)        BUILD_IMPORTER=true; BUILD_ALL=false ;;
    --seed)            RUN_SEED=true ;;
    --skip-migration)  SKIP_MIGRATION=true ;;
    --clean-database)  RUN_CLEAN_DATABASE=true; BUILD_BACKEND=true; BUILD_ALL=false ;;
    --pull-always)     PULL_IMAGES=true ;;
    --help|-h)
      sed -n '/^# Användning:/,/^[^#]/p' "$0" | grep '^#' | sed 's/^# \?//'
      exit 0
      ;;
    *) fatal "Okänd flagga: $arg (--help för hjälp)" ;;
  esac
done

if [ "$BUILD_ALL" = true ]; then
  BUILD_BACKEND=true
  BUILD_FLUTTER=true
  BUILD_IMPORTER=true
fi

# Om databasrensning begärs, stäng av automigrering i containern för att undvika dubbelkörning.
if [ "$RUN_CLEAN_DATABASE" = true ]; then
  SKIP_MIGRATION=true
fi

# ── Validering ────────────────────────────────────────────────────────────────
[ -f ".env" ] || fatal ".env saknas. Kör: cp .env.example .env && nano .env"

require_cmd git
require_cmd docker

if [ "$BUILD_BACKEND" = true ] || [ "$RUN_SEED" = true ] || [ "$RUN_CLEAN_DATABASE" = true ]; then
  require_cmd grep
fi

export SKIP_MIGRATION
COMPOSE_CMD=(docker compose -f compose.yml -f compose.flutter.yml)

# ── Git pull ──────────────────────────────────────────────────────────────────
info "Hämtar senaste kod (recipe-app)..."
git pull origin main

if [ -d "$SCRIPT_DIR/../microservice-importer/.git" ]; then
  info "Hämtar senaste kod (microservice-importer)..."
  (cd "$SCRIPT_DIR/../microservice-importer" && git pull origin main)
else
  warn "microservice-importer repo hittades inte på förväntad path, hoppar över git pull där."
fi

# ── Bygger valda tjänster ─────────────────────────────────────────────────────
SERVICES=()
[ "$BUILD_BACKEND" = true ]  && SERVICES+=(recipe-api)
[ "$BUILD_FLUTTER" = true ]  && SERVICES+=(recipe-flutter)
[ "$BUILD_IMPORTER" = true ] && SERVICES+=(importer-api)

if [ "${#SERVICES[@]}" -eq 0 ]; then
  info "Bygger: alla tjänster..."
else
  info "Bygger: ${SERVICES[*]}"
fi

if [ "$PULL_IMAGES" = true ]; then
  info "(kontrollerar uppdateringar för basimages...)"
  "${COMPOSE_CMD[@]}" build "${SERVICES[@]}"
else
  "${COMPOSE_CMD[@]}" build --pull=false "${SERVICES[@]}"
fi

info "Startar tjänster..."
"${COMPOSE_CMD[@]}" up -d

# ── Databasrensning (opt-in) ──────────────────────────────────────────────────
if [ "$RUN_CLEAN_DATABASE" = true ]; then
  CLEAN_SQL_FILE="backend/prisma/maintenance/clean-database.sql"

  wait_for_backend_prisma || fatal "Backend blev inte redo för Prisma-kommandon i tid."

  info "Säkerställer uppdaterat databasschema före rensning..."
  run_prisma_migrate_deploy

  [ -f "$CLEAN_SQL_FILE" ] || fatal "Saknar $CLEAN_SQL_FILE"

  MARIADB_ROOT_PASSWORD="$(read_env_value MARIADB_ROOT_PASSWORD)"
  MARIADB_DATABASE="$(read_env_value MARIADB_DATABASE)"

  [ -n "$MARIADB_ROOT_PASSWORD" ] || fatal "MARIADB_ROOT_PASSWORD saknas i .env"
  [ -n "$MARIADB_DATABASE" ] || fatal "MARIADB_DATABASE saknas i .env"

  info "Kör databasrensning från $CLEAN_SQL_FILE ..."
  docker exec -i recipe-db mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" < "$CLEAN_SQL_FILE"
  info "Databasrensning klar (kategorier bevarade enligt SQL-filen)."

  run_prisma_generate
fi

# Visa Prisma Client-output även vid vanlig deploy när automigrering är aktiv.
if [ "$RUN_CLEAN_DATABASE" = false ] && [ "$SKIP_MIGRATION" = false ] && [ "$BUILD_BACKEND" = true ]; then
  wait_for_backend_prisma || fatal "Backend blev inte redo för Prisma-kommandon i tid."
  run_prisma_generate
fi

# ── Seed (opt-in) ─────────────────────────────────────────────────────────────
if [ "$RUN_SEED" = true ]; then
  MARIADB_ROOT_PASSWORD="$(read_env_value MARIADB_ROOT_PASSWORD)"
  MARIADB_DATABASE="$(read_env_value MARIADB_DATABASE)"

  [ -n "$MARIADB_ROOT_PASSWORD" ] || fatal "MARIADB_ROOT_PASSWORD saknas i .env"
  [ -n "$MARIADB_DATABASE" ] || fatal "MARIADB_DATABASE saknas i .env"

  wait_for_db "$MARIADB_ROOT_PASSWORD" || fatal "Databasen blev inte redo i tid."

  if [ -f "db/seeds/seed_all.sql" ]; then
    docker exec -i recipe-db mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" < db/seeds/seed_all.sql
    info "Full seed klar."
  else
    warn "Ingen db/seeds/seed_all.sql hittades — hoppar över seed."
  fi
fi

info "Status:"
"${COMPOSE_CMD[@]}" ps

END_TS="$(date +%s)"
DURATION="$((END_TS - START_TS))"
info "Deploy klart på ${DURATION}s."
