const express = require("express");
const router = express.Router();
const multer = require("multer");
const authorize = require("../../../../middlewares/authorize-sapps");
const ucCostRealizationService = require("./ucCostRealization.service");
const path = require("path");
const sharp = require("sharp");
const fs = require("fs");

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    const dest = path.resolve(__dirname, "../../../../public/data/images/upcountry/tmp");

    // ✅ Auto create folder if not exists
    if (!fs.existsSync(dest)) {
      fs.mkdirSync(dest, { recursive: true });
    }

    cb(null, dest);
  },
  filename: function (req, file, cb) {
    const ext = path.extname(file.originalname);
    const tempName = `TEMP-${Date.now()}${ext}`;
    cb(null, tempName);
  },
});

const upload = multer({
  storage,
  fileFilter: function (req, file, cb) {
    if (!file.mimetype.startsWith("image/")) {
      cb(new Error("Hanya file gambar yang diperbolehkan!"), false);
    } else {
      cb(null, true);
    }
  },
});

router.post("/create", authorize(), upload.single("filename"), create);
router.post("/", authorize(), getAll);
router.post("/option", authorize(), option);
router.get("/count", authorize(), count);
router.put("/:id", authorize(), upload.single("filename"), update);
router.delete("/:id", authorize(), _delete);

module.exports = router;

/**
 * Create a new drug
 * @param {Object} req.body - The drug data
 * @param {Object} res - The response object
 * @param {Function} next - The next middleware function
 * @returns {Promise} - A promise resolving to the created drug
 */
async function create(req, res, next) {
  try {
    let compressedFilename = null;

    if (req.file) {
      const inputPath = req.file.path;

      // amankan semua karakter aneh di nama file
      const safe = (text) => (text ? text.replace(/[^a-z0-9]/gi, "_").toUpperCase() : "UNKNOWN");

      const compressedName = `UC-${safe(req.body.employee_name)}-${safe(req.body.request_no)}-${safe(
        req.body.category
      )}-${safe(req.body.upload_date)}-${Math.random().toString(36).substring(2, 15)}.webp`;

      const finalDir = path.resolve(__dirname, "../../../../public/data/images/upcountry");

      const outputPath = path.join(finalDir, compressedName);

      // ✅ pastikan folder final ada
      if (!fs.existsSync(finalDir)) {
        fs.mkdirSync(finalDir, { recursive: true });
      }
      await sharp(inputPath).resize({ width: 1000 }).webp({ quality: 70 }).toFile(outputPath);

      // hapus file temp pakai delay
      setTimeout(() => {
        if (fs.existsSync(inputPath)) {
          fs.unlink(inputPath, (err) => {
            if (err) console.log("Gagal hapus temp:", err.message);
          });
        }
      }, 500);

      compressedFilename = compressedName;
    }

    const createData = {
      ...req.body,
      filename: compressedFilename,
    };

    const result = await ucCostRealizationService.create(createData);
    res.json(result);
  } catch (error) {
    console.error("CREATE ERROR:", error);
    next(error);
  }
}

/**
 * Update an existing drug
 * @param {number} req.params.id - The drug ID to be updated
 * @param {Object} req.body - The drug data to be updated
 * @param {Object} res - The response object
 * @param {Function} next - The next middleware function
 * @returns {Promise} - A promise resolving to the updated drug
 */
async function update(req, res, next) {
  try {
    let compressedFilename = req.body.filename || null;

    if (req.file) {
      const inputPath = req.file.path;

      const safe = (text) => (text ? text.replace(/[^a-z0-9]/gi, "_").toUpperCase() : "UNKNOWN");

      const compressedName = `UC-${safe(req.body.employee_name)}-${safe(req.body.request_no)}-${safe(
        req.body.category
      )}-${safe(req.body.upload_date)}-${Math.random().toString(36).substring(2, 15)}.webp`;

      const outputPath = path.join(__dirname, "../../../../public/data/images/upcountry", compressedName);

      await sharp(inputPath).resize({ width: 1000 }).webp({ quality: 70 }).toFile(outputPath);

      // hapus temp file update
      setTimeout(() => {
        fs.unlink(inputPath, (err) => {
          if (err) console.error("❌ Update temp gagal dihapus:", err.message);
          else console.log("✅ Update temp dihapus");
        });
      }, 500);

      compressedFilename = compressedName;
    }

    const updateData = {
      ...req.body,
      filename: compressedFilename,
    };

    const result = await ucCostRealizationService.update(req.params.id, updateData);
    res.json(result);
  } catch (error) {
    console.error(error);
    next(error);
  }
}

/**
 * Get a list of all drugs
 * @param {Object} req.query - The query object
 * @param {Object} res - The response object
 * @param {Function} next - The next middleware function
 * @returns {Promise} - A promise resolving to an array of drugs
 */
function getAll(req, res, next) {
  ucCostRealizationService
    .getAll(req.body)
    .then((result) => res.json(result))
    .catch(next);
}

/**
 * Get an array of drug objects to be used as options in a select box
 * @param {Object} req.query - The query object
 * @param {Object} res - The response object
 * @param {Function} next - The next middleware function
 * @returns {Promise} - A promise resolving to an array of drug objects
 */
function option(req, res, next) {
  ucCostRealizationService
    .option(req.body)
    .then((result) => res.json(result))
    .catch(next);
}

/**
 * Count the number of drugs matching a query
 * @param {Object} req.query - The query object
 * @param {Object} res - The response object
 * @param {Function} next - The next middleware function
 * @returns {Promise} - A promise resolving to the count of drugs
 */
function count(req, res, next) {
  ucCostRealizationService
    .count(req.query)
    .then((result) => res.json(result))
    .catch(next);
}

/**
 * Delete a drug
 * @param {number} req.params.id - The drug ID to be deleted
 * @param {Object} res - The response object
 * @param {Function} next - The next middleware function
 * @returns {Promise} - A promise resolving to the result of the deletion process
 */
function _delete(req, res, next) {
  ucCostRealizationService
    .delete(req.params.id)
    .then((result) => res.json(result))
    .catch(next);
}
