import prisma from '../prisma/client.js'; // get doctors export const getAllDoctors = async (req, res) => { try { const { admin } = req.query; const doctors = await prisma.doctor.findMany({ where: admin === 'true' ? {} : { isActive: true }, include: { seo: true, departments: { include: { department: true, timing: true, }, }, specializations: { orderBy: { createdAt: 'asc', }, }, }, orderBy: [{ globalSortOrder: 'asc' }, { name: 'asc' }], }); const formatted = doctors.map((doc, index) => ({ SL_NO: String(index + 1), doctorId: doc.doctorId, name: doc.name, image: doc.image ?? '', designation: doc.designation, workingStatus: doc.workingStatus, qualification: doc.qualification, isActive: doc.isActive, experience: doc.experience, professionalSummary: doc.professionalSummary, globalSortOrder: doc.globalSortOrder, specializations: doc.specializations.map((item) => ({ id: item.id, name: item.name, description: item.description, })), seo: { seoTitle: doc.seo?.seoTitle ?? '', metaDescription: doc.seo?.metaDescription ?? '', focusKeyphrase: doc.seo?.focusKeyphrase ?? '', slug: doc.seo?.slug ?? '', tags: doc.seo?.tags ?? [], ogTitle: doc.seo?.ogTitle ?? '', ogDescription: doc.seo?.ogDescription ?? '', ogImage: doc.seo?.ogImage ?? '', }, departments: doc.departments.map((d) => { const t = d.timing || {}; const timingArray = [ t.monday && `Monday ${t.monday}`, t.tuesday && `Tuesday ${t.tuesday}`, t.wednesday && `Wednesday ${t.wednesday}`, t.thursday && `Thursday ${t.thursday}`, t.friday && `Friday ${t.friday}`, t.saturday && `Saturday ${t.saturday}`, t.sunday && `Sunday ${t.sunday}`, t.additional && t.additional, ].filter(Boolean); return { departmentId: d.department.departmentId, departmentName: d.department.name, timing: timingArray.join(' & '), deptSortOrder: d.sortOrder, }; }), })); res.status(200).json({ success: true, data: formatted, }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: 'Failed to fetch doctors', }); } }; // get doctor by id export const getDoctorByDoctorId = async (req, res) => { try { const { doctorId } = req.params; const { admin } = req.query; const doctor = await prisma.doctor.findFirst({ where: { doctorId, ...(admin === 'true' ? {} : { isActive: true }), }, include: { seo: true, specializations: true, departments: { include: { department: true, timing: true, }, }, }, }); if (!doctor) { return res.status(404).json({ success: false, message: 'Doctor not found', }); } const response = { doctorId: doctor.doctorId, name: doctor.name, image: doctor.image ?? '', designation: doctor.designation, workingStatus: doctor.workingStatus, qualification: doctor.qualification, experience: doctor.experience, professionalSummary: doctor.professionalSummary, isActive: doctor.isActive, seo: { seoTitle: doctor.seo?.seoTitle ?? '', metaDescription: doctor.seo?.metaDescription ?? '', focusKeyphrase: doctor.seo?.focusKeyphrase ?? '', slug: doctor.seo?.slug ?? '', tags: doctor.seo?.tags ?? [], ogTitle: doctor.seo?.ogTitle ?? '', ogDescription: doctor.seo?.ogDescription ?? '', ogImage: doctor.seo?.ogImage ?? '', }, specializations: doctor.specializations?.map((item) => ({ id: item.id, name: item.name, description: item.description, })) ?? [], departments: doctor.departments.map((d) => ({ departmentId: d.department.departmentId, departmentName: d.department.name, timing: d.timing || {}, })), }; res.status(200).json({ success: true, data: response, }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: 'Failed to fetch doctor', }); } }; // get doctors by department export const getDoctorsByDepartmentId = async (req, res) => { try { const { Department_ID } = req.query; if (!Department_ID) { return res.status(400).json({ success: false, message: 'Department_ID is required', }); } const department = await prisma.department.findUnique({ where: { departmentId: Department_ID }, }); if (!department) { return res.status(404).json({ success: false, message: 'Department not found', }); } const doctorsInDept = await prisma.doctorDepartment.findMany({ where: { departmentId: department.id, doctor: { isActive: true }, }, include: { doctor: { include: { seo: { select: { slug: true, }, }, }, }, }, orderBy: { sortOrder: 'asc' }, }); const result = doctorsInDept.map((d) => ({ GG_ID: d.doctor.doctorId, Name: d.doctor.name, image: d.doctor.image ?? '', designation: d.doctor.designation, hierarchyOrder: d.sortOrder, slug: d.doctor.seo?.slug ?? '', })); res.status(200).json({ success: true, data: result, }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: 'Failed to fetch doctors', }); } }; // add doctors export const createDoctor = async (req, res) => { try { const { doctorId, name, image, designation, workingStatus, qualification, isActive, globalSortOrder, departments, experience, professionalSummary, seoTitle, metaDescription, focusKeyphrase, slug, tags, specializations, ogTitle, ogDescription, ogImage, } = req.body; const messages = []; if (!doctorId) messages.push('Doctor ID is required'); if (!name?.trim()) messages.push('Doctor name is required'); if (!designation?.trim()) messages.push('Designation is required'); if (!qualification?.trim()) messages.push('Qualification is required'); if (!departments || departments.length === 0) { messages.push('At least one department is required'); } if (messages.length > 0) { return res.status(400).json({ success: false, message: messages.join(', '), }); } const seo = await prisma.seo.create({ data: { seoTitle, metaDescription, focusKeyphrase, slug: slug ? slug : null, tags: tags || [], // Open Graph ogTitle, ogDescription, ogImage, }, }); const doctor = await prisma.doctor.create({ data: { doctorId, name, image, designation, workingStatus, qualification, experience: experience ? Number(experience) : null, professionalSummary, seoId: seo.id, isActive: isActive !== undefined ? isActive : true, globalSortOrder: globalSortOrder !== undefined ? Number(globalSortOrder) : 0, }, }); for (const dep of departments) { const department = await prisma.department.findUnique({ where: { departmentId: dep.departmentId }, }); if (!department) continue; const doctorDepartment = await prisma.doctorDepartment.create({ data: { doctorId: doctor.id, departmentId: department.id, sortOrder: dep.sortOrder !== undefined ? Number(dep.sortOrder) : 0, }, }); if (dep.timing) { await prisma.doctorTiming.create({ data: { doctorDepartmentId: doctorDepartment.id, ...dep.timing, }, }); } } if (specializations?.length) { await prisma.doctorSpecialization.createMany({ data: specializations .filter((item) => item.name?.trim()) .map((item) => ({ name: item.name.trim(), description: item.description?.trim() || null, doctorId: doctor.id, })), }); } res.status(201).json({ success: true, message: 'Doctor created successfully', }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: 'Failed to create doctor', }); } }; //update doctors export const updateDoctor = async (req, res) => { try { const { doctorId, action } = req.params; const { name, designation, image, workingStatus, qualification, isActive, globalSortOrder, departments, experience, professionalSummary, seoTitle, metaDescription, ogTitle, ogDescription, focusKeyphrase, slug, tags, ogImage, specializations, } = req.body; if (!doctorId) { return res.status(400).json({ success: false, message: 'Doctor ID is required', }); } const doctor = await prisma.doctor.findUnique({ where: { doctorId } }); if (!doctor) return res.status(404).json({ success: false, message: 'Doctor not found' }); if (action === 'toggleStatus') { await prisma.doctor.update({ where: { id: doctor.id }, data: { isActive: !doctor.isActive, }, }); return res.status(200).json({ success: true, message: `Doctor has been ${doctor.isActive ? 'deactivated' : 'activated'} successfully`, }); } const messages = []; if (!doctorId) messages.push('Doctor ID is required'); if (!name?.trim()) messages.push('Doctor name is required'); if (!qualification?.trim()) messages.push('Qualification is required'); if (!designation?.trim()) messages.push('Designation is required'); if (!departments || departments.length === 0) { messages.push('At least one department is required'); } if (messages.length > 0) { return res.status(400).json({ success: false, message: messages.join(', '), }); } await prisma.doctor.update({ where: { id: doctor.id }, data: { name, designation, image, workingStatus, qualification, isActive, experience: experience ? Number(experience) : null, professionalSummary, globalSortOrder: globalSortOrder !== undefined ? Number(globalSortOrder) : undefined, }, }); if (doctor.seoId) { await prisma.seo.update({ where: { id: doctor.seoId, }, data: { seoTitle, metaDescription, ogTitle, ogDescription, ogImage, focusKeyphrase, slug: slug ? slug : null, tags: tags || [], }, }); } else { const seo = await prisma.seo.create({ data: { ogImage, metaDescription, seoTitle, ogDescription, ogTitle, focusKeyphrase, slug: slug ? slug : null, tags: tags || [], }, }); await prisma.doctor.update({ where: { id: doctor.id, }, data: { seoId: seo.id, }, }); } // Update Departments & Timings if (Array.isArray(departments)) { const oldRelations = await prisma.doctorDepartment.findMany({ where: { doctorId: doctor.id, }, include: { timing: true, }, }); // Delete old timings for (const rel of oldRelations) { if (rel.timing) { await prisma.doctorTiming.deleteMany({ where: { doctorDepartmentId: rel.id, }, }); } } // Delete old departments await prisma.doctorDepartment.deleteMany({ where: { doctorId: doctor.id, }, }); // Recreate departments + timings for (const dep of departments) { const department = await prisma.department.findUnique({ where: { departmentId: dep.departmentId, }, }); if (!department) continue; const doctorDepartment = await prisma.doctorDepartment.create({ data: { doctorId: doctor.id, departmentId: department.id, sortOrder: dep.sortOrder !== undefined ? Number(dep.sortOrder) : 0, }, }); if (dep.timing && Object.keys(dep.timing).length > 0) { const { id, doctorDepartmentId, createdAt, updatedAt, ...cleanTiming } = dep.timing; await prisma.doctorTiming.create({ data: { doctorDepartmentId: doctorDepartment.id, ...cleanTiming, }, }); } } } // Update Specializations if (Array.isArray(specializations)) { await prisma.doctorSpecialization.deleteMany({ where: { doctorId: doctor.id, }, }); if (specializations.length) { await prisma.doctorSpecialization.createMany({ data: specializations .filter((item) => item.name?.trim()) .map((item) => ({ name: item.name.trim(), description: item.description?.trim() || null, doctorId: doctor.id, })), }); } } res.status(200).json({ success: true, message: 'Doctor updated successfully' }); } catch (error) { console.error('Update Error:', error); res.status(500).json({ success: false, message: 'Failed to update doctor' }); } }; //delete doctor export const deleteDoctor = async (req, res) => { try { const { doctorId } = req.params; const doctor = await prisma.doctor.findUnique({ where: { doctorId }, }); if (!doctor) { return res.status(404).json({ success: false, message: 'Doctor not found', }); } const doctorDepartments = await prisma.doctorDepartment.findMany({ where: { doctorId: doctor.id }, }); for (const dd of doctorDepartments) { await prisma.doctorTiming.deleteMany({ where: { doctorDepartmentId: dd.id }, }); } await prisma.doctorDepartment.deleteMany({ where: { doctorId: doctor.id }, }); await prisma.doctor.delete({ where: { id: doctor.id }, }); res.status(200).json({ success: true, message: 'Doctor deleted successfully', }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: 'Failed to delete doctor', }); } }; // get doctor timings export const getDoctorTimings = async (req, res) => { try { const doctors = await prisma.doctor.findMany({ include: { departments: { include: { timing: true, }, }, }, }); const result = doctors.map((doc) => { const timing = doc.departments[0]?.timing || {}; return { Doctor_ID: doc.doctorId, Doctor: doc.name, Monday: timing.monday || '', Tuesday: timing.tuesday || '', Wednesday: timing.wednesday || '', Thursday: timing.thursday || '', Friday: timing.friday || '', Saturday: timing.saturday || '', Sunday: timing.sunday || '', Additional: timing.additional || '', }; }); res.status(200).json({ success: true, data: result, }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: 'Failed to fetch doctor timings', }); } }; // get doctor timings by id export const getDoctorTimingById = async (req, res) => { try { const { doctorId } = req.params; const { admin } = req.query; const doctor = await prisma.doctor.findFirst({ where: { doctorId, ...(admin === 'true' ? {} : { isActive: true }), }, include: { departments: { include: { department: true, timing: true, }, }, }, }); if (!doctor) { return res.status(404).json({ success: false, message: 'Doctor not found', }); } const result = { doctorId: doctor.doctorId, doctorName: doctor.name, departments: doctor.departments.map((d) => ({ departmentId: d.department.departmentId, departmentName: d.department.name, deptSortOrder: d.sortOrder, timing: d.timing || {}, })), }; res.status(200).json({ success: true, data: result, }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: 'Failed to fetch doctor timing', }); } };