"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "insurancePlansRoute", {
    enumerable: true,
    get: function() {
        return insurancePlansRoute;
    }
});
const _express = /*#__PURE__*/ _interop_require_default(require("express"));
const _expressasynchandler = /*#__PURE__*/ _interop_require_default(require("express-async-handler"));
const _zod = require("zod");
const _sequelize = require("sequelize");
const _constants = require("@tamanu/constants");
const _errors = require("@tamanu/errors");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
const insurancePlansRoute = _express.default.Router();
const updateInvoiceInsurancePlansSchema = _zod.z.object({
    invoiceInsurancePlanIds: _zod.z.array(_zod.z.string()).default([])
}).strip();
insurancePlansRoute.put('/:id/insurancePlans', (0, _expressasynchandler.default)(async (req, res)=>{
    req.checkPermission('write', 'Invoice');
    const invoiceId = req.params.id;
    const invoice = await req.models.Invoice.findByPk(invoiceId, {
        attributes: [
            'id',
            'status'
        ]
    });
    if (!invoice) {
        throw new _errors.NotFoundError('Invoice not found');
    }
    if (invoice.status !== _constants.INVOICE_STATUSES.IN_PROGRESS) {
        throw new _errors.InvalidOperationError('Only in progress invoices can be updated');
    }
    const { data, error } = await updateInvoiceInsurancePlansSchema.safeParseAsync(req.body);
    if (error) {
        throw new _errors.ValidationError(error.message);
    }
    const { invoiceInsurancePlanIds } = data;
    const transaction = await req.db.transaction();
    try {
        // Remove links not in provided list (or all if list empty)
        await req.models.InvoicesInvoiceInsurancePlan.destroy(invoiceInsurancePlanIds.length ? {
            where: {
                invoiceId,
                invoiceInsurancePlanId: {
                    [_sequelize.Op.notIn]: invoiceInsurancePlanIds
                }
            }
        } : {
            where: {
                invoiceId
            }
        }, {
            transaction
        });
        // Find existing links to avoid duplicates
        const existing = await req.models.InvoicesInvoiceInsurancePlan.findAll({
            where: {
                invoiceId
            },
            attributes: [
                'invoiceInsurancePlanId'
            ],
            transaction
        });
        const existingIds = new Set(existing.map((r)=>r.invoiceInsurancePlanId));
        const toCreate = invoiceInsurancePlanIds.filter((id)=>!existingIds.has(id));
        if (toCreate.length) {
            await req.models.InvoicesInvoiceInsurancePlan.bulkCreate(toCreate.map((planId)=>({
                    id: crypto.randomUUID(),
                    invoiceId,
                    invoiceInsurancePlanId: planId
                })), {
                transaction
            });
        }
        await transaction.commit();
        // Return the current set of linked plans
        const linked = await req.models.InvoicesInvoiceInsurancePlan.findAll({
            where: {
                invoiceId
            },
            include: [
                {
                    model: req.models.InvoiceInsurancePlan,
                    as: 'invoiceInsurancePlan'
                }
            ]
        });
        res.json({
            count: linked.length,
            data: linked
        });
    } catch (e) {
        await transaction.rollback();
        throw e;
    }
}));

//# sourceMappingURL=insurancePlans.js.map