# version: '3.8'

services:
  web:
    build: .
    container_name: hwPaymentApi
    ports:
      - "${APP_PORT}:${FAST_API_PORT}"
    env_file:
      - .env
    depends_on:
      db:
        condition: service_healthy
      rabbitmq:
        condition: service_healthy
      redis:
        condition: service_healthy
      kafka:
        condition: service_healthy
    volumes:
      - .:/app
      - uploads_data:/app/uploads
      # PRD-006: MaxMind GeoLite2-City database (read-only).
      # Download via: MAXMIND_LICENSE_KEY=<key> ./scripts/download_geoip_db.sh
      - ./geoip/GeoLite2-City.mmdb:/app/geoip/GeoLite2-City.mmdb:ro
    networks:
      - fastapi_network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:${FAST_API_PORT}/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  db:
    image: postgres:15-alpine
    container_name: fastapi_db
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
    ports:
      - "${DB_PORT}:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - fastapi_network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-fastapi_db}"]
      interval: 10s
      timeout: 5s
      retries: 5

  # RabbitMQ - Message Broker for Celery
  rabbitmq:
    image: rabbitmq:3.12-management-alpine
    container_name: hwPaymentRabbitmq
    environment:
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
      RABBITMQ_DEFAULT_VHOST: /
    ports:
      - "5673:5672"    # AMQP port
      - "15673:15672"  # Management UI port
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
    networks:
      - fastapi_network
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis - Result Backend and Cache for Celery
  redis:
    image: redis:7-alpine
    container_name: hwPaymentRedis
    ports:
      - "6380:6379"
    volumes:
      - redis_data:/data
    networks:
      - fastapi_network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    command: redis-server --appendonly yes

  # Celery Worker - Background Task Processing
  celery_worker:
    build: .
    container_name: hwPaymentCeleryWorker
    command: celery -A src.worker.celery_app:celery_app worker --loglevel=info
    env_file:
      - .env
    depends_on:
      db:
        condition: service_healthy
      rabbitmq:
        condition: service_healthy
      redis:
        condition: service_healthy
    volumes:
      - .:/app
      - uploads_data:/app/uploads
      # PRD-006: MaxMind GeoLite2-City database (read-only, same file as web service)
      - ./geoip/GeoLite2-City.mmdb:/app/geoip/GeoLite2-City.mmdb:ro
    networks:
      - fastapi_network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "celery", "-A", "src.worker.celery_app:celery_app", "inspect", "ping"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # Celery Beat - Scheduled Task Dispatcher (PRD-006: nightly token cleanup)
  celery_beat:
    build: .
    container_name: hwPaymentCeleryBeat
    command: celery -A src.worker.celery_app:celery_app beat --loglevel=info --scheduler celery.beat:PersistentScheduler
    env_file:
      - .env
    depends_on:
      db:
        condition: service_healthy
      rabbitmq:
        condition: service_healthy
      redis:
        condition: service_healthy
    volumes:
      - .:/app
      - uploads_data:/app/uploads
      - ./geoip/GeoLite2-City.mmdb:/app/geoip/GeoLite2-City.mmdb:ro
    networks:
      - fastapi_network
    restart: unless-stopped
  
  zookeeper:
    image: confluentinc/cp-zookeeper:7.4.0
    hostname: zookeeper
    container_name: payment-zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    volumes:
      - zookeeper-data:/var/lib/zookeeper/data
      - zookeeper-logs:/var/lib/zookeeper/log
    # healthcheck:
    #   test: ["CMD", "bash", "-c", "zookeeper-shell.sh localhost:2181 <<< 'ruok' | grep imok"]
    #   interval: 5s
    #   timeout: 5s
    #   retries: 5
    #   start_period: 10s
    networks:
      - fastapi_network

  kafka:
    image: confluentinc/cp-kafka:7.4.0
    hostname: kafka
    container_name: payment-kafka
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"
      - "9101:9101"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_JMX_PORT: 9101
      KAFKA_JMX_HOSTNAME: localhost
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
      KAFKA_NUM_PARTITIONS: 3
      KAFKA_DEFAULT_REPLICATION_FACTOR: 1
    volumes:
      - kafka-data:/var/lib/kafka/data
    healthcheck:
      test: ["CMD", "bash", "-c", "/usr/bin/kafka-topics --bootstrap-server kafka:29092 --list || exit 1"]
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 15s
    networks:
      - fastapi_network

  kafka-ui:
    image: provectuslabs/kafka-ui:latest
    container_name: payment-kafka-ui
    depends_on:
      - kafka
    ports:
      - "8080:8080"
    environment:
      KAFKA_CLUSTERS_0_NAME: payment-gateway
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:29092
      KAFKA_CLUSTERS_0_ZOOKEEPER: zookeeper:2181
    networks:
      - fastapi_network

  # Uncomment to add pgAdmin for database management
  # pgadmin:
  #   image: dpage/pgadmin4:latest
  #   environment:
  #     PGADMIN_DEFAULT_EMAIL: admin@example.com
  #     PGADMIN_DEFAULT_PASSWORD: admin
  #   ports:
  #     - "5050:80"
  #   depends_on:
  #     - db
  #   networks:
  #     - fastapi_network

volumes:
  postgres_data:
    driver: local
  uploads_data:
    driver: local
  rabbitmq_data:
    driver: local
  redis_data:
    driver: local
  zookeeper-data:
    driver: local
  zookeeper-logs:
    driver: local
  kafka-data:
    driver: local

networks:
  fastapi_network:
    driver: bridge
