const { validationResult } = require('express-validator');
const Unit = require('../models/Unit');
// Helper function to generate unit code from name
function generateCodeFromName(name) {
    if (!name)
        return '';
    return name
        .trim()
        .toUpperCase()
        .replace(/[^A-Z0-9\s-]/g, '') // Remove special characters except spaces and hyphens
        .replace(/\s+/g, '_') // Replace spaces with underscores
        .replace(/-+/g, '_') // Replace hyphens with underscores
        .replace(/_+/g, '_') // Replace multiple underscores with single underscore
        .substring(0, 20); // Limit to 20 characters
}
class UnitController {
    // Get all units
    static async getAllUnits(req, res, next) {
        try {
            const { page = 1, limit = 50, search = '', parent_id = null, tree = 'false', include_inactive = 'false' } = req.query;
            const options = {
                page: parseInt(page),
                limit: parseInt(limit),
                search,
                parent_id,
                organization_id: req.user?.organization_id,
                include_inactive: include_inactive === 'true'
            };
            let units;
            if (tree === 'true') {
                units = await Unit.getUnitTree(options);
            }
            else {
                units = await Unit.findAll(options);
            }
            const statistics = await Unit.getStatistics();
            res.status(200).json({
                status: 'success',
                message: 'Units retrieved successfully',
                data: {
                    units: tree === 'true' ? units : units.map(unit => unit.toJSON()),
                    statistics,
                    pagination: {
                        page: parseInt(page),
                        limit: parseInt(limit),
                        total: Array.isArray(units) ? units.length : 0
                    },
                    filters: {
                        search,
                        parent_id,
                        tree: tree === 'true',
                        include_inactive: include_inactive === 'true'
                    }
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Get unit by ID
    static async getUnitById(req, res, next) {
        try {
            const { id } = req.params;
            const unit = await Unit.findById(id, req.user?.organization_id);
            if (!unit) {
                return res.status(404).json({
                    status: 'error',
                    message: 'Unit not found'
                });
            }
            res.status(200).json({
                status: 'success',
                message: 'Unit retrieved successfully',
                data: {
                    unit: unit.toJSON()
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Create new unit
    static async createUnit(req, res, next) {
        try {
            const errors = validationResult(req);
            if (!errors.isEmpty()) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Validation failed',
                    errors: errors.array()
                });
            }
            const { name, description, parent_id } = req.body;
            let { code } = req.body;
            const created_by = req.user ? req.user.id : 1; // Default to user ID 1 for testing
            const organization_id = req.user?.organization_id || 1;
            // Auto-generate code from name if not provided
            if (!code || code.trim() === '') {
                code = generateCodeFromName(name);
            }
            // Prepare data for creation, ensuring undefined values are handled
            const unitData = {
                name,
                code,
                organization_id,
                description: description || null,
                parent_id: parent_id || null,
                created_by
            };
            const unitId = await Unit.create(unitData);
            const newUnit = await Unit.findById(unitId, organization_id);
            res.status(201).json({
                status: 'success',
                message: 'Unit created successfully',
                data: {
                    unit: newUnit.toJSON()
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Update unit
    static async updateUnit(req, res, next) {
        try {
            const errors = validationResult(req);
            if (!errors.isEmpty()) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Validation failed',
                    errors: errors.array()
                });
            }
            const { id } = req.params;
            const updateData = req.body;
            const organization_id = req.user?.organization_id;
            // Check if unit exists
            const unit = await Unit.findById(id, organization_id);
            if (!unit) {
                return res.status(404).json({
                    status: 'error',
                    message: 'Unit not found'
                });
            }
            // If parent_id is being updated, prevent circular reference
            if (updateData.parent_id) {
                if (parseInt(updateData.parent_id) === parseInt(id)) {
                    return res.status(400).json({
                        status: 'error',
                        message: 'Unit cannot be its own parent'
                    });
                }
            }
            const updated = await Unit.update(id, updateData, organization_id);
            if (!updated) {
                return res.status(404).json({
                    status: 'error',
                    message: 'Unit not found or no changes made'
                });
            }
            const updatedUnit = await Unit.findById(id, organization_id);
            res.status(200).json({
                status: 'success',
                message: 'Unit updated successfully',
                data: {
                    unit: updatedUnit.toJSON()
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Delete unit
    static async deleteUnit(req, res, next) {
        try {
            const { id } = req.params;
            const deleted = await Unit.delete(id);
            if (!deleted) {
                return res.status(404).json({
                    status: 'error',
                    message: 'Unit not found'
                });
            }
            res.status(200).json({
                status: 'success',
                message: 'Unit deleted successfully'
            });
        }
        catch (error) {
            if (error.message.includes('Cannot delete')) {
                return res.status(400).json({
                    status: 'error',
                    message: error.message
                });
            }
            next(error);
        }
    }
    // Get unit children
    static async getUnitChildren(req, res, next) {
        try {
            const { id } = req.params;
            const organization_id = req.user?.organization_id;
            const children = await Unit.getChildren(id, organization_id);
            res.status(200).json({
                status: 'success',
                message: 'Unit children retrieved successfully',
                data: {
                    parent_id: parseInt(id),
                    children: children.map(child => child.toJSON()),
                    total: children.length
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Get unit statistics
    static async getUnitStatistics(req, res, next) {
        try {
            const statistics = await Unit.getStatistics();
            res.status(200).json({
                status: 'success',
                message: 'Unit statistics retrieved successfully',
                data: {
                    statistics
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
}
module.exports = UnitController;
//# sourceMappingURL=unitController.js.map