const fsp = require("fs/promises");
const { escapeQuoted, handleServerError } = require("../utils/helpers");
const {
  ensureStorageDependencies,
  listFilesForUser,
  createFileEntry,
  createFolderEntry,
  getDownloadStream,
  deleteEntryById
} = require("../services/storageService");

async function listFilesController(req, res) {
  try {
    await ensureStorageDependencies();
    const files = await listFilesForUser(req.user, req.query);
    res.json({ files });
  } catch (error) {
    handleServerError(res, error, "Failed to fetch files");
  }
}

async function uploadFileController(req, res) {
  let tempFilePath = "";
  try {
    await ensureStorageDependencies();
    if (!req.file) {
      return res.status(400).json({ error: "file is required" });
    }

    tempFilePath = req.file.path || "";
    const file = await createFileEntry(req.user, req.file, req.body || {});
    return res.status(201).json({ file });
  } catch (error) {
    handleServerError(res, error, "Failed to upload file");
  } finally {
    if (tempFilePath) {
      try {
        await fsp.unlink(tempFilePath);
      } catch {
        // Ignore temp cleanup failures.
      }
    }
  }
}

async function createFolderController(req, res) {
  try {
    await ensureStorageDependencies();
    const result = await createFolderEntry(req.user, req.body || {});
    if (result.error) {
      return res.status(result.status).json({ error: result.error });
    }
    return res.status(result.status).json({ folder: result.data });
  } catch (error) {
    handleServerError(res, error, "Failed to create folder");
  }
}

async function downloadFileController(req, res) {
  try {
    await ensureStorageDependencies();
    const result = await getDownloadStream(req.params.id, req.user.id);
    if (result.error) {
      return res.status(result.status).json({ error: result.error });
    }

    const { fileRecord, stream } = result;
    res.setHeader("Content-Type", fileRecord.contentType || "application/octet-stream");
    res.setHeader(
      "Content-Disposition",
      `attachment; filename="${escapeQuoted(fileRecord.originalFileName || fileRecord.displayName || "download.bin")}"`
    );

    stream.on("error", (error) => {
      if (!res.headersSent) {
        res.status(500).json({ error: "failed to read file" });
      } else {
        res.end();
      }
      console.error("MinIO stream error", error);
    });
    stream.pipe(res);
  } catch (error) {
    if (error && error.code === "NOT_FOUND") {
      return res.status(404).json({ error: "file not found" });
    }
    handleServerError(res, error, "Failed to download file");
  }
}

async function deleteEntryController(req, res) {
  try {
    await ensureStorageDependencies();
    const force = String(req.query.force || "").toLowerCase() === "true";
    const result = await deleteEntryById(req.params.id, req.user.id, force);

    if (result.error) {
      return res.status(result.status).json({
        error: result.error,
        requiresConfirmation: Boolean(result.requiresConfirmation),
        fileCount: result.fileCount,
        itemCount: result.itemCount
      });
    }

    return res.json(result);
  } catch (error) {
    if (error && error.code === "NOT_FOUND") {
      return res.status(404).json({ error: "entry not found" });
    }
    handleServerError(res, error, "Failed to delete entry");
  }
}

module.exports = {
  listFilesController,
  uploadFileController,
  createFolderController,
  downloadFileController,
  deleteEntryController
};
