import models from "$models/index.js";

const normalizePayload = (body = {}) => ({
  name: String(body.name || "").trim(),
  bankCode: String(body.bankCode || "").trim(),
  sejamBankId: String(body.sejamBankId || "").trim(),
});

const validatePayload = (payload) => {
  if (!payload.name) return "نام بانک الزامی است.";
  if (!payload.bankCode) return "کد بانک الزامی است.";
  if (!payload.sejamBankId) return "شناسه بانک سجام الزامی است.";
  return "";
};

const buildDuplicateMessage = (error) => {
  if (error?.code !== 11000) return "";

  if (error.keyPattern?.bankCode) {
    return "کد بانک تکراری است.";
  }

  if (error.keyPattern?.sejamBankId) {
    return "شناسه بانک سجام تکراری است.";
  }

  return "اطلاعات بانک تکراری است.";
};

export const ALL = async (req, res) => {
  try {
    const pageSize = req.query.pageSize ? parseInt(req.query.pageSize) : 20;
    const currentPage = req.query.page ? parseInt(req.query.page) : 1;
    const skip = pageSize * currentPage - pageSize;
    const query = {};

    if (req.query.search) {
      const search = String(req.query.search).trim();
      query.$or = [
        { name: { $regex: search, $options: "i" } },
        { bankCode: { $regex: search, $options: "i" } },
        { sejamBankId: { $regex: search, $options: "i" } },
      ];
    }

    const banks = await models.bank
      .find(query)
      .limit(pageSize)
      .skip(skip)
      .sort({ name: 1 });

    const totalData = await models.bank.countDocuments(query);
    const totalPage = pageSize ? Math.ceil(totalData / pageSize) : 0;

    return res.status(200).send({
      banks,
      totalData,
      currentPage,
      totalPage,
    });
  } catch (error) {
    const status = error.status || 500;
    const message = error.message || "خطا در دریافت بانک‌ها";
    return res.status(status).send({ message });
  }
};

export const SINGLE = async (req, res) => {
  try {
    const bank = await models.bank.findById(req.params.id);

    if (!bank) {
      return res.status(404).send({ message: "یافت نشد" });
    }

    return res.status(200).send(bank);
  } catch (error) {
    const status = error.status || 500;
    const message = error.message || "خطا در دریافت بانک";
    return res.status(status).send({ message });
  }
};

export const CREATE = async (req, res) => {
  try {
    const payload = normalizePayload(req.body);
    const validationMessage = validatePayload(payload);

    if (validationMessage) {
      return res.status(422).send({ message: validationMessage });
    }

    const bank = await models.bank.create(payload);

    return res.status(201).send({
      message: "بانک با موفقیت ایجاد شد",
      data: bank,
    });
  } catch (error) {
    const duplicateMessage = buildDuplicateMessage(error);
    if (duplicateMessage) {
      return res.status(409).send({ message: duplicateMessage });
    }

    const status = error.status || 500;
    const message = error.message || "خطا در ایجاد بانک";
    return res.status(status).send({ message });
  }
};

export const UPDATE = async (req, res) => {
  try {
    const { id } = req.params;
    const payload = normalizePayload(req.body);
    const validationMessage = validatePayload(payload);

    if (validationMessage) {
      return res.status(422).send({ message: validationMessage });
    }

    const bank = await models.bank.findByIdAndUpdate(
      id,
      { $set: payload },
      { new: true, runValidators: true },
    );

    if (!bank) {
      return res.status(404).send({ message: "یافت نشد" });
    }

    return res.status(200).send({
      message: "بانک با موفقیت ویرایش شد",
      data: bank,
    });
  } catch (error) {
    const duplicateMessage = buildDuplicateMessage(error);
    if (duplicateMessage) {
      return res.status(409).send({ message: duplicateMessage });
    }

    const status = error.status || 500;
    const message = error.message || "خطا در ویرایش بانک";
    return res.status(status).send({ message });
  }
};

export const DELETE = async (req, res) => {
  try {
    const bank = await models.bank.findByIdAndDelete(req.params.id);

    if (!bank) {
      return res.status(404).send({ message: "یافت نشد" });
    }

    return res.status(200).send({
      message: "بانک با موفقیت حذف شد",
    });
  } catch (error) {
    const status = error.status || 500;
    const message = error.message || "خطا در حذف بانک";
    return res.status(status).send({ message });
  }
};
