const db = require("../db");

function showCreatePatient(req, res) {
  res.render("patient_create", {
    title: "Patient anlegen",
    sidebarPartial: "partials/sidebar",
    active: "patients",
    user: req.session.user,
    lang: req.session.lang || "de",
  });
}

function createPatient(req, res) {
  const { firstname, lastname, birthdate } = req.body;

  db.query(
    "INSERT INTO patients (firstname, lastname, birthdate, active) VALUES (?, ?, ?, 1)",
    [firstname, lastname, birthdate],
    (err) => {
      if (err) {
        console.error(err);
        return res.send("Datenbankfehler");
      }
      res.redirect("/dashboard");
    },
  );
}

async function listPatients(req, res) {
  const { firstname, lastname, birthdate } = req.query;

  let sql = "SELECT * FROM patients WHERE 1=1";
  const params = [];

  if (firstname) {
    sql += " AND LOWER(firstname) LIKE LOWER(?)";
    params.push(`%${firstname}%`);
  }

  if (lastname) {
    sql += " AND LOWER(lastname) LIKE LOWER(?)";
    params.push(`%${lastname}%`);
  }

  if (birthdate) {
    sql += " AND birthdate = ?";
    params.push(birthdate);
  }

  sql += " ORDER BY lastname, firstname";

  try {
    // ✅ alle Patienten laden
    const [patients] = await db.promise().query(sql, params);

    // ✅ ausgewählten Patienten aus Session laden (falls vorhanden)
    const selectedPatientId = req.session.selectedPatientId || null;

    let selectedPatient = null;

    if (selectedPatientId) {
      const [rows] = await db
        .promise()
        .query("SELECT * FROM patients WHERE id = ?", [selectedPatientId]);

      selectedPatient = rows?.[0] || null;

      // ✅ falls Patient nicht mehr existiert → Auswahl löschen
      if (!selectedPatient) {
        req.session.selectedPatientId = null;
      }
    }

    // ✅ Sidebar IMMER patient-sidebar (sofort beim Laden)
    const backUrl = "/dashboard";

    return res.render("patients", {
      title: "Patientenübersicht",

      // ✅ Sidebar dynamisch
      sidebarPartial: selectedPatient
        ? "partials/patient_sidebar"
        : "partials/sidebar",

      // ✅ Active dynamisch
      active: selectedPatient ? "patient_dashboard" : "patients",

      patients,

      // ✅ wichtig: für patient-sidebar
      patient: selectedPatient,
      selectedPatientId: selectedPatient?.id || null,

      query: req.query,
      user: req.session.user,
      lang: req.session.lang || "de",

      // ✅ wichtig: zurück Button
      backUrl,
    });
  } catch (err) {
    console.error(err);
    return res.send("Datenbankfehler");
  }
}

function showEditPatient(req, res) {
  db.query(
    "SELECT * FROM patients WHERE id = ?",
    [req.params.id],
    (err, results) => {
      if (err || results.length === 0)
        return res.send("Patient nicht gefunden");

      res.render("patient_edit", {
        title: "Patient bearbeiten",
        sidebarPartial: "partials/patient_sidebar",
        active: "patient_edit",

        patient: results[0],
        error: null,
        user: req.session.user,
        lang: req.session.lang || "de",
        returnTo: req.query.returnTo || null,
      });
    },
  );
}

function updatePatient(req, res) {
  const id = req.params.id;
  const returnTo = req.body.returnTo;

  const {
    firstname,
    lastname,
    dni,
    birthdate,
    gender,
    email,
    phone,
    street,
    house_number,
    postal_code,
    city,
    country,
    notes,
  } = req.body;

  if (!firstname || !lastname || !birthdate) {
    req.session.flash = {
      type: "warning",
      message: "Vorname, Nachname und Geburtsdatum sind Pflichtfelder",
    };
    return res.redirect("back");
  }

  db.query(
    `UPDATE patients SET
      firstname = ?,
      lastname = ?,
      dni = ?,
      birthdate = ?,
      gender = ?,
      email = ?,
      phone = ?,
      street = ?,
      house_number = ?,
      postal_code = ?,
      city = ?,
      country = ?,
      notes = ?
     WHERE id = ?`,
    [
      firstname,
      lastname,
      dni || null,
      birthdate,
      gender || null,
      email || null,
      phone || null,
      street || null,
      house_number || null,
      postal_code || null,
      city || null,
      country || null,
      notes || null,
      id,
    ],
    (err) => {
      if (err) {
        console.error(err);
        return res.send("Fehler beim Speichern");
      }

      if (returnTo === "overview") {
        return res.redirect(`/patients/${id}/overview`);
      }

      res.redirect("/patients");
    },
  );
}

function showPatientMedications(req, res) {
  const patientId = req.params.id;
  const returnTo = req.query.returnTo || null;

  const patientSql = "SELECT * FROM patients WHERE id = ?";
  const medsSql = `
    SELECT
      v.id,
      m.name AS medication,
      f.name AS form,
      v.dosage,
      v.package
    FROM medication_variants v
    JOIN medications m ON v.medication_id = m.id
    JOIN medication_forms f ON v.form_id = f.id
    ORDER BY m.name, v.dosage
  `;

  const currentSql = `
    SELECT
      pm.id,
      m.name AS medication,
      f.name AS form,
      v.dosage,
      v.package,
      pm.dosage_instruction,
      pm.start_date,
      pm.end_date
    FROM patient_medications pm
    JOIN medication_variants v ON pm.medication_variant_id = v.id
    JOIN medications m ON v.medication_id = m.id
    JOIN medication_forms f ON v.form_id = f.id
    WHERE pm.patient_id = ?
    ORDER BY pm.start_date DESC
  `;

  db.query(patientSql, [patientId], (err, patients) => {
    if (err || patients.length === 0) {
      return res.send("Patient nicht gefunden");
    }

    db.query(medsSql, (err, meds) => {
      if (err) return res.send("Medikamente konnten nicht geladen werden");

      db.query(currentSql, [patientId], (err, currentMeds) => {
        if (err)
          return res.send("Aktuelle Medikation konnte nicht geladen werden");

        res.render("patient_medications", {
          title: "Medikamente",
          sidebarPartial: "partials/patient-doctor-sidebar",
          active: "patient_medications",

          patient: patients[0],
          meds,
          currentMeds,
          user: req.session.user,
          lang: req.session.lang || "de",
          returnTo,
        });
      });
    });
  });
}

function moveToWaitingRoom(req, res) {
  const id = req.params.id;

  db.query(
    `
    UPDATE patients
    SET waiting_room = 1,
        discharged = 0,
        active = 1
    WHERE id = ?
    `,
    [id],
    (err) => {
      if (err) return res.send("Fehler beim Verschieben ins Wartezimmer");
      return res.redirect("/dashboard");
    },
  );
}

function showWaitingRoom(req, res) {
  db.query(
    "SELECT * FROM patients WHERE waiting_room = 1 AND active = 1 ORDER BY lastname",
    (err, patients) => {
      if (err) return res.send("Datenbankfehler");

      res.render("waiting_room", {
        title: "Wartezimmer",
        sidebarPartial: "partials/sidebar",
        active: "patients",

        patients,
        user: req.session.user,
        lang: req.session.lang || "de",
      });
    },
  );
}

function showPatientOverview(req, res) {
  const patientId = req.params.id;

  const patientSql = `
    SELECT *
    FROM patients
    WHERE id = ?
  `;

  const notesSql = `
  SELECT
    pn.*,
    u.title,
    u.first_name,
    u.last_name
  FROM patient_notes pn
  LEFT JOIN users u ON pn.created_by = u.id
  WHERE pn.patient_id = ?
  ORDER BY pn.created_at DESC
`;

  const medicationVariantsSql = `
    SELECT
      mv.id AS variant_id,
      m.name AS medication_name,
      mf.name AS form_name,
      mv.dosage,
      mv.package
    FROM medication_variants mv
    JOIN medications m ON mv.medication_id = m.id
    JOIN medication_forms mf ON mv.form_id = mf.id
    ORDER BY m.name, mf.name, mv.dosage
  `;

  db.query(patientSql, [patientId], (err, patients) => {
    if (err || patients.length === 0) {
      return res.send("Patient nicht gefunden");
    }

    const patient = patients[0];

    const serviceNameField =
      patient.country === "ES"
        ? "COALESCE(NULLIF(name_es, ''), name_de)"
        : "name_de";

    const servicesSql = `
      SELECT
        id,
        ${serviceNameField} AS name,
        price
      FROM services
      WHERE active = 1
      ORDER BY ${serviceNameField}
    `;

    const todayServicesSql = `
      SELECT
        ps.id,
        ps.quantity,
        COALESCE(ps.price_override, s.price) AS price,
        ${serviceNameField} AS name,
        u.username AS doctor
      FROM patient_services ps
      JOIN services s ON ps.service_id = s.id
      LEFT JOIN users u ON ps.created_by = u.id
      WHERE ps.patient_id = ?
        AND ps.service_date = CURDATE()
        AND ps.invoice_id IS NULL
      ORDER BY ps.created_at DESC
    `;

    db.query(notesSql, [patientId], (err, notes) => {
      if (err) return res.send("Fehler Notizen");

      db.query(servicesSql, (err, services) => {
        if (err) return res.send("Fehler Leistungen");

        db.query(todayServicesSql, [patientId], (err, todayServices) => {
          if (err) return res.send("Fehler heutige Leistungen");

          db.query(medicationVariantsSql, (err, medicationVariants) => {
            if (err) return res.send("Fehler Medikamente");

            res.render("patient_overview", {
              title: "Patient Übersicht",
              sidebarPartial: "partials/patient-doctor-sidebar",
              active: "patient_overview",

              patient,
              notes,
              services,
              todayServices,
              medicationVariants,
              user: req.session.user,
              lang: req.session.lang || "de",
            });
          });
        });
      });
    });
  });
}

function assignMedicationToPatient(req, res) {
  const patientId = req.params.id;
  const { medication_variant_id, dosage_instruction, start_date, end_date } =
    req.body;

  if (!medication_variant_id) {
    req.session.flash = {
      type: "warning",
      message: "Bitte ein Medikament auswählen",
    };
    return res.redirect(`/patients/${patientId}/overview`);
  }

  db.query(
    `
    INSERT INTO patient_medications
      (patient_id, medication_variant_id, dosage_instruction, start_date, end_date)
    VALUES (?, ?, ?, ?, ?)
    `,
    [
      patientId,
      medication_variant_id,
      dosage_instruction || null,
      start_date || new Date(),
      end_date || null,
    ],
    (err) => {
      if (err) {
        console.error(err);
        return res.send("Fehler beim Verordnen");
      }

      req.session.flash = {
        type: "success",
        message: "Medikament erfolgreich verordnet",
      };

      res.redirect(`/patients/${patientId}/overview`);
    },
  );
}

function addPatientNote(req, res) {
  const patientId = req.params.id;
  const { note } = req.body;

  if (!note || note.trim() === "") {
    return res.redirect(`/patients/${patientId}/overview`);
  }

  db.query(
    "INSERT INTO patient_notes (patient_id, created_by, note) VALUES (?, ?, ?)",
    [patientId, req.session.user.id, note],

    (err) => {
      if (err) return res.send("Fehler beim Speichern der Notiz");
      res.redirect(`/patients/${patientId}/overview`);
    },
  );
}

function callFromWaitingRoom(req, res) {
  const patientId = req.params.id;

  db.query(
    "UPDATE patients SET waiting_room = 0 WHERE id = ?",
    [patientId],
    (err) => {
      if (err) return res.send("Fehler beim Entfernen aus dem Wartezimmer");
      res.redirect(`/patients/${patientId}/overview`);
    },
  );
}

function dischargePatient(req, res) {
  const patientId = req.params.id;

  db.query(
    `
    UPDATE patients
    SET discharged = 1,
        waiting_room = 0,
        active = 0
    WHERE id = ?
    `,
    [patientId],
    (err) => {
      if (err) {
        console.error(err);
        return res.send("Fehler beim Entlassen des Patienten");
      }

      return res.redirect("/dashboard");
    },
  );
}

