import { randomUUID } from 'crypto';
import { extname } from 'path';
import type { AttachmentKind } from '../task/entities/attachment.entity';

// 드라이브 파일 1건 최대 크기(기본 200MB) — env 로 조정 가능.
// presigned PUT 은 크기를 서명으로 강제하지 못하므로, 최종 검증은 complete 단계의 HEAD 로 한다.
export const DRIVE_MAX_FILE_SIZE = (() => {
  const mb = Number(process.env.DRIVE_MAX_FILE_MB);
  return Number.isFinite(mb) && mb > 0 ? mb * 1024 * 1024 : 200 * 1024 * 1024;
})();

// 허용 MIME 화이트리스트 — 실행/스크립트(text/html, image/svg+xml 등)는 차단(심층 방어).
// 문서 첨부(upload.config) 기준에 드라이브 용도의 미디어 타입을 추가했다.
export const DRIVE_ALLOWED_MIME_TYPES: ReadonlySet<string> = new Set<string>([
  // 이미지
  'image/png',
  'image/jpeg',
  'image/gif',
  'image/webp',
  // 문서
  'application/pdf',
  'text/plain',
  'text/csv',
  'text/markdown',
  'application/msword',
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  'application/vnd.ms-excel',
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  'application/vnd.ms-powerpoint',
  'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  'application/json',
  // 압축
  'application/zip',
  'application/x-zip-compressed',
  'application/x-7z-compressed',
  'application/x-rar-compressed',
  // 미디어(드라이브 용도)
  'video/mp4',
  'video/webm',
  'video/quicktime',
  'audio/mpeg',
  'audio/wav',
  'audio/ogg',
]);

// 허용 MIME 여부
export function isAllowedMime(mime: string): boolean {
  return DRIVE_ALLOWED_MIME_TYPES.has(mime);
}

// MIME/확장자로 아이콘 종류 파생(첨부와 동일 분류 재사용)
export function deriveKind(mime: string, name: string): AttachmentKind {
  const lower = name.toLowerCase();
  if (mime.startsWith('image/')) return 'img';
  if (mime === 'application/pdf' || lower.endsWith('.pdf')) return 'pdf';
  if (
    mime.includes('zip') ||
    mime.includes('compressed') ||
    lower.endsWith('.zip')
  ) {
    return 'zip';
  }
  return 'doc';
}

// 버킷 객체 키 생성 — {APP_ENV}/drive/{userId}/{uuid}{ext}
// 원본 파일명은 DB(name)에만 보관하고, 키는 충돌/인코딩 안전을 위해 uuid 기반으로 만든다.
export function buildObjectKey(userId: string, filename: string): string {
  const env = process.env.APP_ENV || process.env.NODE_ENV || 'development';
  const ext = extname(filename).toLowerCase().slice(0, 16); // 비정상적으로 긴 확장자 방어
  return `${env}/drive/${userId}/${randomUUID()}${ext}`;
}
