import { Client } from 'minio';

import { env } from '@/lib/env';
import { logger } from '@/lib/logger';

export const minioClient = new Client({
  endPoint: env.MINIO_ENDPOINT,
  port: env.MINIO_PORT,
  useSSL: env.MINIO_USE_SSL,
  accessKey: env.MINIO_ACCESS_KEY,
  secretKey: env.MINIO_SECRET_KEY,
});

const BUCKET = env.MINIO_BUCKET;

/**
 * Ensures the configured bucket exists, creating it if not.
 * Should be called once at application startup.
 */
export async function ensureBucket(): Promise<void> {
  try {
    const exists = await minioClient.bucketExists(BUCKET);
    if (!exists) {
      await minioClient.makeBucket(BUCKET);
      logger.info({ bucket: BUCKET }, 'MinIO bucket created');
    } else {
      logger.debug({ bucket: BUCKET }, 'MinIO bucket exists');
    }
  } catch (err) {
    logger.error({ err, bucket: BUCKET }, 'Failed to ensure MinIO bucket');
    throw err;
  }
}

/**
 * Generates a pre-signed GET URL for an object.
 *
 * Default expiry is 15 minutes (900 seconds) per SECURITY-GUIDELINES.md §7.1.
 */
export async function getPresignedUrl(
  objectKey: string,
  expirySeconds = 900,
): Promise<string> {
  return minioClient.presignedGetObject(BUCKET, objectKey, expirySeconds);
}

/**
 * Constructs a storage path from typed components.
 *
 * Format: `{portSlug}/{entity}/{entityId}/{fileId}.{extension}`
 *
 * No user-supplied input should ever be used as path components — only UUIDs
 * and controlled slugs (SECURITY-GUIDELINES.md §3.4, §7.1).
 */
export function buildStoragePath(
  portSlug: string,
  entity: string,
  entityId: string,
  fileId: string,
  extension: string,
): string {
  return `${portSlug}/${entity}/${entityId}/${fileId}.${extension}`;
}
