services:
  # ─── Postgres ────────────────────────────────────────────────────────────────
  ec-db:
    image: postgres:15-alpine
    container_name: ec-db
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-your-super-secret-password}
      POSTGRES_DB: ${POSTGRES_DB:-postgres}
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
    command: postgres -c wal_level=logical -c max_replication_slots=10 -c max_wal_senders=10
    volumes:
      - ec-db-data:/var/lib/postgresql/data
      - ./supabase/migrations:/docker-entrypoint-initdb.d:ro
    ports:
      # Avoid Windows dynamic/excluded ranges (5435 often blocked); host tools can use 54350
      - "54350:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
      interval: 5s
      timeout: 5s
      retries: 10

  # ─── PostgREST ──────────────────────────────────────────────────────────────
  ec-rest:
    image: postgrest/postgrest:v12.2.0
    container_name: ec-rest
    restart: unless-stopped
    depends_on:
      ec-db:
        condition: service_healthy
    environment:
      PGRST_DB_URI: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-your-super-secret-password}@ec-db:5432/${POSTGRES_DB:-postgres}
      PGRST_DB_SCHEMA: public
      PGRST_DB_ANON_ROLE: anon
      PGRST_JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-token-with-at-least-32-characters}
      PGRST_DB_USE_LEGACY_GUCS: "false"
      PGRST_APP_SETTINGS_JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-token-with-at-least-32-characters}
      PGRST_APP_SETTINGS_JWT_EXP: "3600"

  # ─── Supabase Auth (GoTrue) ─────────────────────────────────────────────────
  ec-auth:
    image: supabase/gotrue:v2.158.1
    container_name: ec-auth
    # Valid FQDN for SMTP EHLO/HELO — avoids MailHog rejecting with "Invalid HELO name"
    hostname: auth.localhost
    restart: unless-stopped
    depends_on:
      ec-db:
        condition: service_healthy
    environment:
      GOTRUE_API_HOST: 0.0.0.0
      GOTRUE_API_PORT: 9999
      # Kong on host:8002 — FQDN for SMTP EHLO; hardcoded so .env cannot set http://localhost (breaks recovery links + HELO).
      API_EXTERNAL_URL: http://host.docker.internal:8002
      GOTRUE_DB_DRIVER: postgres
      GOTRUE_DB_DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-your-super-secret-password}@ec-db:5432/${POSTGRES_DB:-postgres}?search_path=auth
      # Browser app origin — align with FRONTEND_PORT if SITE_URL is unset (see .env)
      GOTRUE_SITE_URL: ${SITE_URL:-http://localhost:${FRONTEND_PORT:-8098}}
      GOTRUE_JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-token-with-at-least-32-characters}
      GOTRUE_JWT_EXP: 3600
      GOTRUE_DISABLE_SIGNUP: "false"
      GOTRUE_EXTERNAL_EMAIL_ENABLED: "true"
      GOTRUE_MAILER_AUTOCONFIRM: "true"
      DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-your-super-secret-password}@ec-db:5432/${POSTGRES_DB:-postgres}?search_path=auth
      # Always MailHog for GoTrue — do not inherit SMTP_HOST from .env (may point at production SMTP and break HELO).
      GOTRUE_SMTP_HOST: ec-mailhog
      GOTRUE_SMTP_PORT: "1025"
      GOTRUE_SMTP_ADMIN_EMAIL: ${SMTP_ADMIN_EMAIL:-admin@example.com}
      GOTRUE_SMTP_SENDER_NAME: ${SMTP_SENDER_NAME:-Email Campaigner}
      GOTRUE_MAILER_URLPATHS_INVITE: /auth/v1/verify
      GOTRUE_MAILER_URLPATHS_CONFIRMATION: /auth/v1/verify
      GOTRUE_MAILER_URLPATHS_RECOVERY: /auth/v1/verify
      GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: /auth/v1/verify
    ports:
      - "9998:9999"

  # ─── Supabase Realtime ──────────────────────────────────────────────────────
  ec-realtime:
    image: supabase/realtime:v2.34.47
    container_name: ec-realtime
    restart: unless-stopped
    depends_on:
      ec-db:
        condition: service_healthy
    environment:
      PORT: 4000
      DB_HOST: ec-db
      DB_PORT: 5432
      DB_USER: ${POSTGRES_USER:-postgres}
      DB_PASSWORD: ${POSTGRES_PASSWORD:-your-super-secret-password}
      DB_NAME: ${POSTGRES_DB:-postgres}
      DB_AFTER_CONNECT_QUERY: "SET search_path TO _realtime"
      DB_ENC_KEY: supabaserealtime
      API_JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-token-with-at-least-32-characters}
      FLY_ALLOC_ID: fly123
      FLY_APP_NAME: realtime
      APP_NAME: realtime
      SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3bhZGKvIAZ
      ERL_AFLAGS: -proto_dist inet_tcp
      ENABLE_TAILSCALE: "false"
      DNS_NODES: "''"
      RLIMIT_NOFILE: "524288"

  # ─── Kong API Gateway ───────────────────────────────────────────────────────
  ec-kong:
    image: kong:2.8.1
    container_name: ec-kong
    restart: unless-stopped
    depends_on:
      ec-db:
        condition: service_healthy
    environment:
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: /var/lib/kong/kong.yml
      KONG_DNS_ORDER: LAST,A,CNAME
      # Trust Docker network so X-Forwarded-Host from ec-edge (full host:port) reaches GoTrue.
      KONG_TRUSTED_IPS: "0.0.0.0/0,::/0"
      KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth
      KONG_NGINX_PROXY_PROXY_BUFFER_SIZE: 160k
      KONG_NGINX_PROXY_PROXY_BUFFERS: "64 160k"
    volumes:
      - ./supabase/kong.yml:/var/lib/kong/kong.yml:ro
    ports:
      - "8446:8443"

  # ─── Nginx edge — host :8002 (fixes X-Forwarded-Host port for GoTrue emails) ─
  ec-edge:
    image: nginx:alpine
    container_name: ec-edge
    restart: unless-stopped
    depends_on:
      - ec-kong
    ports:
      - "8002:8000"
    volumes:
      - ./nginx/kong-edge.conf:/etc/nginx/conf.d/default.conf:ro

  # ─── pg-meta ────────────────────────────────────────────────────────────────
  ec-meta:
    image: supabase/postgres-meta:v0.84.2
    container_name: ec-meta
    restart: unless-stopped
    depends_on:
      ec-db:
        condition: service_healthy
    environment:
      PG_META_PORT: 8080
      PG_META_DB_HOST: ec-db
      PG_META_DB_PORT: 5432
      PG_META_DB_NAME: ${POSTGRES_DB:-postgres}
      PG_META_DB_USER: ${POSTGRES_USER:-postgres}
      PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD:-your-super-secret-password}
    ports:
      - "8082:8080"

  # ─── Supabase Studio ────────────────────────────────────────────────────────
  ec-studio:
    image: supabase/studio:latest
    container_name: ec-studio
    restart: unless-stopped
    depends_on:
      ec-db:
        condition: service_healthy
    environment:
      STUDIO_PG_META_URL: http://ec-meta:8080
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-your-super-secret-password}
      DEFAULT_ORGANIZATION_NAME: ${DEFAULT_ORGANIZATION:-Email Campaigner}
      DEFAULT_PROJECT_NAME: ${DEFAULT_PROJECT:-email-campaigner}
      SUPABASE_URL: http://ec-kong:8000
      SUPABASE_PUBLIC_URL: ${SUPABASE_PUBLIC_URL:-http://localhost:8002}
      SUPABASE_ANON_KEY: ${ANON_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTY0MTc2OTIwMCwiZXhwIjoxOTU3MzI1MjAwfQ.OARdq5jInfHTCanAPseUjrzVCfwtcEwhoemDqEmFTEY}
      SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE5NTczMjUyMDB9.kd_LC3bXxpaQhlRpxnDl9OABszXZ0tslEH9JfN51mYw}
    ports:
      - "3103:3000"

  # ─── MailHog (local SMTP catcher) ───────────────────────────────────────────
  ec-mailhog:
    image: mailhog/mailhog:latest
    container_name: ec-mailhog
    restart: unless-stopped
    ports:
      - "1025:1025"
      - "8025:8025"

  # ─── API Backend ────────────────────────────────────────────────────────────
  ec-api:
    build:
      context: ./api
      dockerfile: Dockerfile
    container_name: ec-api
    restart: unless-stopped
    depends_on:
      ec-db:
        condition: service_healthy
      ec-mailhog:
        condition: service_started
    env_file:
      - .env
    environment:
      NODE_ENV: ${NODE_ENV:-development}
      PORT: 3002
      FRONTEND_PORT: ${FRONTEND_PORT:-8098}
      DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-your-super-secret-password}@ec-db:5432/${POSTGRES_DB:-postgres}
      SUPABASE_URL: http://ec-kong:8000
      SUPABASE_SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE5NTczMjUyMDB9.kd_LC3bXxpaQhlRpxnDl9OABszXZ0tslEH9JfN51mYw}
      JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-token-with-at-least-32-characters}
      APP_BASE_URL: ${APP_BASE_URL:-http://localhost:3002}
      MAILHOG_HOST: ec-mailhog
      MAILHOG_PORT: 1025
    ports:
      - "3002:3002"
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3002/health || exit 1"]
      interval: 15s
      timeout: 5s
      retries: 5

  # ─── Frontend ────────────────────────────────────────────────────────────────
  ec-frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      args:
        VITE_SUPABASE_URL: ${VITE_SUPABASE_URL:-http://localhost:8002}
        VITE_SUPABASE_ANON_KEY: ${ANON_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTY0MTc2OTIwMCwiZXhwIjoxOTU3MzI1MjAwfQ.OARdq5jInfHTCanAPseUjrzVCfwtcEwhoemDqEmFTEY}
        VITE_API_URL: ${VITE_API_URL:-http://localhost:3002}
    container_name: ec-frontend
    restart: unless-stopped
    depends_on:
      - ec-api
    ports:
      - "${FRONTEND_PORT:-8098}:5173"

volumes:
  ec-db-data:
