const Lab = require("./models/lab.model");
const LabResult = require("./models/LabResult");
const pool = require("../../../managers/dbConfig");
const { transformDateTimeField } = require("../../../managers/formatDateTime");

// ✅ Fetch all available lab tests
exports.getLabTests = async (req, res) => {
  const tests = await Lab.getAllTests();
  res.json(tests);
};

// ✅ Request a new lab test
exports.requestLabTest = async (req, res) => {
  const { pt_id, requested_by, test_name } = req.body;
  if (!requested_by) throw "Staff ID can NOT be ascertained! Try Re-Login.";
  const doctor_id = requested_by;

  if (!pt_id || !test_name) throw "Patient ID and test name are required";

  await Lab.requestTest(pt_id, doctor_id, test_name);
  res.status(201).json({ message: "Lab test requested successfully" });
};

// ✅ Fetch lab test requests for a patient
exports.getPatientLabRequests = async (req, res) => {
  const { patient_id } = req.params;
  const requests = await Lab.getPatientLabRequests(patient_id);
  res.json(requests);
};

exports.getPendingRequests = async (req, res) => {
  const [requests] = await Lab.getPendingLabRequests();
  const cleanedDateRequests = transformDateTimeField(requests);

  res.status(200).json({
    status: "success",
    data: cleanedDateRequests,
  });
};

// ✅ Update lab test request status
exports.updateLabTestStatus = async (req, res) => {
  const { request_id, status } = req.body;

  if (!request_id || !["pending", "completed", "canceled"].includes(status)) {
    throw "Invalid request ID or status";
  }

  await Lab.updateTestStatus(request_id, status);
  res.json({ message: "Lab test status updated successfully" });
};

// ✅ Upload lab test result
exports.uploadLabResult = async (req, res) => {
  const { request_id, result_text } = req.body;
  const result_file = req.file ? req.file.filename : null; // File handling
  const tested_by = req.user.id;

  if (!request_id || (!result_text && !result_file)) {
    throw "Test ID and at least one result (text or file) are required";
  }

  await Lab.uploadLabResult(request_id, result_text, result_file, tested_by);
  res.json({ message: "Lab test result uploaded successfully" });
};

// Fetch Lab Results with Flexible Filters
exports.getLabResults = async (req, res) => {
  const {
    patient_id,
    fetch_date,
    start_date,
    end_date,
    tested_by,
    requested_by,
    limit,
    offset,
    page,
  } = req.pagination;

  const results = await Lab.getLabResults({
    branch_id: req.user.branch_id,
    patient_id,
    fetch_date,
    start_date,
    end_date,
    tested_by,
    requested_by,
    limit,
    offset,
  });

  res.status(200).json({
    status: "success",
    page,
    data: results,
  });
};

// ✅ Fetch lab test results for a patient
exports.getLatestPatientLabResults = async (req, res) => {
  const { patient_id } = req.params;
  const results = await Lab.getLatestPatientLabResults(patient_id);
  res.json(results);
};

exports.labResults = async (req, res) => {
  const { pt_id, request_id, specimen, signed_by, comment, results } = req.body;

  // 🚨 Validate required fields
  if (!request_id) throw "Request ID is required";
  // if (!pt_id || !signed_by) throw "Patient ID and Signed By are required";
  if (!results || Object.keys(results).length === 0)
    throw `No lab results provided for ${results}`;

  // ✅ Save lab results
  const savedResult = await LabResult.saveLabResults({
    pt_id,
    request_id,
    signed_by,
    specimen,
    comment,
    results,
  });

  res.status(201).json({
    message: "Lab results saved successfully!",
    data: savedResult,
  });
};

exports.fetchLabResults = async (req, res) => {
  const {
    id: patient_id,
    limit,
    offset,
    start_date,
    end_date,
  } = req.pagination;

  let sql = `
      SELECT 
          lr.id AS result_id,
          lr.pt_id AS patient_id,
          lr.signed_by AS tested_by,
          lr.specimen,
          lr.comment,
          lr.date_time,
          lrf.test_category,
          lrf.test_name,
          lrf.value AS result
      FROM 
          lab_results lr
      JOIN 
          lab_results_fileds lrf ON lr.id = lrf.result_id
      WHERE 
          1 = 1`; // ✅ Ensures the WHERE clause can be dynamically appended

  const params = [];

  // ✅ Add patient filter if provided
  if (patient_id) {
    sql += " AND lr.pt_id = ?";
    params.push(patient_id);
  }

  // ✅ Add date filters if provided
  if (start_date) {
    sql += " AND DATE(lr.date_time) >= ?";
    params.push(start_date);
  }
  if (end_date) {
    sql += " AND DATE(lr.date_time) <= ?";
    params.push(end_date);
  }

  // ✅ Apply ordering and pagination
  sql += " ORDER BY lr.date_time DESC LIMIT ? OFFSET ?";
  params.push(limit, offset);

  const [rows] = await pool.execute(sql, params);
  const cleanedDateRows = transformDateTimeField(rows);

  res.status(200).json({
    status: "success",
    page: req.pagination.page,
    data: cleanedDateRows,
  });
};
