const { getPool } = require('../config/db');

function formatAppointment(row) {
  return {
    id: row.id,
    patientId: row.patient_id,
    doctorId: row.doctor_id,
    patientName: row.patient_name,
    doctorName: row.doctor_name,
    appointmentDate: row.appointment_date,
    appointmentTime: row.appointment_time,
    status: row.status,
    createdAt: row.created_at,
    hasReport: Boolean(row.has_report),
  };
}

const appointmentSelect = `
  SELECT a.*,
    p.full_name AS patient_name,
    u.name AS doctor_name,
    (SELECT COUNT(*) FROM medical_reports mr WHERE mr.appointment_id = a.id) AS has_report
  FROM appointments a
  JOIN patients p ON p.id = a.patient_id
  JOIN users u ON u.id = a.doctor_id
`;

exports.getAppointments = async (req, res) => {
  try {
    const pool = getPool();
    let query = `${appointmentSelect}`;
    const params = [];

    if (req.user.role === 'doctor') {
      query += ' WHERE a.doctor_id = ?';
      params.push(req.user.id);
    }

    query += ' ORDER BY a.appointment_date DESC, a.appointment_time DESC';

    const [rows] = await pool.query(query, params);
    res.json({ appointments: rows.map(formatAppointment) });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.getAppointment = async (req, res) => {
  try {
    const pool = getPool();
    const [rows] = await pool.query(`${appointmentSelect} WHERE a.id = ?`, [req.params.id]);

    if (!rows.length) {
      return res.status(404).json({ message: 'Appointment not found' });
    }

    if (req.user.role === 'doctor' && rows[0].doctor_id !== req.user.id) {
      return res.status(403).json({ message: 'Access denied' });
    }

    res.json({ appointment: formatAppointment(rows[0]) });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.createAppointment = async (req, res) => {
  try {
    const { patientId, doctorId, appointmentDate, appointmentTime, status } = req.body;

    if (!patientId || !doctorId || !appointmentDate || !appointmentTime) {
      return res.status(400).json({ message: 'Patient, doctor, date, and time are required' });
    }

    const pool = getPool();

    const [doctor] = await pool.query('SELECT id FROM users WHERE id = ? AND role = ?', [
      doctorId,
      'doctor',
    ]);
    if (!doctor.length) {
      return res.status(400).json({ message: 'Invalid doctor selected' });
    }

    const [result] = await pool.query(
      `INSERT INTO appointments (patient_id, doctor_id, appointment_date, appointment_time, status)
       VALUES (?, ?, ?, ?, ?)`,
      [patientId, doctorId, appointmentDate, appointmentTime, status || 'scheduled'],
    );

    const [rows] = await pool.query(`${appointmentSelect} WHERE a.id = ?`, [result.insertId]);
    res.status(201).json({ appointment: formatAppointment(rows[0]) });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.updateAppointment = async (req, res) => {
  try {
    const { patientId, doctorId, appointmentDate, appointmentTime, status } = req.body;
    const pool = getPool();

    const [existing] = await pool.query('SELECT id FROM appointments WHERE id = ?', [req.params.id]);
    if (!existing.length) {
      return res.status(404).json({ message: 'Appointment not found' });
    }

    if (doctorId) {
      const [doctor] = await pool.query('SELECT id FROM users WHERE id = ? AND role = ?', [
        doctorId,
        'doctor',
      ]);
      if (!doctor.length) {
        return res.status(400).json({ message: 'Invalid doctor selected' });
      }
    }

    await pool.query(
      `UPDATE appointments
       SET patient_id = ?, doctor_id = ?, appointment_date = ?, appointment_time = ?, status = ?
       WHERE id = ?`,
      [patientId, doctorId, appointmentDate, appointmentTime, status, req.params.id],
    );

    const [rows] = await pool.query(`${appointmentSelect} WHERE a.id = ?`, [req.params.id]);
    res.json({ appointment: formatAppointment(rows[0]) });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.cancelAppointment = async (req, res) => {
  try {
    const pool = getPool();
    const [result] = await pool.query(
      "UPDATE appointments SET status = 'cancelled' WHERE id = ?",
      [req.params.id],
    );

    if (result.affectedRows === 0) {
      return res.status(404).json({ message: 'Appointment not found' });
    }

    const [rows] = await pool.query(`${appointmentSelect} WHERE a.id = ?`, [req.params.id]);
    res.json({ appointment: formatAppointment(rows[0]) });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.deleteAppointment = async (req, res) => {
  try {
    const pool = getPool();
    const [result] = await pool.query('DELETE FROM appointments WHERE id = ?', [req.params.id]);

    if (result.affectedRows === 0) {
      return res.status(404).json({ message: 'Appointment not found' });
    }

    res.json({ message: 'Appointment deleted' });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};
