import _ from "underscore";
import { accessGrantHelpers } from "$helpers/index.js";
import models from "$models/index.js";
import { buildUserTableQuery } from "./user.query.js";

export const ALL = async (req, res) => {
  try {
    const {
      pageSize,
      currentPage,
      skip,
      filterQuery,
      sort,
      sortField,
      sortDirection,
    } = buildUserTableQuery(req.query);

    const users = await models.user
      .find(filterQuery)
      .select("-__v")
      .limit(pageSize)
      .skip(skip)
      .sort(sort)
      .populate("role");

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

    res.status(200).send({
      users,
      totalData,
      currentPage,
      totalPage,
      sortField,
      sortDirection,
    });
  } catch (error) {
    const status = error.status || 500;
    const message = error.message || "ERROR ON FETCHING USERS";
    return res.status(status).send({ message });
  }
};

export const SINGLE = async (req, res) => {
  try {
    const { id } = req.params;

    const data = await models.user
      .findById(id)
      .select("-createdAt -updatedAt -__v")
      .populate({
        path: "role",
        model: "Role",
      });

    if (data) {
      res.status(200).send(data);
    } else {
      return res.status(404).send({ message: "user did not found" });
    }
  } catch (error) {
    const status = error.status || 500;
    const message = error.message || "ERROR ON FETCHING USER";
    return res.status(status).send({ message });
  }
};

export const UPDATE = async (req, res) => {
  try {
    const _id = req.params.id;
    const bodyData = {};

    if (req.body.role) {
      bodyData.role = req.body.role;
    }

    if (req.body.mobile !== undefined) {
      bodyData.mobile = req.body.mobile;
    }

    if (req.body.accessGrants !== undefined) {
      bodyData.accessGrants = accessGrantHelpers.normalizeAccessGrants(
        req.body.accessGrants,
      );
    }

    if (
      !bodyData.role &&
      bodyData.mobile === undefined &&
      bodyData.accessGrants === undefined
    ) {
      throw { status: 400, message: "اطلاعاتی برای ویرایش ارسال نشده است" };
    }

    const data = await models.user
      .findOneAndUpdate({ _id }, { $set: bodyData }, { new: true })
      .select("-__v")
      .populate("role");

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

export const DELETE = async (req, res) => {
  try {
    const { id } = req.params;

    const data = await models.user.findByIdAndDelete(id);

    if (data) {
      res.status(200).send({
        message: "کاربر با موفقیت حذف شد",
      });
    } else {
      return res.status(404).send({ message: "کاربر یافت نشد" });
    }
  } 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 userData = req.body;

    // Validate required fields for SEJAM users
    if (!userData.nationalId) {
      throw { status: 400, message: "کد ملی الزامی است" };
    }

    if (!userData.role) {
      throw { status: 400, message: "نقش کاربر الزامی است" };
    }

    // Check if user with this national ID already exists
    const existingUser = await models.user.findOne({
      nationalId: userData.nationalId,
    });
    if (existingUser) {
      throw { status: 400, message: "کاربر با این کد ملی قبلا ثبت شده است" };
    }

    const newUser = await models.user.create({
      ...userData,
      accessGrants: accessGrantHelpers.normalizeAccessGrants(
        userData.accessGrants,
      ),
    });

    const populatedUser = await models.user
      .findById(newUser._id)
      .select("-__v")
      .populate("role");

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