services:
  briefs-db:
    image: postgres:16-alpine
    container_name: city_briefs_db
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${BRIEF_DB_USER:-brief_user}
      POSTGRES_PASSWORD: ${BRIEF_DB_PASSWORD:-change_this_password}
      POSTGRES_DB: city_briefs_ops
    volumes:
      - briefs_db_data:/var/lib/postgresql/data
    networks:
      - brief-internal
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${BRIEF_DB_USER:-brief_user} -d city_briefs_ops"]
      interval: 10s
      timeout: 5s
      retries: 10

  briefs-web:
    image: nginx:1.27-alpine
    container_name: city_briefs_web
    restart: unless-stopped
    volumes:
      - ${BRIEF_OUTPUT_HOST_DIR:-./brief-output}:/usr/share/nginx/html/brief:ro
      - ./docker/nginx-brief.conf:/etc/nginx/conf.d/default.conf:ro
    ports:
      - "8085:80"
    networks:
      - brief-internal
    healthcheck:
      test: ["CMD-SHELL", "wget -q -O /dev/null http://127.0.0.1/brief/og-cover.jpg"]
      interval: 10s
      timeout: 5s
      retries: 10

  city-briefing-agent:
    build:
      context: .
      dockerfile: docker/Dockerfile
    container_name: city-briefing-agent
    restart: unless-stopped
    depends_on:
      briefs-db:
        condition: service_healthy
      briefs-web:
        condition: service_healthy
    environment:
      APP_ENV: ${APP_ENV:-production}
      APP_HOST: ${APP_HOST:-0.0.0.0}
      APP_PORT: ${APP_PORT:-8000}
      APP_VERSION: ${APP_VERSION:-12.0.0}
      BRIEF_SERVICE_API_KEYS: ${BRIEF_SERVICE_API_KEYS}
      APP_TIMEZONE: ${APP_TIMEZONE:-America/Los_Angeles}
      DAYS_TO_SHOW: ${DAYS_TO_SHOW:-7}
      SHOW_CONCURRENCY: ${SHOW_CONCURRENCY:-3}

      DATABASE_URL: postgresql://${BRIEF_DB_USER:-brief_user}:${BRIEF_DB_PASSWORD:-change_this_password}@briefs-db:5432/city_briefs_ops

      SCC_BASE_URL: ${SCC_BASE_URL:-https://planner.maxify.it}
      SCC_API_KEY: ${SCC_API_KEY}

      PERPLEXITY_API_KEY: ${PERPLEXITY_API_KEY}
      PERPLEXITY_MODEL: ${PERPLEXITY_MODEL:-sonar-pro}
      PERPLEXITY_TIMEOUT: ${PERPLEXITY_TIMEOUT:-60}
      PERPLEXITY_MAX_CONCURRENCY: ${PERPLEXITY_MAX_CONCURRENCY:-2}

      # ── OpenAI (fact-check + 20-idea generation) ────────────────────────────
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      OPENAI_FACT_CHECK_MODEL: ${OPENAI_FACT_CHECK_MODEL:-gpt-4o}
      OPENAI_GENERATION_MODEL: ${OPENAI_GENERATION_MODEL:-gpt-4o}
      OPENAI_TIMEOUT: ${OPENAI_TIMEOUT:-60}
      OPENAI_MAX_CONCURRENCY: ${OPENAI_MAX_CONCURRENCY:-2}

      # ── Anthropic ────────────────────────────────────────────────────────
      ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
      ANTHROPIC_RANKING_MODEL: ${ANTHROPIC_RANKING_MODEL:-claude-sonnet-4-6}
      ANTHROPIC_TIMEOUT: ${ANTHROPIC_TIMEOUT:-90}
      ANTHROPIC_MAX_CONCURRENCY: ${ANTHROPIC_MAX_CONCURRENCY:-2}

      # ── YouTube (recent uploads + transcripts) ──────────────────────────
      YOUTUBE_API_KEY: ${YOUTUBE_API_KEY}
      YOUTUBE_CHANNEL_ID: ${YOUTUBE_CHANNEL_ID:-UCQTmZczX5kGRgaPIgpy6CyQ}
      YOUTUBE_MAX_VIDEOS: ${YOUTUBE_MAX_VIDEOS:-5}
      YOUTUBE_TIMEOUT: ${YOUTUBE_TIMEOUT:-30}
      YOUTUBE_MAX_CONCURRENCY: ${YOUTUBE_MAX_CONCURRENCY:-2}

      VOICE_PROFILES_DIR: /app/voice_profiles
      DEFAULT_COMEDIAN_ID: ${DEFAULT_COMEDIAN_ID:-max-amini}

      PUBLIC_BASE_URL: ${PUBLIC_BASE_URL:-http://localhost:8085/brief}
      INTERNAL_PUBLIC_BASE_URL: ${INTERNAL_PUBLIC_BASE_URL:-http://briefs-web/brief}
      BRIEF_OUTPUT_DIR: /brief-output
      OG_COVER_URL: ${OG_COVER_URL:-http://localhost:8085/brief/og-cover.jpg}
      INTERNAL_OG_COVER_URL: ${INTERNAL_OG_COVER_URL:-http://briefs-web/brief/og-cover.jpg}
      OG_SITE_NAME: ${OG_SITE_NAME:-Max Amini}

      SLACK_ALERTS_CHANNEL: ${SLACK_ALERTS_CHANNEL:-#city-brief-alerts}
    ports:
      - "8002:8000"
    volumes:
      # Code: live-reload in dev; the bind-mount is fine in prod too because
      # deploys use `git pull` then `docker compose up -d --build`.
      - ./app:/app/app:ro
      - ./migrations:/app/migrations:ro
      - ./voice_profiles:/app/voice_profiles:ro
      # Production sets BRIEF_OUTPUT_HOST_DIR=/var/www/just2done.com/brief.
      # Local development defaults to ./brief-output. A bind mount is required
      # so generated HTML is served by the host's public web server.
      - ${BRIEF_OUTPUT_HOST_DIR:-./brief-output}:/brief-output
    networks:
      - brief-internal
      - proxy      # external — join prod n8n's network so prod can reach us by service name
    healthcheck:
      test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://localhost:8000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s

volumes:
  briefs_db_data:

networks:
  brief-internal:
    driver: bridge
  proxy:
    # Production: must already exist on the VPS host (the prod n8n instance
    # joins the same external network, so http://city-briefing-agent:8000
    # resolves from n8n HTTP nodes). `docker network create proxy` once.
    # Local dev: comment out the next two lines so compose creates it.
    external: true
