const express = require("express");
const router = express.Router();
const multer = require('multer');
const authorize = require("../../../../middlewares/authorize-sapps");
const dbSAPPS = require("../../helpers/db");
const goodsReceiptService = require("./goodsReceipt.service");

function toBool(v) {
    if (v === true || v === 1) return true;
    if (v === 'true' || v === '1') return true;
    return false;
}

/** Resolve req.user.role (with access_read_all_data, administrator_of_pirlo) for access control. */
async function resolveUserRole(req) {
    const user = req.user || {};
    if (user.role && typeof user.role === 'object' && user.role.id != null) {
        return {
            ...user.role,
            access_read_all_data: toBool(user.role.access_read_all_data),
            administrator_of_pirlo: toBool(user.role.administrator_of_pirlo)
        };
    }
    const roleId = user.role_id ?? user.roleId ?? user.role?.id;
    if (!roleId) return {};
    try {
        const roleRow = await dbSAPPS.Role.findByPk(roleId, {
            attributes: ['id', 'access_read_all_data', 'administrator_of_pirlo']
        });
        const raw = roleRow ? roleRow.get() : {};
        const role = {
            ...raw,
            access_read_all_data: toBool(raw.access_read_all_data),
            administrator_of_pirlo: toBool(raw.administrator_of_pirlo)
        };
        req.user.role = role;
        return role;
    } catch {
        return {};
    }
}

/** Only users with BOTH access_read_all_data and administrator_of_pirlo may create. */
function canCreateGoodsReceipt(role) {
    if (!role || typeof role !== 'object') return false;
    const a = role.access_read_all_data === true || role.access_read_all_data === 'true' || role.access_read_all_data === 1;
    const b = role.administrator_of_pirlo === true || role.administrator_of_pirlo === 'true' || role.administrator_of_pirlo === 1;
    return Boolean(a && b);
}

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './public/data/images/');
    },
    filename: function (req, file, cb) {
        cb(null, Date.now() + '-' + file.originalname);
    }
});

const upload = multer({ storage: storage });

router.post("/create", authorize(), upload.fields([
    { name: 'shipper_filename', maxCount: 1 },
    { name: 'cosignee_filename', maxCount: 1 },
]), create);

router.get("/", authorize(), getAll);
router.get("/shippers", authorize(), getAllShipper);
router.get("/cosignees", authorize(), getAllCosignee);
router.get("/filter", authorize(), filter);
router.get("/option", authorize(), option);
router.get("/count", authorize(), count);

router.put("/:id", authorize(), upload.fields([
    { name: 'shipper_filename', maxCount: 1 },
    { name: 'cosignee_filename', maxCount: 1 },
]), update);

router.put("/enabled/:id", authorize(), enabled);
router.put("/completed/:id", authorize(), completed);
router.delete("/:id", authorize(), _delete);

module.exports = router;

function create(req, res, next) {
    resolveUserRole(req).then((role) => {
        if (!canCreateGoodsReceipt(role)) {
            return res.status(403).json({
                success: false,
                message: 'Only users with access_read_all_data and administrator_of_pirlo can create goods receipts.'
            });
        }
        const createData = {
            ...req.body,
            shipper_filename: req.files && req.files.shipper_filename ? req.files.shipper_filename[0].filename : null,
            cosignee_filename: req.files && req.files.cosignee_filename ? req.files.cosignee_filename[0].filename : null
        };
        return goodsReceiptService.create(createData).then((result) => res.json(result)).catch(next);
    }).catch(next);
}

function getAll(req, res, next) {
    resolveUserRole(req).then((role) => {
        const params = {
            ...req.query,
            access_read_all_data: role.access_read_all_data === true,
            administrator_of_pirlo: role.administrator_of_pirlo === true
        };
        return goodsReceiptService.getAll(params).then((result) => res.json(result)).catch(next);
    }).catch(next);
}

function getAllShipper(req, res, next) {
    resolveUserRole(req).then((role) => {
        const params = {
            ...req.query,
            access_read_all_data: role.access_read_all_data === true,
            administrator_of_pirlo: role.administrator_of_pirlo === true
        };
        return goodsReceiptService.getAllShipper(params).then((result) => res.json(result)).catch(next);
    }).catch(next);
}

function getAllCosignee(req, res, next) {
    resolveUserRole(req).then((role) => {
        const params = {
            ...req.query,
            access_read_all_data: role.access_read_all_data === true,
            administrator_of_pirlo: role.administrator_of_pirlo === true
        };
        return goodsReceiptService.getAllCosignee(params).then((result) => res.json(result)).catch(next);
    }).catch(next);
}

function filter(req, res, next) {
    resolveUserRole(req).then((role) => {
        const params = {
            ...req.query,
            access_read_all_data: role.access_read_all_data === true,
            administrator_of_pirlo: role.administrator_of_pirlo === true
        };
        return goodsReceiptService.filter(params).then((result) => res.json(result)).catch(next);
    }).catch(next);
}

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

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

function update(req, res, next) {
    const updateData = {
        ...req.body,
        shipper_filename: req.files && req.files.shipper_filename ? req.files.shipper_filename[0].filename : req.body.shipper_filename ? req.body.shipper_filename : null,
        cosignee_filename: req.files && req.files.cosignee_filename ? req.files.cosignee_filename[0].filename : req.body.cosignee_filename ? req.body.cosignee_filename : null
    };

    goodsReceiptService
        .update(req.params.id, updateData)
        .then((result) => res.json(result))
        .catch(next);
}

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

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

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

