const validator = require("validator");
const Inventory = require("./models/invetories.model");
const {
  transformDateTimeField,
  getFormattedDateTime,
} = require("../../../managers/formatDateTime");
const db = require("../../../managers/dbConfig");
const { decrypt } = require("../../../managers/encrytion");
const { decryptRecords } = require("../../../managers/decryption");

// ✅ Fetch all inventory items for a branch
const getInventory = async (req, res) => {
  const { limit, offset, page } = req.pagination;

  const items = await Inventory.getAll(req.user.branch_id, limit, offset);
  if (items.length === 0) throw "No item found";

  transformDateTimeField(items);

  res.status(200).json({
    status: "success",
    page,
    drugs: items,
  });
};

//  ✅ Fetch inventory items by filter
const getInventoryByFilter = async (req, res) => {
  const { id, item_name, item_class, limit, offset, page } = req.pagination;

  const items = await Inventory.getByFilter({
    id,
    item_name,
    item_class,
    branch_id: req.user.branch_id,
    limit,
    offset,
  });

  if (items.length === 0) throw "No matching items found";

  const drugs = transformDateTimeField(items);

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

// ✅ Add new inventory item
const createInventoryItem = async (req, res) => {
  //   if (req.user.cadre != "pharmacist" && req.user.rank != 1)
  //     throw "Unauthorised! You're not permitted to use this resources.";
  let {
    item_name,
    packs_per_carton,
    cards_per_pack,
    tablets_per_card,
    units_per_pack,
    item_type,
    item_class,
    available_quantities,
    sp_pu,
    cp_pu,
    measured_in,
    low_stock_threshold,
    updated_by,
  } = req.body;
  let unit_quantity = available_quantities;

  if (!item_name) throw "Item_name is required";
  if (!item_type) throw "Item_type is required";
  if (!item_class) throw "Item_class is required";
  // if (!sFName || !sLName)
  //   throw "the staff first name and last name were required!";

  // const updated_by = `${sFName} ${sLName}`;

  //   switch (measured_in) {
  //     case "cartons":
  //       if (
  //         validator.isNumeric(String(packs_per_carton)) &&
  //         validator.isNumeric(String(cards_per_pack)) &&
  //         validator.isNumeric(String(tablets_per_card)) &&
  //         validator.isNumeric(String(available_quantities))
  //       ) {
  //         unit_quantity =
  //           packs_per_carton *
  //           cards_per_pack *
  //           tablets_per_card *
  //           available_quantities;
  //       } else {
  //         throw new Error(
  //           "Invalid input: All required fields must be numeric and not empty for cartons."
  //         );
  //       }
  //       break;

  //     case "packs":
  //       if (item_type === "counting_drug") {
  //         if (
  //           validator.isNumeric(String(units_per_pack)) &&
  //           validator.isNumeric(String(available_quantities))
  //         ) {
  //           unit_quantity = units_per_pack * available_quantities;
  //         } else {
  //           throw new Error(
  //             "Invalid input: All required fields must be numeric and not empty for drug_counting."
  //           );
  //         }
  //       } else {
  //         if (
  //           item_type !== "counting_drug" &&
  //           validator.isNumeric(String(cards_per_pack)) &&
  //           validator.isNumeric(String(tablets_per_card)) &&
  //           validator.isNumeric(String(available_quantities))
  //         ) {
  //           unit_quantity =
  //             cards_per_pack * tablets_per_card * available_quantities;
  //         } else {
  //           throw new Error(
  //             "Invalid input: All required fields must be numeric and not empty for packs."
  //           );
  //         }
  //       }
  //       break;

  //     case "cards":
  //       if (
  //         validator.isNumeric(String(tablets_per_card)) &&
  //         validator.isNumeric(String(available_quantities))
  //       ) {
  //         unit_quantity = tablets_per_card * available_quantities;
  //       } else {
  //         throw new Error(
  //           "Invalid input: All required fields must be numeric and not empty for cards."
  //         );
  //       }
  //       break;

  //     default:
  //       throw new Error(
  //         "Invalid value for 'mesured_in': how should we measured the quantity of the available stock."
  //       );
  //   }

  //   console.log(`Calculated unit quantity: ${unit_quantity}`);

  await Inventory.create(
    item_name,
    unit_quantity,
    item_type,
    item_class,

    low_stock_threshold,
    req.user.branch_id,
    updated_by,
    cp_pu,
    sp_pu
  );
  res.status(201).json({ message: "Inventory item added successfully" });
};

// ✅ Update inventory details
const updateInventoryDetails = async (req, res) => {
  let {
    item_name,
    cp_pu,
    sp_pu,
    item_type,
    item_class,
    low_stock_threshold,
    updated_by,
  } = req.body;

  if (!updated_by) throw "staff Identity can not be ascertained!";

  await Inventory.updateStockDetails(
    req.params.id,
    item_name,
    cp_pu,
    sp_pu,
    item_type,
    item_class,
    low_stock_threshold,
    updated_by,
    req.user.branch_id
  );
  res.status(201).json({ message: "Inventory item updated successfully" });
};

// ✅ Restock inventory (increase quantity)
const restockInventory = async (req, res) => {
  const { id, quantity, updated_by } = req.body;

  //const updated_by = `${sFName} ${sLName}`;

  if (!quantity || quantity <= 0) throw "Invalid restock quantity";
  if (!validator.isNumeric(String(quantity)))
    throw `${quantity} is NOT a valid and plain number`;

  await Inventory.restock(id, quantity, updated_by, req.user.branch_id);
  res.status(200).json({ message: `Restocked ${quantity} units successfully` });
};

// ✅ Dispense stock (reduce quantity)
const dispenseStock = async (req, res) => {
  let { quantity, patient_id, customer_name, sFName, sLName } = req.body;
  const dispensed_by = `${sFName} ${sLName}`;

  if (!quantity || quantity <= 0) throw "Invalid quantity";
  if (!sFName || !sLName) throw "staff full name is required";
  if (!validator.isNumeric(String(quantity)))
    throw `${quantity} is NOT a valid and plain number`;
  patient_id = patient_id ?? "Not for patient";

  await Inventory.dispenseStock(
    req.params.id,
    quantity,
    patient_id,
    dispensed_by,
    req.user.branch_id
  );
  res.status(200).json({
    message: `${quantity} units dispensed successfully by ${dispensed_by}`,
  });
};

const dispenseMultipleItems = async (req, res) => {
  const { items, patient_id, dispensed_by } = req.body;

  if (!patient_id) throw "Patient ID is required";
  if (!dispensed_by) throw "Staff details is required";

  if (!Array.isArray(items) || items.length === 0) throw "Invalid items list";

  await Inventory.dispenseMultipleItems(
    items,
    patient_id,
    dispensed_by,
    req.user.branch_id
  );
  res.status(200).json({ message: "Items dispensed successfully" });
};

// ✅ Fetch dispensed drug history items
const getDispenseHistory = async (req, res) => {
  const { id, limit, offset, page } = req.pagination;

  const [history] = await Inventory.getDispenseHistory(
    req.user.branch_id,
    id,
    limit,
    offset
  );

  const d_hx = transformDateTimeField(history);

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

// ✅ Fetch low-stock items
const getLowStockItems = async (req, res) => {
  const [items] = await Inventory.getLowStockItems(req.user.branch_id);
  res.status(200).json(items);
};

const fetchRx = async (req, res) => {
  const today = getFormattedDateTime();
  const { patient_id } = req.query;

  if (!patient_id) throw "patient ID is required";

  const sql = `SELECT rx FROM tx WHERE patient_id=? AND DATE(date_time) = ?`;
  const [rx] = await db.execute(sql, [patient_id, today]);

  if (rx.length < 1)
    throw `patient ${patient_id} has no treatment record for today`;
  const sanitizedDateTime = transformDateTimeField(rx);

  const encryptedData = ["rx"];
  const decrypted = decryptRecords(
    sanitizedDateTime,
    process.env.enc_key,
    encryptedData
  );

  res.status(200).json({
    status: "success",
    rxItems: decrypted,
  });
};

module.exports = {
  getInventory,
  getInventoryByFilter,
  createInventoryItem,
  updateInventoryDetails,
  restockInventory,
  dispenseStock,
  dispenseMultipleItems,
  getDispenseHistory,
  getLowStockItems,
  fetchRx,
};
