import { connection } from "../configs/db.js";
import { verifyCookies } from "../auth/auth.js";
import express from "express";

const appointmentRouter = express.Router();

// reusable JOIN query

const appointmentJoinQuery = `
SELECT
    a.id,
    a.appointment_date,
    a.appointment_time,
    a.status,
    a.created_at,

    p.id AS patient_id,
    p.full_name AS patient_name,
    p.gender,
    p.date_of_birth,
    p.phone_number,
    p.address,

    u.id AS doctor_id,
    u.username AS doctor_name

FROM appointments a

JOIN patients p
ON a.patient_id = p.id

JOIN users u
ON a.doctor_id = u.id
`;


// CREATE APPOINTMENT

appointmentRouter.post("/create", verifyCookies, async (req, res) => {

    try {

        if (req.role !== "receptionist") {
            return res.status(403).json({
                message: "Forbidden"
            });
        }

        const {
            patient_id,
            doctor_id,
            appointment_date,
            appointment_time,
            status
        } = req.body;

        if (
            !patient_id ||
            !doctor_id ||
            !appointment_date ||
            !appointment_time
        ) {
            return res.status(400).json({
                message:
                    "Patient id, doctor id, appointment date and appointment time are required"
            });
        }

        // check patient

        const [doesPatientExist] =
        await connection.query(
            "SELECT * FROM patients WHERE id = ?",
            [patient_id]
        );

        if (doesPatientExist.length === 0) {
            return res.status(400).json({
                message: "Patient does not exist"
            });
        }

        // check doctor

        const [doesDoctorExist] =
        await connection.query(
            "SELECT * FROM users WHERE id = ? AND role = 'doctor'",
            [doctor_id]
        );

        if (doesDoctorExist.length === 0) {
            return res.status(400).json({
                message: "Doctor does not exist"
            });
        }

        // check duplicate appointment

        const duplicateSQL = `
        SELECT * FROM appointments
        WHERE patient_id = ?
        AND doctor_id = ?
        AND appointment_date = ?
        AND appointment_time = ?
        `;

        const [doesAppointmentExist] =
        await connection.query(
            duplicateSQL,
            [
                patient_id,
                doctor_id,
                appointment_date,
                appointment_time
            ]
        );

        if (doesAppointmentExist.length > 0) {
            return res.status(400).json({
                message: "Appointment already exists"
            });
        }

        // insert

        const insertSQL = `
        INSERT INTO appointments
        (
            patient_id,
            doctor_id,
            appointment_date,
            appointment_time,
            status
        )
        VALUES (?, ?, ?, ?, ?)
        `;

        const [insertResult] =
        await connection.query(
            insertSQL,
            [
                patient_id,
                doctor_id,
                appointment_date,
                appointment_time,
                status || "pending"
            ]
        );

        if (insertResult.affectedRows > 0) {
            return res.status(201).json({
                message: "Appointment created successfully"
            });
        }

        return res.status(500).json({
            message: "Failed to create appointment"
        });

    } catch (error) {

        console.error("Error creating appointment:", error);

        return res.status(500).json({
            message: "Internal server error"
        });
    }
});


// DELETE APPOINTMENT

appointmentRouter.delete(
    "/delete/:id",
    verifyCookies,
    async (req, res) => {

        try {

            if (req.role !== "receptionist") {
                return res.status(403).json({
                    message: "Forbidden"
                });
            }

            const { id } = req.params;

            const [deleteResult] =
            await connection.query(
                "DELETE FROM appointments WHERE id = ?",
                [id]
            );

            if (deleteResult.affectedRows > 0) {
                return res.status(200).json({
                    message: "Appointment deleted successfully"
                });
            }

            return res.status(404).json({
                message: "Appointment not found"
            });

        } catch (error) {

            console.error(
                "Error deleting appointment:",
                error
            );

            return res.status(500).json({
                message: "Internal server error"
            });
        }
    }
);


// UPDATE APPOINTMENT

appointmentRouter.put(
    "/update/:id",
    verifyCookies,
    async (req, res) => {

        try {

            if (req.role !== "receptionist") {
                return res.status(403).json({
                    message: "Forbidden"
                });
            }

            const { id } = req.params;

            const {
                patient_id,
                doctor_id,
                appointment_date,
                appointment_time,
                status
            } = req.body;

            if (
                !patient_id ||
                !doctor_id ||
                !appointment_date ||
                !appointment_time
            ) {
                return res.status(400).json({
                    message:
                        "Patient id, doctor id, appointment date and appointment time are required"
                });
            }

            // existing appointment

            const [existingAppointment] =
            await connection.query(
                "SELECT * FROM appointments WHERE id = ?",
                [id]
            );

            if (existingAppointment.length === 0) {
                return res.status(404).json({
                    message: "Appointment not found"
                });
            }

            // patient exists

            const [doesPatientExist] =
            await connection.query(
                "SELECT * FROM patients WHERE id = ?",
                [patient_id]
            );

            if (doesPatientExist.length === 0) {
                return res.status(400).json({
                    message: "Patient does not exist"
                });
            }

            // doctor exists

            const [doesDoctorExist] =
            await connection.query(
                "SELECT * FROM users WHERE id = ? AND role = 'doctor'",
                [doctor_id]
            );

            if (doesDoctorExist.length === 0) {
                return res.status(400).json({
                    message: "Doctor does not exist"
                });
            }

            // update

            const updateSQL = `
            UPDATE appointments
            SET
                patient_id = ?,
                doctor_id = ?,
                appointment_date = ?,
                appointment_time = ?,
                status = ?
            WHERE id = ?
            `;

            const [updateResult] =
            await connection.query(
                updateSQL,
                [
                    patient_id,
                    doctor_id,
                    appointment_date,
                    appointment_time,
                    status || "pending",
                    id
                ]
            );

            if (updateResult.affectedRows > 0) {
                return res.status(200).json({
                    message:
                        "Appointment updated successfully"
                });
            }

            return res.status(500).json({
                message: "Failed to update appointment"
            });

        } catch (error) {

            console.error(
                "Error updating appointment:",
                error
            );

            return res.status(500).json({
                message: "Internal server error"
            });
        }
    }
);


// GET ALL APPOINTMENTS

appointmentRouter.get(
    "/all",
    verifyCookies,
    async (req, res) => {

        try {

            const [results] =
            await connection.query(
                appointmentJoinQuery
            );

            return res.status(200).json(results);

        } catch (error) {

            console.error(
                "Error fetching appointments:",
                error
            );

            return res.status(500).json({
                message: "Internal server error"
            });
        }
    }
);


// GET APPOINTMENT BY ID

appointmentRouter.get(
    "/:id",
    verifyCookies,
    async (req, res) => {

        try {

            const { id } = req.params;

            const sql = `
            ${appointmentJoinQuery}
            WHERE a.id = ?
            `;

            const [results] =
            await connection.query(sql, [id]);

            if (results.length > 0) {
                return res.status(200).json(results[0]);
            }

            return res.status(404).json({
                message: "Appointment not found"
            });

        } catch (error) {

            console.error(
                "Error fetching appointment:",
                error
            );

            return res.status(500).json({
                message: "Internal server error"
            });
        }
    }
);

export default appointmentRouter;