const AboutUs = require('../models/AboutUs'); const { saveOptimizedImage, removeStoredFile } = require('../services/mediaService'); const { asyncController } = require('../utils/asyncController'); const stripHtml = (value) => String(value || '').replace(/<[^>]*>/g, ''); const normalizeStringArray = (value) => { if (Array.isArray(value)) { return value.map((item) => String(item).trim()).filter(Boolean); } if (value === undefined || value === null) { return []; } const raw = String(value).trim(); if (!raw) return []; try { const parsed = JSON.parse(raw); if (Array.isArray(parsed)) { return parsed.map((item) => String(item).trim()).filter(Boolean); } } catch { // Fallback to single-value handling when value is not JSON. } return [raw]; }; const normalizeRooms = (value) => { if (value === undefined || value === null) { return []; } let parsed = value; if (!Array.isArray(parsed)) { const raw = String(value).trim(); if (!raw) return []; try { parsed = JSON.parse(raw); } catch { parsed = []; } } if (!Array.isArray(parsed)) return []; return parsed.map((item) => { if (!item || typeof item !== 'object') { return { title: String(item || '').trim(), image: '', }; } return { title: String(item.title || '').trim(), image: String(item.image || '').trim(), }; }); }; const mapUploadedFilesByField = (req) => { const filesByField = {}; if (Array.isArray(req.files)) { req.files.forEach((file) => { if (!file?.fieldname) return; if (!filesByField[file.fieldname]) filesByField[file.fieldname] = []; filesByField[file.fieldname].push(file); }); } else if (req.files && typeof req.files === 'object') { Object.entries(req.files).forEach(([field, files]) => { if (!Array.isArray(files)) return; filesByField[field] = files; }); } if (req.file?.fieldname) { filesByField[req.file.fieldname] = [req.file]; } return filesByField; }; // GET /api/about-us — public const getAboutUs = asyncController(async (req, res) => { const doc = await AboutUs.findOne({ slug: 'main' }).lean(); if (!doc) { return res.json({ greeting: '', vision: '', mission: [], objectives: [], studyProgramObjectives: '', scientificVision: [], headPhoto: '', locationText: '', locationPhoto: '', mapsEmbedUrl: '', programs: [], rooms: [], }); } return res.json({ greeting: doc.greeting || '', vision: doc.vision || '', mission: Array.isArray(doc.mission) ? doc.mission : [], objectives: Array.isArray(doc.objectives) ? doc.objectives : [], studyProgramObjectives: doc.studyProgramObjectives || '', scientificVision: Array.isArray(doc.scientificVision) ? doc.scientificVision : [], headPhoto: doc.headPhoto || '', locationText: doc.locationText || '', locationPhoto: doc.locationPhoto || '', mapsEmbedUrl: doc.mapsEmbedUrl || '', programs: Array.isArray(doc.programs) ? doc.programs : [], rooms: Array.isArray(doc.rooms) ? doc.rooms .map((room) => ({ title: String(room?.title || '').trim(), image: String(room?.image || '').trim(), })) .filter((room) => room.title || room.image) : [], }); }); // PUT /api/about-us — admin only const updateAboutUs = asyncController(async (req, res) => { const { greeting, vision, mission, objectives, studyProgramObjectives, scientificVision, locationText, mapsEmbedUrl, programs, rooms } = req.body; const currentDoc = await AboutUs.findOne({ slug: 'main' }).lean(); const filesByField = mapUploadedFilesByField(req); const headPhotoFile = filesByField.headPhoto?.[0]; const locationPhotoFile = filesByField.locationPhoto?.[0]; const payload = {}; if (greeting !== undefined) payload.greeting = stripHtml(String(greeting).trim()); if (vision !== undefined) payload.vision = stripHtml(String(vision).trim()); if (mission !== undefined) { payload.mission = normalizeStringArray(mission).map(stripHtml); } if (objectives !== undefined) { payload.objectives = normalizeStringArray(objectives).map(stripHtml); } if (studyProgramObjectives !== undefined) { payload.studyProgramObjectives = stripHtml(String(studyProgramObjectives).trim()); } if (scientificVision !== undefined) { payload.scientificVision = normalizeStringArray(scientificVision).map(stripHtml); } if (locationText !== undefined) { payload.locationText = stripHtml(String(locationText).trim()); } if (mapsEmbedUrl !== undefined) { let rawUrl = String(mapsEmbedUrl).trim(); // If user accidentally pasted a full