services:
    # ==============================================================================
    # LIDIFY CORE APPLICATION
    # ==============================================================================

    # Backend API - Your Lidify Express.js server
    backend:
        build:
            context: ./backend
            dockerfile: Dockerfile
        container_name: lidify_backend
        environment:
            # Database
            DATABASE_URL: postgresql://${POSTGRES_USER:-lidifydb}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-lidify}
            POSTGRES_USER: ${POSTGRES_USER:-lidifydb}
            POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
            POSTGRES_DB: ${POSTGRES_DB:-lidify}
            REDIS_URL: redis://redis:6379

            # Server config
            PORT: 3006
            NODE_ENV: ${NODE_ENV:-production}
            SESSION_SECRET: ${SESSION_SECRET:-changeme-generate-secure-key}
            SETTINGS_ENCRYPTION_KEY: ${SETTINGS_ENCRYPTION_KEY:-}

            # Music library (required)
            # IMPORTANT: Inside Docker, music is always at /music (mounted from host MUSIC_PATH)
            # Don't use ${MUSIC_PATH} here as it contains the host path, not container path
            MUSIC_PATH: /music
            TRANSCODE_CACHE_PATH: /app/cache/transcodes
            TRANSCODE_CACHE_MAX_GB: ${TRANSCODE_CACHE_MAX_GB:-10}

            # CORS
            ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-http://localhost:3000,http://localhost:3030}

            # Lidarr webhook callback URL - how Lidarr can reach Lidify
            # Use backend:3006 for same-network communication, or external IP:3030 for external Lidarr
            LIDIFY_CALLBACK_URL: ${LIDIFY_CALLBACK_URL:-http://backend:3006}
            # Debug: enable extra podcast stream/cache logging
            PODCAST_DEBUG: ${PODCAST_DEBUG:-0}
        volumes:
            - ${MUSIC_PATH:-./music}:/music
            - backend_cache:/app/cache
            - backend_logs:/app/logs
        ports:
            - "${BACKEND_PORT:-3006}:3006"
        depends_on:
            postgres:
                condition: service_healthy
            redis:
                condition: service_healthy
        restart: unless-stopped
        healthcheck:
            test: ["CMD", "node", "healthcheck.js"]
            interval: 30s
            timeout: 10s
            retries: 3

    # Frontend Web UI - Your Lidify Next.js app
    frontend:
        build:
            context: ./frontend
            dockerfile: Dockerfile
            args:
                # Prefer relative /api requests (Next.js rewrites will proxy to backend).
                # If you need a custom API URL, set NEXT_PUBLIC_API_URL explicitly.
                NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-}
        container_name: lidify_frontend
        environment:
            NODE_ENV: ${NODE_ENV:-production}
            # Used by next.config.ts rewrites() inside the container.
            # IMPORTANT: "localhost" inside a container refers to itself, not the host.
            BACKEND_URL: ${BACKEND_URL:-http://backend:3006}
            # Exposed to the browser; leave empty by default so the app uses /api via rewrites.
            NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-}
        ports:
            - "${FRONTEND_PORT:-3030}:3030"
        depends_on:
            - backend
        restart: unless-stopped
        healthcheck:
            test: ["CMD", "node", "healthcheck.js"]
            interval: 30s
            timeout: 10s
            retries: 3

    # ==============================================================================
    # INFRASTRUCTURE (Database & Cache)
    # ==============================================================================

    postgres:
        image: postgres:16-alpine
        container_name: lidify_db
        environment:
            POSTGRES_USER: ${POSTGRES_USER:-lidifydb}
            POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
            POSTGRES_DB: ${POSTGRES_DB:-lidify}
        volumes:
            - postgres_data:/var/lib/postgresql/data
        ports:
            - "${POSTGRES_PORT:-5432}:5432"
        restart: unless-stopped
        healthcheck:
            # IMPORTANT:
            # pg_isready defaults to connecting to a database with the same name as the user.
            # Our default user is "lidifydb" but default database is "lidify",
            # so without -d this will spam logs with: FATAL: database "lidifydb" does not exist
            test:
                [
                    "CMD-SHELL",
                    "pg_isready -U ${POSTGRES_USER:-lidifydb} -d ${POSTGRES_DB:-lidify}",
                ]
            interval: 10s
            timeout: 5s
            retries: 5

    redis:
        image: redis:7-alpine
        container_name: lidify_redis
        ports:
            - "${REDIS_PORT:-6379}:6379"
        restart: unless-stopped
        healthcheck:
            test: ["CMD", "redis-cli", "ping"]
            interval: 10s
            timeout: 5s
            retries: 5

    # ==============================================================================
    # EXTERNAL SERVICES (Music Management)
    # ==============================================================================

    # Lidarr - Music collection manager
    lidarr:
        image: lscr.io/linuxserver/lidarr:latest
        container_name: lidify_lidarr
        environment:
            - PUID=${PUID:-1000}
            - PGID=${PGID:-1000}
            - TZ=${TZ:-UTC}
        volumes:
            - lidarr_config:/config
            - ${MUSIC_PATH:-./music}:/music
            - ${DOWNLOAD_PATH:-./downloads}:/downloads
        ports:
            - "8686:8686"
        restart: unless-stopped

    # Prowlarr - Indexer manager
    prowlarr:
        image: lscr.io/linuxserver/prowlarr:latest
        container_name: lidify_prowlarr
        environment:
            - PUID=${PUID:-1000}
            - PGID=${PGID:-1000}
            - TZ=${TZ:-UTC}
        volumes:
            - prowlarr_config:/config
        ports:
            - "9696:9696"
        restart: unless-stopped

    # FlareSolverr - Cloudflare bypass for Prowlarr
    flaresolverr:
        image: ghcr.io/flaresolverr/flaresolverr:latest
        container_name: lidify_flaresolverr
        environment:
            - LOG_LEVEL=${LOG_LEVEL:-info}
            - LOG_HTML=${LOG_HTML:-false}
            - CAPTCHA_SOLVER=${CAPTCHA_SOLVER:-none}
            - TZ=${TZ:-UTC}
        ports:
            - "8191:8191"
        restart: unless-stopped

    # NOTE: Soulseek is now handled directly by the backend using slsk-client
    # No Docker container needed - downloads go straight to Singles/Artist/Album/

    # qBittorrent - Torrent client
    qbittorrent:
        image: lscr.io/linuxserver/qbittorrent:latest
        container_name: lidify_qbittorrent
        environment:
            - PUID=${PUID:-1000}
            - PGID=${PGID:-1000}
            - TZ=${TZ:-UTC}
            - WEBUI_PORT=8080
        volumes:
            - qbittorrent_config:/config
            - ${MUSIC_PATH:-./music}/torrents:/music/torrents
            - ${DOWNLOAD_PATH:-./downloads}:/downloads
        ports:
            - "8080:8080"
            - "6881:6881"
            - "6881:6881/udp"
        restart: unless-stopped

    # SABnzbd - Usenet client
    sabnzbd:
        image: lscr.io/linuxserver/sabnzbd:latest
        container_name: lidify_sabnzbd
        environment:
            - PUID=${PUID:-1000}
            - PGID=${PGID:-1000}
            - TZ=${TZ:-UTC}
        volumes:
            - sabnzbd_config:/config
            - ${DOWNLOAD_PATH:-./downloads}:/downloads
        ports:
            - "8085:8080"
        restart: unless-stopped

    # ==============================================================================
    # AUDIO ANALYSIS SERVICE (Essentia)
    # ==============================================================================

    # Audio Analyzer - Extracts BPM, key, mood, and other audio features
    audio-analyzer:
        build:
            context: ./services/audio-analyzer
        container_name: lidify_audio_analyzer
        environment:
            REDIS_URL: redis://redis:6379
            DATABASE_URL: postgresql://${POSTGRES_USER:-lidifydb}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-lidify}
            MUSIC_PATH: /music
            BATCH_SIZE: ${AUDIO_ANALYSIS_BATCH_SIZE:-10}
            SLEEP_INTERVAL: ${AUDIO_ANALYSIS_INTERVAL:-5}
            # Default workers reduced from 8 to 2 for stability (Issue #26 fix)
            # Each worker requires 1-1.5GB RAM normally, up to 2-3GB peak
            NUM_WORKERS: ${AUDIO_ANALYSIS_WORKERS:-2}
            # CPU thread limiting per worker (default 1 for conservative CPU usage)
            THREADS_PER_WORKER: ${AUDIO_ANALYSIS_THREADS_PER_WORKER:-1}
        volumes:
            # Music library (read-only)
            - ${MUSIC_PATH:-./music}:/music:ro
            # NOTE: Models are baked into the Docker image at /app/models
            # No volume mount needed - previously this caused models to be hidden by empty volume
        depends_on:
            postgres:
                condition: service_healthy
            redis:
                condition: service_healthy
        restart: unless-stopped
        # Memory limits prevent OOM kills (Issue #26 fix)
        # 6G limit = safe for 2 workers at 2-3GB peak each
        # 2G reservation = minimum guaranteed memory
        deploy:
            resources:
                limits:
                    memory: 6G
                    cpus: '4'
                reservations:
                    memory: 2G
        # Disabled by default - enable when needed
        profiles:
            - audio-analysis

volumes:
    # Lidify core
    postgres_data:
    backend_cache:
    backend_logs:
    # External services
    lidarr_config:
    prowlarr_config:
    qbittorrent_config:
    sabnzbd_config:

networks:
    default:
        name: lidify_network
