import "server-only";

import { createHash, randomUUID } from "node:crypto";
import { mkdir, unlink, writeFile } from "node:fs/promises";
import path from "node:path";

export const MAX_STRATEGIC_EVIDENCE_BYTES = 10 * 1024 * 1024;

const EVIDENCE_STORAGE_ROOT = path.join(process.cwd(), "storage", "strategic-diagnostic");

const EXTENSION_BY_MIME: Record<string, string> = {
  "application/pdf": "pdf",
  "application/msword": "doc",
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
  "image/jpeg": "jpg",
  "image/png": "png",
};

function normalizeExtension(fileName: string, mimeType: string) {
  const fromMime = EXTENSION_BY_MIME[mimeType] ?? "";
  const fromName = fileName.includes(".") ? fileName.split(".").pop()?.toLowerCase() ?? "" : "";

  if (fromMime) {
    return fromMime;
  }

  return fromName || "bin";
}

function sanitizeFileName(fileName: string, extension: string) {
  const withoutExtension = fileName.replace(/\.[^/.]+$/, "");
  const safeBase = withoutExtension.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-") || "evidence";
  const safeExtension = extension.replace(/[^a-z0-9]+/g, "") || "bin";
  return `${safeBase}.${safeExtension}`;
}

export function isAllowedEvidenceMimeType(mimeType: string) {
  return mimeType in EXTENSION_BY_MIME;
}

export type StoredStrategicEvidenceFile = {
  fileName: string;
  storedFileName: string;
  filePath: string;
  mimeType: string;
  sizeBytes: number;
  checksumSha256: string;
};

export async function storeStrategicEvidenceFile(
  userId: string,
  originalFileName: string,
  mimeType: string,
  buffer: Buffer,
): Promise<StoredStrategicEvidenceFile> {
  const extension = normalizeExtension(originalFileName, mimeType);
  const safeOriginalName = sanitizeFileName(originalFileName, extension);
  const userDirectory = path.join(EVIDENCE_STORAGE_ROOT, userId);
  const storedFileName = `${Date.now()}-${randomUUID()}.${extension}`;
  const absoluteFilePath = path.join(userDirectory, storedFileName);

  await mkdir(userDirectory, { recursive: true });
  await writeFile(absoluteFilePath, buffer);

  return {
    fileName: safeOriginalName,
    storedFileName,
    filePath: path.join("storage", "strategic-diagnostic", userId, storedFileName).replace(/\\/g, "/"),
    mimeType,
    sizeBytes: buffer.byteLength,
    checksumSha256: createHash("sha256").update(buffer).digest("hex"),
  };
}

export async function removeStoredStrategicEvidenceFile(relativeFilePath: string | null | undefined) {
  if (!relativeFilePath) {
    return;
  }

  const storageRoot = path.resolve(process.cwd(), "storage");
  const absolutePath = path.resolve(process.cwd(), relativeFilePath);

  if (!absolutePath.startsWith(`${storageRoot}${path.sep}`)) {
    return;
  }

  try {
    await unlink(absolutePath);
  } catch {
    // Ignore delete errors (already deleted or inaccessible).
  }
}
