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

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    const isImage = file && file.mimetype && file.mimetype.startsWith("image/");
    const subfolder = isImage ? "images" : "documents";
    const dest = path.resolve(__dirname, `../../../../public/data/${subfolder}/upcountries/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,
  limits: {
    fileSize: 2 * 1024 * 1024, // 2MB
  },
  fileFilter: (req, file, cb) => {
    const allowedTypes = [
      // documents
      "application/pdf",
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "application/mime",
      // images
      "image/jpeg",
      "image/png",
      "image/webp",
      "image/gif",
    ];

    if (!allowedTypes.includes(file.mimetype)) {
      return cb(
        new multer.MulterError(
          "LIMIT_UNEXPECTED_FILE",
          "Format file tidak diizinkan. Gunakan PDF, DOCX atau gambar (jpg/png)",
        ),
      );
    }

    cb(null, true);
  },
});

router.post("/", authorize(), getAll);
router.post("/create", authorize(), upload.single("filename"), create);
router.post("/generate-doc-no", authorize(), generateDocumentNo);
router.post("/request-ga", authorize(), requestGA);
router.get("/filter", authorize(), filter);
router.get("/option", authorize(), option);
router.get("/count", authorize(), count);
// Backwards-compatible route: some clients call '/update/:id'
router.put("/update/:id", authorize(), upload.single("filename"), update);
router.put(
  "/update-file/:id",
  authorize(),
  (req, res, next) => {
    upload.single("files")(req, res, function (err) {
      if (err instanceof multer.MulterError) {
        // Error dari multer
        if (err.code === "LIMIT_FILE_SIZE") {
          return res.status(400).json({
            success: false,
            message: "Ukuran file terlalu besar. Maksimal 2MB",
          });
        }

        return res.status(400).json({
          success: false,
          message: err.message,
        });
      } else if (err) {
        // Error lain
        return res.status(400).json({
          success: false,
          message: "Upload file gagal",
        });
      }

      next();
    });
  },
  updateFile,
);
router.put("/enabled/:id", authorize(), enabled);
router.delete("/:id", authorize(), _delete);

module.exports = router;

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-JARAK-${req.file.filename.split(".")[0]}.webp`;
      const finalDir = path.resolve(__dirname, "../../../../public/data/images/upcountries");

      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,
    };

    console.log("createData di controller:", createData);

    const result = await upCountryService.create(createData);
    res.json(result);
  } catch (error) {
    console.error(error);
    next(error);
  }
}

async function update(req, res, next) {
  try {
    let compressedFilename = req.body.filename || 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-JARAK-${req.file.filename.split(".")[0]}.webp`;
      const finalDir = path.resolve(__dirname, "../../../../public/data/images/upcountries");

      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 updateData = {
      ...req.body,
      filename: compressedFilename,
    };

    console.log("ID yang diupdate:", req.params.id);

    console.log("updateData di controller:", updateData);

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

async function updateFile(req, res, next) {
  try {
    let filenameToSave = req.body.filename || null;

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

      const finalDestinationDir = path.resolve(__dirname, "../../../../public/data/documents/upcountries");

      if (!fs.existsSync(finalDestinationDir)) {
        fs.mkdirSync(finalDestinationDir, { recursive: true });
      }

      const outputPath = path.join(finalDestinationDir, originalFilename);
      await fs.promises.rename(inputPath, outputPath);

      filenameToSave = originalFilename;

      // Jika file adalah gambar, pindahkan ke folder images instead
      if (req.file && req.file.mimetype && req.file.mimetype.startsWith("image/")) {
        const finalImageDir = path.resolve(__dirname, "../../../../public/data/images/upcountries");
        if (!fs.existsSync(finalImageDir)) {
          fs.mkdirSync(finalImageDir, { recursive: true });
        }
        const imageOutputPath = path.join(finalImageDir, originalFilename);
        // pindahkan dari tmp ke folder images
        await fs.promises.rename(inputPath, imageOutputPath).catch(async (e) => {
          // jika rename awal sudah memindahkan, coba pindahkan dari documents lokasi
          if (fs.existsSync(outputPath)) {
            await fs.promises.rename(outputPath, imageOutputPath);
          } else {
            throw e;
          }
        });

        filenameToSave = originalFilename;
      }
    }

    const updateData = {
      ...req.body,
      files: filenameToSave,
    };

    const result = await upCountryService.updateFile(req.params.id, updateData);

    return res.json(result);
  } catch (error) {
    next(error);
  }
}

function generateDocumentNo(req, res, next) {
  upCountryService
    .generateDocumentNo(req.body)
    .then((result) => res.json(result))
    .catch(next);
}

function requestGA(req, res, next) {
  upCountryService
    .requestGA(req.body)
    .then((result) => res.json(result))
    .catch(next);
}

function getAll(req, res, next) {
  upCountryService
    .getAll(req.body)
    .then((result) => res.json(result))
    .catch(next);
}

function filter(req, res, next) {
  upCountryService
    .filter(req.query)
    .then((result) => res.json(result))
    .catch(next);
}

function option(req, res, next) {
  upCountryService
    .option()
    .then((result) => res.json(result))
    .catch(next);
}

function count(req, res, next) {
  upCountryService
    .count()
    .then((result) => res.json(result))
    .catch(next);
}

function enabled(req, res, next) {
  upCountryService
    .enabled(req.params.id, req.body)
    .then((result) => res.json(result))
    .catch(next);
}

function _delete(req, res, next) {
  upCountryService
    .delete(req.params.id)
    .then((result) => res.json(result))
    .catch(next);
}
