# syntax=docker/dockerfile:1
# =============================================================================
# Portal (Next.js) Dockerfile
# =============================================================================
# Multi-stage build with standalone output for minimal image size
# Optimized for fast builds, security, and small production images
# =============================================================================

ARG NODE_VERSION=22
ARG PNPM_VERSION=10.25.0

# =============================================================================
# Stage 1: Dependencies (cached layer)
# =============================================================================
FROM node:${NODE_VERSION}-alpine AS deps

ARG PNPM_VERSION

# Install build dependencies
RUN apk add --no-cache libc6-compat \
    && corepack enable \
    && corepack prepare pnpm@${PNPM_VERSION} --activate

WORKDIR /app

# Copy manifests first for dependency caching (all workspace packages)
COPY .npmrc pnpm-workspace.yaml package.json pnpm-lock.yaml ./
COPY packages/domain/package.json ./packages/domain/package.json
COPY apps/portal/package.json ./apps/portal/package.json
COPY apps/bff/package.json ./apps/bff/package.json

# Install only the packages needed for the portal (domain + portal)
# Disable inject-workspace-packages so symlinks are used (domain dist doesn't exist at install time)
ENV HUSKY=0
RUN --mount=type=cache,id=pnpm-portal,target=/root/.local/share/pnpm/store \
    pnpm config set inject-workspace-packages false && \
    pnpm install --frozen-lockfile --filter @customer-portal/domain... --filter @customer-portal/portal...

# =============================================================================
# Stage 2: Builder
# =============================================================================
FROM deps AS builder

# Copy source files
COPY tsconfig.json tsconfig.base.json tsconfig.node.json tsconfig.next.json ./
COPY packages/domain/ ./packages/domain/
COPY apps/portal/ ./apps/portal/

# Build-time environment variables
ARG NEXT_PUBLIC_API_BASE=/api
ARG NEXT_PUBLIC_APP_NAME="Customer Portal"
ARG NEXT_PUBLIC_APP_VERSION=1.0.0

ENV NODE_ENV=production \
    NEXT_PUBLIC_API_BASE=${NEXT_PUBLIC_API_BASE} \
    NEXT_PUBLIC_APP_NAME=${NEXT_PUBLIC_APP_NAME} \
    NEXT_PUBLIC_APP_VERSION=${NEXT_PUBLIC_APP_VERSION} \
    NEXT_TELEMETRY_DISABLED=1

# Build: domain → Next.js (standalone output)
# After building domain, manually create symlink to ensure resolution works
RUN pnpm --filter @customer-portal/domain build \
    && mkdir -p node_modules/@customer-portal \
    && ln -sf ../../packages/domain node_modules/@customer-portal/domain \
    && pnpm --filter @customer-portal/portal build

# =============================================================================
# Stage 3: Production
# =============================================================================
FROM node:${NODE_VERSION}-alpine AS production

LABEL org.opencontainers.image.title="Customer Portal Frontend" \
      org.opencontainers.image.description="Next.js Customer Portal" \
      org.opencontainers.image.vendor="Customer Portal"

# Minimal runtime dependencies + security hardening
RUN apk add --no-cache dumb-init libc6-compat \
    && addgroup --system --gid 1001 nodejs \
    && adduser --system --uid 1001 nextjs \
    # Remove apk cache and unnecessary files
    && rm -rf /var/cache/apk/* /tmp/* /root/.npm

WORKDIR /app

# Copy standalone build artifacts with correct ownership
COPY --from=builder --chown=nextjs:nodejs /app/apps/portal/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/portal/.next/static ./apps/portal/.next/static
COPY --from=builder --chown=nextjs:nodejs /app/apps/portal/public ./apps/portal/public

# Security: Run as non-root user
USER nextjs

# Expose frontend port
EXPOSE 3000

# Environment configuration
ENV NODE_ENV=production \
    NEXT_TELEMETRY_DISABLED=1 \
    PORT=3000 \
    HOSTNAME="0.0.0.0" \
    # Node.js production optimizations
    NODE_OPTIONS="--max-old-space-size=512"

# Health check for container orchestration
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
    CMD node -e "fetch('http://localhost:3000/_health').then(r=>r.ok||process.exit(1)).catch(()=>process.exit(1))"

ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "apps/portal/server.js"]
