const { validationResult } = require('express-validator');
const Organization = require('../models/Organization');
const { buildPublicUploadPath, ensureAbsoluteUrl } = require('../middleware/fileUpload');
const fs = require('fs');
const path = require('path');
class OrganizationController {
    static isSuperAdmin(user) {
        if (!user)
            return false;
        const roleName = (user.role || '').toLowerCase();
        return user.role_id === 1 || roleName === 'super admin'.toLowerCase() || roleName === 'super_admin'.toLowerCase();
    }
    // Helper function to convert relative logo path to full URL
    static addLogoUrl(req, organization) {
        try {
            if (!organization) {
                return null;
            }
            const orgJson = organization.toJSON ? organization.toJSON() : organization;
            if (!orgJson) {
                return null;
            }
            if (orgJson.logo) {
                const originalLogo = String(orgJson.logo);
                try {
                    // Always produce an absolute URL with normalized port for images
                    const absolute = ensureAbsoluteUrl(req, originalLogo);
                    orgJson.logo_url = absolute;
                    // For UI compatibility, expose absolute in logo as well
                    orgJson.logo = absolute;
                }
                catch (urlError) {
                    console.error('❌ Error converting organization logo URL:', urlError);
                    orgJson.logo_url = originalLogo;
                    orgJson.logo = originalLogo;
                }
            }
            return orgJson;
        }
        catch (error) {
            console.error('❌ Error in addLogoUrl:', error);
            try {
                const data = organization.toJSON ? organization.toJSON() : organization;
                if (data && data.logo)
                    data.logo_url = ensureAbsoluteUrl(req, data.logo);
                if (data && data.logo)
                    data.logo = ensureAbsoluteUrl(req, data.logo);
                return data;
            }
            catch {
                return null;
            }
        }
    }
    // Get all organizations
    static async getOrganizations(req, res, next) {
        try {
            const { page = 1, limit = 50, search = '', is_active = '', type = '' } = req.query;
            const options = {
                page: parseInt(page) || 1,
                limit: parseInt(limit) || 50,
                search,
                is_active,
                type
            };
            // Restrict non-super-admins to their own organization
            if (!OrganizationController.isSuperAdmin(req.user) && req.user && req.user.organization_id) {
                options.organization_id = parseInt(req.user.organization_id);
            }
            const result = await Organization.findAll(options);
            const statistics = await Organization.getStatistics();
            res.status(200).json({
                status: 'success',
                message: 'Organizations retrieved successfully',
                data: {
                    organizations: result.data.map(org => {
                        const orgWithLogo = OrganizationController.addLogoUrl(req, org);
                        return orgWithLogo || org.toJSON();
                    }).filter(Boolean),
                    statistics,
                    pagination: result.pagination
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Get organization by ID
    static async getOrganizationById(req, res, next) {
        try {
            const { id } = req.params;
            // Restrict non-super-admins to their own organization
            if (!OrganizationController.isSuperAdmin(req.user)) {
                if (!req.user || !req.user.organization_id || parseInt(id) !== parseInt(req.user.organization_id)) {
                    return res.status(403).json({
                        status: 'error',
                        message: 'Forbidden: You can only access your own organization'
                    });
                }
            }
            const organization = await Organization.findById(id);
            if (!organization) {
                return res.status(404).json({
                    status: 'error',
                    message: 'Organization not found'
                });
            }
            const organizationWithLogo = OrganizationController.addLogoUrl(req, organization) || organization.toJSON();
            res.status(200).json({
                status: 'success',
                message: 'Organization retrieved successfully',
                data: {
                    organization: organizationWithLogo
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Get organization statistics
    static async getStatistics(req, res, next) {
        try {
            const statistics = await Organization.getStatistics();
            res.status(200).json({
                status: 'success',
                message: 'Organization statistics retrieved successfully',
                data: statistics
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Get organization types
    static async getTypes(req, res, next) {
        try {
            const types = await Organization.getTypes();
            res.status(200).json({
                status: 'success',
                message: 'Organization types retrieved successfully',
                data: {
                    types
                }
            });
        }
        catch (error) {
            next(error);
        }
    }
    // Create new organization
    static async createOrganization(req, res, next) {
        try {
            // Validation errors
            const errors = validationResult(req);
            if (!errors.isEmpty()) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Validation failed',
                    errors: errors.array()
                });
            }
            // Parse FormData or JSON body
            const name = req.body.name;
            const code = req.body.code;
            const type = req.body.type || null;
            const description = req.body.description || null;
            const address = req.body.address || null;
            const phone = req.body.phone || null;
            const email = req.body.email || null;
            const website = req.body.website || null;
            const theme = req.body.theme || null;
            // Homepage view toggles (optional)
            const homepage_view_home = req.body.homepage_view_home === 'true' || req.body.homepage_view_home === true ? 1 : 0;
            const homepage_view_units = req.body.homepage_view_units === 'true' || req.body.homepage_view_units === true ? 1 : 0;
            const homepage_view_contacts = req.body.homepage_view_contacts === 'true' || req.body.homepage_view_contacts === true ? 1 : 0;
            const homepage_view_department_grid = req.body.homepage_view_department_grid === 'true' || req.body.homepage_view_department_grid === true ? 1 : 0;
            const department_grid_bool_input = (req.body.department_grid !== undefined ? req.body.department_grid : homepage_view_department_grid);
            const department_grid_bool = (department_grid_bool_input === 'true' || department_grid_bool_input === true || department_grid_bool_input === 1 || department_grid_bool_input === '1') ? 1 : 0;
            const auto_user_create_input = (req.body.auto_user_create !== undefined ? req.body.auto_user_create : req.body.auto_user_crete);
            const auto_user_create = auto_user_create_input === 'true' || auto_user_create_input === true ? 1 : 0;
            let department_grid = null;
            if (req.body.department_grid !== undefined) {
                const dg = req.body.department_grid;
                if (typeof dg === 'string') {
                    try {
                        department_grid = JSON.parse(dg);
                    }
                    catch {
                        department_grid = dg.split(',').map(s => {
                            const t = String(s).trim();
                            const n = Number(t);
                            return Number.isNaN(n) ? t : n;
                        });
                    }
                }
                else if (Array.isArray(dg)) {
                    department_grid = dg;
                }
                else if (typeof dg === 'object' && dg !== null) {
                    department_grid = dg;
                }
            }
            // Optional role permissions (array or JSON/string)
            let role_permissions = null;
            if (req.body.role_permissions !== undefined) {
                const rp = req.body.role_permissions;
                if (typeof rp === 'string') {
                    try {
                        // Try parse JSON string
                        role_permissions = JSON.parse(rp);
                    }
                    catch {
                        // Fallback: treat as comma-separated
                        role_permissions = rp.split(',').map(s => {
                            const t = String(s).trim();
                            const n = Number(t);
                            return Number.isNaN(n) ? t : n;
                        });
                    }
                }
                else if (Array.isArray(rp)) {
                    role_permissions = rp;
                }
                else if (typeof rp === 'object' && rp !== null) {
                    role_permissions = rp;
                }
            }
            let required_field_permissions = null;
            if (req.body.required_field_permissions !== undefined) {
                const rfp = req.body.required_field_permissions;
                if (typeof rfp === 'string') {
                    try {
                        required_field_permissions = JSON.parse(rfp);
                    }
                    catch {
                        required_field_permissions = rfp.split(',').map(s => String(s).trim()).filter(Boolean);
                    }
                }
                else if (Array.isArray(rfp)) {
                    required_field_permissions = rfp;
                }
                else if (typeof rfp === 'object' && rfp !== null) {
                    required_field_permissions = rfp;
                }
            }
            let logoPath = null;
            if (req.file) {
                logoPath = buildPublicUploadPath('organization', req.file.filename);
                if (logoPath && !logoPath.startsWith('/')) {
                    logoPath = '/' + logoPath;
                }
            }
            else if (req.body.logo) {
                const value = String(req.body.logo);
                if (value.startsWith('data:image/')) {
                    try {
                        const match = value.match(/^data:(image\/[a-zA-Z0-9.+-]+);base64,(.+)$/);
                        if (match) {
                            const mime = match[1];
                            const base64 = match[2];
                            const extRaw = mime.split('/')[1];
                            const ext = extRaw === 'jpeg' ? 'jpg' : extRaw;
                            const filename = `${Date.now()}-${Math.round(Math.random() * 1e9)}.${ext}`;
                            const dir = path.resolve(__dirname, '..', '..', 'public', 'Images', 'organization');
                            fs.mkdirSync(dir, { recursive: true });
                            fs.writeFileSync(path.join(dir, filename), Buffer.from(base64, 'base64'));
                            logoPath = buildPublicUploadPath('organization', filename);
                            if (logoPath && !logoPath.startsWith('/')) {
                                logoPath = '/' + logoPath;
                            }
                        }
                        else {
                            logoPath = value;
                        }
                    }
                    catch {
                        logoPath = value;
                    }
                }
                else {
                    logoPath = value;
                }
            }
            const organizationData = {
                name,
                code,
                type,
                description,
                address,
                phone,
                email,
                website,
                logo: logoPath,
                theme,
                created_by: req.user ? req.user.id : null,
                role_permissions,
                homepage_view_home,
                homepage_view_units,
                homepage_view_contacts,
                homepage_view_department_grid,
                auto_user_create,
                department_grid: department_grid_bool,
                required_field_permissions
            };
            const organizationId = await Organization.create(organizationData);
            const organization = await Organization.findById(organizationId);
            const organizationWithLogo = OrganizationController.addLogoUrl(req, organization) || organization.toJSON();
            res.status(201).json({
                status: 'success',
                message: 'Organization created successfully',
                data: {
                    organization: organizationWithLogo
                }
            });
        }
        catch (error) {
            // Handle duplicate code error
            if (error.message.includes('Duplicate entry')) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Organization code already exists',
                    error: error.message
                });
            }
            next(error);
        }
    }
    // Update organization
    static async updateOrganization(req, res, next) {
        try {
            // Validation errors
            const errors = validationResult(req);
            if (!errors.isEmpty()) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Validation failed',
                    errors: errors.array()
                });
            }
            const { id } = req.params;
            // Parse FormData or JSON body
            const name = req.body.name;
            const code = req.body.code;
            const type = req.body.type;
            const description = req.body.description;
            const address = req.body.address;
            const phone = req.body.phone;
            const email = req.body.email;
            const website = req.body.website;
            const theme = req.body.theme;
            const is_active = req.body.is_active;
            const homepage_view_home = req.body.homepage_view_home;
            const homepage_view_units = req.body.homepage_view_units;
            const homepage_view_contacts = req.body.homepage_view_contacts;
            const homepage_view_department_grid = req.body.homepage_view_department_grid;
            const department_grid_bool_input_update = (req.body.department_grid !== undefined ? req.body.department_grid : homepage_view_department_grid);
            const department_grid_bool_update = (department_grid_bool_input_update === 'true' || department_grid_bool_input_update === true || department_grid_bool_input_update === 1 || department_grid_bool_input_update === '1') ? 1 : 0;
            const auto_user_create = (req.body.auto_user_create !== undefined ? req.body.auto_user_create : req.body.auto_user_crete);
            // Optional role permissions
            let role_permissions = undefined;
            if (req.body.role_permissions !== undefined) {
                const rp = req.body.role_permissions;
                if (typeof rp === 'string') {
                    try {
                        role_permissions = JSON.parse(rp);
                    }
                    catch {
                        role_permissions = rp.split(',').map(s => {
                            const t = String(s).trim();
                            const n = Number(t);
                            return Number.isNaN(n) ? t : n;
                        });
                    }
                }
                else if (Array.isArray(rp)) {
                    role_permissions = rp;
                }
                else if (typeof rp === 'object' && rp !== null) {
                    role_permissions = rp;
                }
                else if (rp === null) {
                    role_permissions = null;
                }
            }
            let required_field_permissions = undefined;
            if (req.body.required_field_permissions !== undefined) {
                const rfp = req.body.required_field_permissions;
                if (typeof rfp === 'string') {
                    try {
                        required_field_permissions = JSON.parse(rfp);
                    }
                    catch {
                        required_field_permissions = rfp.split(',').map(s => String(s).trim()).filter(Boolean);
                    }
                }
                else if (Array.isArray(rfp)) {
                    required_field_permissions = rfp;
                }
                else if (typeof rfp === 'object' && rfp !== null) {
                    required_field_permissions = rfp;
                }
                else if (rfp === null) {
                    required_field_permissions = null;
                }
            }
            // Check if organization exists
            const existingOrganization = await Organization.findById(id);
            if (!existingOrganization) {
                return res.status(404).json({
                    status: 'error',
                    message: 'Organization not found'
                });
            }
            const updateData = {};
            if (name !== undefined)
                updateData.name = name;
            if (code !== undefined)
                updateData.code = code;
            if (type !== undefined)
                updateData.type = type;
            if (description !== undefined)
                updateData.description = description;
            if (address !== undefined)
                updateData.address = address;
            if (phone !== undefined)
                updateData.phone = phone;
            if (email !== undefined)
                updateData.email = email;
            if (website !== undefined)
                updateData.website = website;
            if (theme !== undefined)
                updateData.theme = theme;
            if (is_active !== undefined)
                updateData.is_active = is_active;
            if (homepage_view_home !== undefined)
                updateData.homepage_view_home = homepage_view_home === 'true' || homepage_view_home === true;
            if (homepage_view_units !== undefined)
                updateData.homepage_view_units = homepage_view_units === 'true' || homepage_view_units === true;
            if (homepage_view_contacts !== undefined)
                updateData.homepage_view_contacts = homepage_view_contacts === 'true' || homepage_view_contacts === true;
            if (homepage_view_department_grid !== undefined)
                updateData.homepage_view_department_grid = homepage_view_department_grid === 'true' || homepage_view_department_grid === true;
            if (department_grid_bool_input_update !== undefined)
                updateData.department_grid = department_grid_bool_update === 1;
            if (role_permissions !== undefined)
                updateData.role_permissions = role_permissions;
            if (required_field_permissions !== undefined)
                updateData.required_field_permissions = required_field_permissions;
            if (auto_user_create !== undefined)
                updateData.auto_user_create = auto_user_create === 'true' || auto_user_create === true;
            // department_grid previously accepted arrays/JSON; now normalize to boolean only via department_grid_bool_update
            if (req.file) {
                // Delete old logo if exists
                if (existingOrganization.logo) {
                    try {
                        const oldLogoPath = existingOrganization.logo;
                        // Only delete if it's a relative path (not a full URL)
                        if (!oldLogoPath.startsWith('http://') && !oldLogoPath.startsWith('https://')) {
                            const fullPath = path.resolve(__dirname, '..', '..', 'public', oldLogoPath);
                            if (fs.existsSync(fullPath)) {
                                fs.unlinkSync(fullPath);
                                console.log('🗑️ Deleted old organization logo:', fullPath);
                            }
                        }
                    }
                    catch (deleteError) {
                        console.error('⚠️ Error deleting old organization logo:', deleteError);
                        // Continue with update even if delete fails
                    }
                }
                // Save only relative path in database
                updateData.logo = buildPublicUploadPath('organization', req.file.filename);
                // Ensure it's a relative path (starts with /)
                if (updateData.logo && !updateData.logo.startsWith('/')) {
                    updateData.logo = '/' + updateData.logo;
                }
            }
            else if (req.body.remove_logo === 'true' || req.body.remove_logo === true) {
                // Remove logo
                if (existingOrganization.logo) {
                    try {
                        const oldLogoPath = existingOrganization.logo;
                        // Only delete if it's a relative path (not a full URL)
                        if (!oldLogoPath.startsWith('http://') && !oldLogoPath.startsWith('https://')) {
                            const fullPath = path.resolve(__dirname, '..', '..', 'public', oldLogoPath);
                            if (fs.existsSync(fullPath)) {
                                fs.unlinkSync(fullPath);
                                console.log('🗑️ Deleted organization logo:', fullPath);
                            }
                        }
                    }
                    catch (deleteError) {
                        console.error('⚠️ Error deleting organization logo:', deleteError);
                    }
                }
                updateData.logo = null;
            }
            else if (req.body.logo !== undefined) {
                const value = String(req.body.logo);
                if (value.startsWith('data:image/')) {
                    try {
                        const match = value.match(/^data:(image\/[a-zA-Z0-9.+-]+);base64,(.+)$/);
                        if (match) {
                            const mime = match[1];
                            const base64 = match[2];
                            const extRaw = mime.split('/')[1];
                            const ext = extRaw === 'jpeg' ? 'jpg' : extRaw;
                            const filename = `${Date.now()}-${Math.round(Math.random() * 1e9)}.${ext}`;
                            const dir = path.resolve(__dirname, '..', '..', 'public', 'Images', 'organization');
                            fs.mkdirSync(dir, { recursive: true });
                            fs.writeFileSync(path.join(dir, filename), Buffer.from(base64, 'base64'));
                            updateData.logo = buildPublicUploadPath('organization', filename);
                            if (updateData.logo && !updateData.logo.startsWith('/')) {
                                updateData.logo = '/' + updateData.logo;
                            }
                        }
                        else {
                            updateData.logo = value;
                        }
                    }
                    catch {
                        updateData.logo = value;
                    }
                }
                else {
                    updateData.logo = value;
                }
            }
            await Organization.update(id, updateData);
            const organization = await Organization.findById(id);
            const organizationWithLogo = OrganizationController.addLogoUrl(req, organization) || organization.toJSON();
            res.status(200).json({
                status: 'success',
                message: 'Organization updated successfully',
                data: {
                    organization: organizationWithLogo
                }
            });
        }
        catch (error) {
            // Handle duplicate code error
            if (error.message.includes('Duplicate entry')) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Organization code already exists',
                    error: error.message
                });
            }
            next(error);
        }
    }
    // Delete organization
    static async deleteOrganization(req, res, next) {
        try {
            const { id } = req.params;
            // Check if organization exists
            const organization = await Organization.findById(id);
            if (!organization) {
                return res.status(404).json({
                    status: 'error',
                    message: 'Organization not found'
                });
            }
            // Prevent deletion of default organization (ID: 1)
            if (parseInt(id) === 1) {
                return res.status(400).json({
                    status: 'error',
                    message: 'Cannot delete the default organization'
                });
            }
            await Organization.delete(id);
            res.status(200).json({
                status: 'success',
                message: 'Organization deleted successfully'
            });
        }
        catch (error) {
            if (error.message.includes('Cannot delete organization')) {
                return res.status(400).json({
                    status: 'error',
                    message: error.message
                });
            }
            next(error);
        }
    }
}
module.exports = OrganizationController;
//# sourceMappingURL=organizationController.js.map