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

usage() {
  cat <<'HELP'
Uso:
  scripts/nuevo-cliente.sh <slug> [--template nombre] [--name "Nombre visible"] [--config archivo.json]

Ejemplos:
  scripts/nuevo-cliente.sh magali-15
  scripts/nuevo-cliente.sh magali-15 --template quince-elegante
  scripts/nuevo-cliente.sh boda-alma-mateo --name "Alma & Mateo"
  scripts/nuevo-cliente.sh magali-15 --config ~/Downloads/config.json

Que hace:
  - crea clientes/<slug>
  - copia la invitacion base o templates/<nombre>
  - aplica un config.json propio si se pasa --config
  - la invitacion queda publicada por el contenedor invitaciones-web
HELP
}

slug=""
display_name=""
config_path=""
template_name=""

while [[ $# -gt 0 ]]; do
  case "$1" in
    -h|--help)
      usage
      exit 0
      ;;
    --name)
      if [[ $# -lt 2 ]]; then
        echo "Error: --name requiere un valor." >&2
        exit 1
      fi
      display_name="$2"
      shift 2
      ;;
    --config)
      if [[ $# -lt 2 ]]; then
        echo "Error: --config requiere un archivo." >&2
        exit 1
      fi
      config_path="$2"
      shift 2
      ;;
    --template)
      if [[ $# -lt 2 ]]; then
        echo "Error: --template requiere un nombre." >&2
        exit 1
      fi
      template_name="$2"
      shift 2
      ;;
    *)
      if [[ -z "$slug" ]]; then
        slug="$1"
      else
        echo "Error: argumento inesperado: $1" >&2
        usage
        exit 1
      fi
      shift
      ;;
  esac
done

if [[ -z "$slug" ]]; then
  usage
  exit 1
fi

if [[ ! "$slug" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then
  echo "Error: el slug solo puede usar minusculas, numeros y guiones. Ej: magali-15" >&2
  exit 1
fi

root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
if [[ -n "$template_name" ]]; then
  if [[ ! "$template_name" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then
    echo "Error: template invalido: $template_name" >&2
    exit 1
  fi
  template_dir="$root_dir/templates/$template_name"
else
  template_dir="$root_dir/sitio-web"
fi
clients_dir="$root_dir/clientes"
client_dir="$clients_dir/$slug"

if [[ ! -d "$template_dir" ]]; then
  echo "Error: no existe la plantilla $template_dir" >&2
  echo "Templates disponibles:" >&2
  find "$root_dir/templates" -mindepth 1 -maxdepth 1 -type d -printf "  %f\n" 2>/dev/null >&2 || true
  exit 1
fi

if [[ -n "$display_name" ]] && ! command -v python3 >/dev/null 2>&1; then
  echo "Error: --name requiere python3 para editar config.json de forma segura." >&2
  exit 1
fi

if [[ -n "$config_path" ]]; then
  config_path="${config_path/#\~/$HOME}"
  if [[ ! -f "$config_path" ]]; then
    echo "Error: no existe el archivo de configuracion: $config_path" >&2
    exit 1
  fi
  if command -v python3 >/dev/null 2>&1; then
    python3 -m json.tool "$config_path" >/dev/null
  fi
fi

if [[ -e "$client_dir" ]]; then
  echo "Error: ya existe $client_dir" >&2
  exit 1
fi

mkdir -p "$clients_dir"
cp -a "$template_dir" "$client_dir"

if [[ -n "$config_path" ]]; then
  cp "$config_path" "$client_dir/config.json"
fi

if command -v python3 >/dev/null 2>&1; then
  client_config="$client_dir/config.json"
  tmp_config="$(mktemp)"
  CLIENT_SLUG="$slug" CLIENT_NAME="$display_name" python3 - "$client_config" "$tmp_config" <<'PY'
import json
import os
import re
import sys

source, target = sys.argv[1], sys.argv[2]
slug = os.environ["CLIENT_SLUG"]
name = os.environ["CLIENT_NAME"]
local_url_re = re.compile(r"^https?://(?:127\.0\.0\.1|localhost)(?::\d+)?(?:/.*)?$", re.IGNORECASE)


def is_local_or_empty_url(value):
    url = str(value or "").strip()
    return not url or bool(local_url_re.fullmatch(url))

with open(source, "r", encoding="utf-8") as fh:
    config = json.load(fh)

config["clientSlug"] = slug
admin_public_url = os.environ.get("ADMIN_PUBLIC_URL", "").strip().rstrip("/")
if admin_public_url and is_local_or_empty_url(config.get("backendApiUrl")):
    config["backendApiUrl"] = admin_public_url
else:
    config["backendApiUrl"] = config.get("backendApiUrl") or "http://127.0.0.1:8099"
clients_base = os.environ.get("CLIENTS_PUBLIC_URL", "").strip().rstrip("/")
if clients_base:
    public_url = f"{clients_base}/clientes/{slug}/"
    if is_local_or_empty_url(config.get("publicUrl")):
        config["publicUrl"] = public_url
    if is_local_or_empty_url(config.get("shareUrl")):
        config["shareUrl"] = public_url
if name:
    config["nombres"] = name
    config["seoTitle"] = f"{name} - Invitacion"
    config["footer"] = name

with open(target, "w", encoding="utf-8") as fh:
    json.dump(config, fh, ensure_ascii=False, indent=2)
    fh.write("\n")
PY
  mv "$tmp_config" "$client_config"
fi

if command -v python3 >/dev/null 2>&1; then
  CLIENT_DIR="$client_dir" ADMIN_SERVER="$root_dir/scripts/admin-server.py" python3 - <<'PY'
import importlib.util
import json
import os
from pathlib import Path

client_dir = Path(os.environ["CLIENT_DIR"])
admin_server = Path(os.environ["ADMIN_SERVER"])
config_path = client_dir / "config.json"

spec = importlib.util.spec_from_file_location("admin_server", admin_server)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

config = json.loads(config_path.read_text(encoding="utf-8"))
module.prepare_social_preview(client_dir, config)
config_path.write_text(json.dumps(config, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
PY
fi

cat <<EOF
Cliente creado.

Carpeta:
  clientes/$slug

Template:
  ${template_name:-sitio-web}

URL local:
  http://127.0.0.1:8092/clientes/$slug/

Siguientes pasos:
  1. Levantar los contenedores si no estan corriendo:
     docker compose up -d --build
  2. Para editar y guardar:
     scripts/admin-server.py
     http://127.0.0.1:8099/admin/
  3. Para ver la invitacion:
     http://127.0.0.1:8092/clientes/$slug/
EOF