function showMedicationPlan(req, res) {
  const patientId = req.params.id;

  const patientSql = "SELECT * FROM patients WHERE id = ?";
  const medsSql = `
    SELECT
      m.name AS medication,
      f.name AS form,
      v.dosage,
      v.package,
      pm.dosage_instruction,
      pm.start_date,
      pm.end_date
    FROM patient_medications pm
    JOIN medication_variants v ON pm.medication_variant_id = v.id
    JOIN medications m ON v.medication_id = m.id
    JOIN medication_forms f ON v.form_id = f.id
    WHERE pm.patient_id = ?
      AND (pm.end_date IS NULL OR pm.end_date >= CURDATE())
    ORDER BY m.name
  `;

  db.query(patientSql, [patientId], (err, patients) => {
    if (err || patients.length === 0) {
      return res.send("Patient nicht gefunden");
    }

    db.query(medsSql, [patientId], (err, meds) => {
      if (err) return res.send("Medikationsplan konnte nicht geladen werden");

      res.render("patient_plan", {
        title: "Medikationsplan",
        sidebarPartial: "partials/patient_sidebar",
        active: "patient_plan",

        patient: patients[0],
        meds,
        user: req.session.user,
        lang: req.session.lang || "de",
      });
    });
  });
}

function movePatientToWaitingRoom(req, res) {
  const patientId = req.params.id;

  db.query(
    `
    UPDATE patients
    SET waiting_room = 1,
        discharged = 0,
        status = 'waiting',
        active = 1
    WHERE id = ?
    `,
    [patientId],
    (err) => {
      if (err) {
        console.error(err);
        req.session.flash = {
          type: "danger",
          message: "Fehler beim Zurücksetzen ins Wartezimmer",
        };
        return res.redirect(`/patients/${patientId}/overview`);
      }

      req.session.flash = {
        type: "success",
        message: "Patient wurde ins Wartezimmer gesetzt",
      };

      return res.redirect("/dashboard");
    },
  );
}

function deactivatePatient(req, res) {
  const id = req.params.id;

  db.query("UPDATE patients SET active = 0 WHERE id = ?", [id], (err) => {
    if (err) {
      console.error(err);
      req.session.flash = {
        type: "danger",
        message: "Patient konnte nicht gesperrt werden",
      };
      return res.redirect("/patients");
    }

    req.session.flash = {
      type: "success",
      message: "Patient wurde gesperrt",
    };

    res.redirect("/patients");
  });
}

function activatePatient(req, res) {
  const id = req.params.id;

  db.query("UPDATE patients SET active = 1 WHERE id = ?", [id], (err) => {
    if (err) {
      console.error(err);
      req.session.flash = {
        type: "danger",
        message: "Patient konnte nicht entsperrt werden",
      };
      return res.redirect("/patients");
    }

    req.session.flash = {
      type: "success",
      message: "Patient wurde entsperrt",
    };

    res.redirect("/patients");
  });
}

async function showPatientOverviewDashborad(req, res) {
  const patientId = req.params.id;

  try {
    const [[patient]] = await db
      .promise()
      .query("SELECT * FROM patients WHERE id = ?", [patientId]);

    if (!patient) {
      return res.redirect("/patients");
    }

    const [medications] = await db.promise().query(
      `
      SELECT
        m.name              AS medication_name,
        mv.dosage           AS variant_dosage,
        pm.dosage_instruction,
        pm.start_date
      FROM patient_medications pm
      JOIN medication_variants mv
        ON pm.medication_variant_id = mv.id
      JOIN medications m
        ON mv.medication_id = m.id
      WHERE pm.patient_id = ?
        AND pm.end_date IS NULL
      ORDER BY pm.start_date DESC
      `,
      [patientId],
    );

    const [invoices] = await db.promise().query(
      `
      SELECT
        id,
        invoice_date,
        total_amount,
        file_path,
        status
      FROM invoices
      WHERE patient_id = ?
      ORDER BY invoice_date DESC
      `,
      [patientId],
    );

    res.render("patient_overview_dashboard", {
      title: "Patient Dashboard",
      sidebarPartial: "partials/patient_sidebar",
      active: "patient_dashboard",

      patient,
      medications,
      invoices,
      user: req.session.user,
      lang: req.session.lang || "de",
    });
  } catch (err) {
    console.error(err);
    res.send("Datenbankfehler");
  }
}

module.exports = {
  listPatients,
  showCreatePatient,
  createPatient,
  showEditPatient,
  updatePatient,
  showPatientMedications,
  moveToWaitingRoom,
  showWaitingRoom,
  showPatientOverview,
  addPatientNote,
  callFromWaitingRoom,
  dischargePatient,
  showMedicationPlan,
  movePatientToWaitingRoom,
  deactivatePatient,
  activatePatient,
  showPatientOverviewDashborad,
  assignMedicationToPatient,
};
