import { registerAs } from '@nestjs/config';
import { isAbsolute, relative, resolve } from 'node:path';
import { DELETED_MEDIA_ROOT } from '../common/media/media.constants';

/**
 * Public HTTP mount for locally stored files. Frozen so a mis-set env
 * cannot overlay `/api` (or `/`) with `express.static`.
 */
export const STORAGE_PUBLIC_MOUNT = '/api/uploads';

/**
 * Resolve `STORAGE_LOCAL_DIR` to an absolute path that is strictly
 * inside `process.cwd()`. Absolute paths, `..`, and cwd itself are
 * rejected — otherwise `express.static` could serve the rest of the
 * host filesystem.
 */
export function resolveStorageRoot(localDir?: string): string {
  const cwd = process.cwd();
  const abs = resolve(cwd, localDir || 'uploads');
  const rel = relative(cwd, abs);
  if (!rel || rel.startsWith('..') || isAbsolute(rel)) {
    throw new Error(
      'STORAGE_LOCAL_DIR must be a directory inside the application working directory',
    );
  }
  return abs;
}

/**
 * True when a path under the public mount points into the trashed-media
 * tree. Decoded and case-folded because the static handler decodes too
 * and macOS volumes are case-insensitive; undecodable paths are blocked.
 */
export function isTrashedMediaPath(path: string): boolean {
  let decoded: string;
  try {
    decoded = decodeURIComponent(path);
  } catch {
    return true;
  }
  const first = decoded.replace(/\\/g, '/').split('/').find(Boolean) ?? '';
  return first.toLowerCase() === DELETED_MEDIA_ROOT;
}

export default registerAs('storage', () => ({
  localDir: process.env.STORAGE_LOCAL_DIR || 'uploads',
  publicBaseUrl: STORAGE_PUBLIC_MOUNT,
}));
