const PatientReport = require('../models/PatientReport');
const FluidsAdministered = require('../models/FluidsAdministered');
const Drug = require('../models/Drug');
const DrugsAdministered = require('../models/DrugsAdministered');
const Observation = require('../models/Observation');
const PatientReportEmail = require('../models/PatientReportEmail');

// Get patient report by request ID
const getPatientReportByRequestId = async (req, res) => {
    try {
        const { requestId } = req.params;
        
        if (!requestId) {
            return res.status(400).json({ error: 'Request ID is required' });
        }

        const patientReport = await PatientReport.getWithDetails(requestId);
        
        if (!patientReport) {
            return res.status(404).json({ error: 'Patient report not found' });
        }

        res.json(patientReport);
    } catch (error) {
        console.error('Error fetching patient report:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Create or update patient report
const createOrUpdatePatientReport = async (req, res) => {
    try {
        const { requestId } = req.params;
        const {
            incident_type_id,
            general_complaints,
            impression,
            patient_allergies,
            patient_past_history,
            patient_admitting_hospital,
            fluids,
            drugs,
            observations
        } = req.body;

        if (!requestId) {
            return res.status(400).json({ error: 'Request ID is required' });
        }

        // Check if patient report already exists for this request
        let patientReport = await PatientReport.findByRequestId(requestId);
        let patientReportId;

        if (patientReport) {
            // Update existing report
            await PatientReport.update(patientReport.id, {
                incident_type_id,
                general_complaints,
                impression,
                patient_allergies,
                patient_past_history,
                patient_admitting_hospital
            });
            patientReportId = patientReport.id;
        } else {
            // Create new report
            patientReportId = await PatientReport.create({
                request_id: requestId,
                incident_type_id,
                general_complaints,
                impression,
                patient_allergies,
                patient_past_history,
                patient_admitting_hospital
            });
        }

        // Handle fluids
        if (fluids && Array.isArray(fluids)) {
            for (const fluid of fluids) {
                if (fluid.id) {
                    // Update existing fluid
                    await FluidsAdministered.update(fluid.id, {
                        fluid_name: fluid.fluid_name,
                        volume: fluid.volume,
                        time_given: fluid.time_given
                    });
                } else {
                    // Create new fluid
                    await FluidsAdministered.create({
                        patient_report_id: patientReportId,
                        fluid_name: fluid.fluid_name,
                        volume: fluid.volume,
                        time_given: fluid.time_given
                    });
                }
            }
        }

        // Handle drugs
        if (drugs && Array.isArray(drugs)) {
            for (const drug of drugs) {
                if (drug.id) {
                    // Update existing drug
                    await DrugsAdministered.update(drug.id, {
                        drug_id: drug.drug_id,
                        dose: drug.dose,
                        route: drug.route,
                        time_given: drug.time_given
                    });
                } else {
                    // Create new drug
                    await DrugsAdministered.create({
                        patient_report_id: patientReportId,
                        drug_id: drug.drug_id,
                        dose: drug.dose,
                        route: drug.route,
                        time_given: drug.time_given
                    });
                }
            }
        }

        // Handle observations
        if (observations && Array.isArray(observations)) {
            for (const observation of observations) {
                if (observation.id) {
                    // Update existing observation
                    await Observation.update(observation.id, {
                        observation: observation.observation,
                        value: observation.value
                    });
                } else {
                    // Create new observation
                    await Observation.create({
                        patient_report_id: patientReportId,
                        observation: observation.observation,
                        value: observation.value
                    });
                }
            }
        }

        // Get updated patient report with all details
        const updatedReport = await PatientReport.getWithDetails(requestId);
        
        res.status(patientReport ? 200 : 201).json(updatedReport);
    } catch (error) {
        console.error('Error creating/updating patient report:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Get all drugs for selection
const getAllDrugs = async (req, res) => {
    try {
        const drugs = await Drug.findAll();
        res.json(drugs);
    } catch (error) {
        console.error('Error fetching drugs:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Create new drug
const createDrug = async (req, res) => {
    try {
        const { name, type } = req.body;

        if (!name) {
            return res.status(400).json({ error: 'Drug name is required' });
        }

        // Check if drug already exists
        const existingDrug = await Drug.findByName(name);
        if (existingDrug) {
            return res.status(400).json({ error: 'Drug already exists' });
        }

        const drugId = await Drug.create({ name, type });
        const drug = await Drug.findById(drugId);
        
        res.status(201).json(drug);
    } catch (error) {
        console.error('Error creating drug:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Get observation types
const getObservationTypes = async (req, res) => {
    try {
        const observationTypes = Observation.getObservationTypes();
        res.json(observationTypes);
    } catch (error) {
        console.error('Error fetching observation types:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Delete fluid
const deleteFluid = async (req, res) => {
    try {
        const { id } = req.params;
        
        if (!id) {
            return res.status(400).json({ error: 'Fluid ID is required' });
        }

        const deleted = await FluidsAdministered.delete(id);
        
        if (!deleted) {
            return res.status(404).json({ error: 'Fluid not found' });
        }

        res.json({ message: 'Fluid deleted successfully' });
    } catch (error) {
        console.error('Error deleting fluid:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Delete drug
const deleteDrug = async (req, res) => {
    try {
        const { id } = req.params;
        
        if (!id) {
            return res.status(400).json({ error: 'Drug ID is required' });
        }

        const deleted = await DrugsAdministered.delete(id);
        
        if (!deleted) {
            return res.status(404).json({ error: 'Drug not found' });
        }

        res.json({ message: 'Drug deleted successfully' });
    } catch (error) {
        console.error('Error deleting drug:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Delete observation
const deleteObservation = async (req, res) => {
    try {
        const { id } = req.params;
        
        if (!id) {
            return res.status(400).json({ error: 'Observation ID is required' });
        }

        const deleted = await Observation.delete(id);
        
        if (!deleted) {
            return res.status(404).json({ error: 'Observation not found' });
        }

        res.json({ message: 'Observation deleted successfully' });
    } catch (error) {
        console.error('Error deleting observation:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Update existing fluid
const updateFluid = async (req, res) => {
    try {
        const { id } = req.params;
        const { fluid_name, volume, time_given } = req.body;
        
        if (!id) {
            return res.status(400).json({ error: 'Fluid ID is required' });
        }

        const updated = await FluidsAdministered.update(id, { fluid_name, volume, time_given });
        
        if (!updated) {
            return res.status(404).json({ error: 'Fluid not found' });
        }

        res.json({ message: 'Fluid updated successfully' });
    } catch (error) {
        console.error('Error updating fluid:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Update existing drug
const updateDrug = async (req, res) => {
    try {
        const { id } = req.params;
        const { drug_id, dose, route, time_given } = req.body;
        
        if (!id) {
            return res.status(400).json({ error: 'Drug ID is required' });
        }

        const updated = await DrugsAdministered.update(id, { drug_id, dose, route, time_given });
        
        if (!updated) {
            return res.status(404).json({ error: 'Drug not found' });
        }

        res.json({ message: 'Drug updated successfully' });
    } catch (error) {
        console.error('Error updating drug:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Update existing observation
const updateObservation = async (req, res) => {
    try {
        const { id } = req.params;
        const { observation, value } = req.body;
        
        if (!id) {
            return res.status(400).json({ error: 'Observation ID is required' });
        }

        const updated = await Observation.update(id, { observation, value });
        
        if (!updated) {
            return res.status(404).json({ error: 'Observation not found' });
        }

        res.json({ message: 'Observation updated successfully' });
    } catch (error) {
        console.error('Error updating observation:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

// Get patient report by email and code (public access)
const getPatientReportByEmailAndCode = async (req, res) => {
    try {
        const { email, code } = req.body;
        
        if (!email || !code) {
            return res.status(400).json({ error: 'Email and code are required' });
        }

        // Find patient report email record
        const patientReportEmail = await PatientReportEmail.findByEmailAndCode(email, code);
        
        if (!patientReportEmail) {
            return res.status(404).json({ error: 'Invalid email or code' });
        }

        // Get complete patient report with details
        const patientReport = await PatientReportEmail.getPatientReportWithDetails(patientReportEmail.patient_report_id);
        
        if (!patientReport) {
            return res.status(404).json({ error: 'Patient report not found' });
        }

        res.json(patientReport);
    } catch (error) {
        console.error('Error fetching patient report by email and code:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

module.exports = {
    getPatientReportByRequestId,
    createOrUpdatePatientReport,
    getAllDrugs,
    createDrug,
    getObservationTypes,
    updateFluid,
    updateDrug,
    updateObservation,
    deleteFluid,
    deleteDrug,
    deleteObservation,
    getPatientReportByEmailAndCode
};
