const BLOCKED_DOCUMENT_TYPES = new Set([
  'application/javascript',
  'application/x-javascript',
  'text/javascript',
  'text/html',
  'application/xhtml+xml',
  'application/x-httpd-php',
  'application/x-sh'
]);

const EXTENSION_TO_MIME: Record<string, string> = {
  jpg: 'image/jpeg',
  jpeg: 'image/jpeg',
  png: 'image/png',
  webp: 'image/webp',
  gif: 'image/gif',
  pdf: 'application/pdf',
  doc: 'application/msword',
  docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  xls: 'application/vnd.ms-excel',
  xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  ppt: 'application/vnd.ms-powerpoint',
  pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  txt: 'text/plain',
  rtf: 'application/rtf',
  odt: 'application/vnd.oasis.opendocument.text'
};

const ALLOWED_DOCUMENT_MIME = new Set([
  'image/jpeg',
  'image/png',
  'image/webp',
  'image/gif',
  'application/pdf',
  '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',
  'text/plain',
  'application/rtf',
  'application/vnd.oasis.opendocument.text'
]);

const MIME_ALIASES: Record<string, string> = {
  'image/jpg': 'image/jpeg',
  'image/pjpeg': 'image/jpeg',
  'application/x-pdf': 'application/pdf'
};

function extractFileExtension(fileName?: string | null) {
  const trimmed = (fileName ?? '').trim().toLowerCase();
  const dotIndex = trimmed.lastIndexOf('.');
  if (dotIndex <= 0) return '';
  return trimmed.slice(dotIndex + 1);
}

export function normalizeDocumentContentType(contentType?: string | null, fileName?: string | null) {
  const raw = (contentType ?? '').trim().toLowerCase();
  const base = raw.split(';')[0]?.trim() ?? '';
  const aliased = MIME_ALIASES[base] ?? base;

  if (aliased && aliased !== 'application/octet-stream' && ALLOWED_DOCUMENT_MIME.has(aliased)) {
    return aliased;
  }

  const extension = extractFileExtension(fileName);
  if (extension && EXTENSION_TO_MIME[extension]) {
    return EXTENSION_TO_MIME[extension];
  }

  return aliased || 'application/octet-stream';
}

export function assertDocumentAttachmentContentType(contentType: string, fileName?: string) {
  const normalized = normalizeDocumentContentType(contentType, fileName);
  if (BLOCKED_DOCUMENT_TYPES.has(normalized)) {
    throw new Error('Тип файла не поддерживается');
  }
  if (!ALLOWED_DOCUMENT_MIME.has(normalized)) {
    throw new Error('Допустимы изображения, PDF, Word, Excel, PowerPoint, TXT и ODT');
  }
  return normalized;
}

export function extensionForDocumentContentType(contentType: string, fileName?: string) {
  const normalized = normalizeDocumentContentType(contentType, fileName);
  switch (normalized) {
    case 'image/jpeg':
      return 'jpg';
    case 'image/png':
      return 'png';
    case 'image/webp':
      return 'webp';
    case 'image/gif':
      return 'gif';
    case 'application/pdf':
      return 'pdf';
    case 'application/msword':
      return 'doc';
    case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
      return 'docx';
    case 'application/vnd.ms-excel':
      return 'xls';
    case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
      return 'xlsx';
    case 'application/vnd.ms-powerpoint':
      return 'ppt';
    case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
      return 'pptx';
    case 'text/plain':
      return 'txt';
    case 'application/rtf':
      return 'rtf';
    case 'application/vnd.oasis.opendocument.text':
      return 'odt';
    default: {
      const extension = extractFileExtension(fileName);
      return extension || 'bin';
    }
  }
}

export function contentTypeForDocumentKey(storageKey: string) {
  const lower = storageKey.toLowerCase();
  if (lower.endsWith('.png')) return 'image/png';
  if (lower.endsWith('.webp')) return 'image/webp';
  if (lower.endsWith('.gif')) return 'image/gif';
  if (lower.endsWith('.pdf')) return 'application/pdf';
  if (lower.endsWith('.doc')) return 'application/msword';
  if (lower.endsWith('.docx')) return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
  if (lower.endsWith('.xls')) return 'application/vnd.ms-excel';
  if (lower.endsWith('.xlsx')) return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
  if (lower.endsWith('.ppt')) return 'application/vnd.ms-powerpoint';
  if (lower.endsWith('.pptx')) return 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
  if (lower.endsWith('.txt')) return 'text/plain';
  if (lower.endsWith('.rtf')) return 'application/rtf';
  if (lower.endsWith('.odt')) return 'application/vnd.oasis.opendocument.text';
  return 'image/jpeg';
}
