const Form = require("../models/formModel");
const FormSubmission = require("../models/formSubmissionModel");
const { errorResponse } = require("../utils/errorResponseHandler");
const { logUserAction } = require("../utils/userActionLogger");


// CREATE form
const createForm = async (req, res) => {
  try {
    const { name, fields, description, status, orgId } = req.body;
    const userId = req.user?._id;

    if (!name || typeof name !== "string" || name.trim() === "") {
      return errorResponse(res, "Form name is required", 400);
    }

    // Check if form with same name already exists
    const existingForm = await Form.findOne({ name: name.trim() });
    if (existingForm) {
      return errorResponse(res, "Form name already exists", 409); 
    }

    if (!Array.isArray(fields) || fields.length === 0) {
      return errorResponse(res, "At least one field is required", 400);
    }

    for (const field of fields) {
      if (!field.fieldId || !field.label || !field.type) {
        return errorResponse(res, "Each field must have fieldId, label, and type", 400);
      }
      if ((field.type === "dropdown" || field.type === "radio") && (!field.options || field.options.length === 0)) {
        return errorResponse(res, `Options are required for ${field.type}`, 400);
      }
    }

    const form = await Form.create({
      name: name.trim(),
      description,
      status: status || "active",
      createdBy: userId,
      updatedBy: userId,
      fields,
      orgId
    });

    await logUserAction({
      userId,
      action: "CREATE",
      model: "Form",
      details: { formId: form._id, name: form.name },
      req
    });

    return res.status(201).json({
      success: true,
      message: "Form created successfully",
      data: form,
    });
  } catch (err) {
    return errorResponse(res, "Failed to create form", 500, err);
  }
};


// GET form by ID
const getFormById = async (req, res) => {
  try {
    const form = await Form.findById(req.params.id);
    if (!form) return errorResponse(res, "Form not found", 404);

    await logUserAction({ userId: req.user?._id, action: "READ", model: "Form", details: { formId: form._id }, req });

    return res.json({
      success: true,
      message: "Form fetched successfully",
      data: form,
    });
  } catch (err) {
    return errorResponse(res, "Failed to fetch form", 500, err);
  }
};

// GET all forms
const getForms = async (req, res) => {
  try {
    let { page = 1, limit = 10, orgId } = req.query;

    page = parseInt(page);
    limit = parseInt(limit);
    const skip = (page - 1) * limit;

    // Base query
    const query = { isDeleted: false };

    // If orgId is provided, filter by it
    if (orgId) {
      query.orgId = orgId;
    }

    const [forms, total] = await Promise.all([
      Form.find(query)
        .skip(skip)
        .limit(limit)
        .sort({ createdAt: -1 }),
      Form.countDocuments(query),
    ]);

    await logUserAction({
      userId: req.user?._id,
      action: "READ",
      model: "Form",
      details: { page, limit, orgId, count: forms.length },
      req,
    });

    return res.json({
      success: true,
      total,
      page,
      totalPages: Math.ceil(total / limit),
       forms,
    });
  } catch (err) {
    return errorResponse(res, "Failed to fetch forms", 500, err);
  }
};


// UPDATE form
const updateForm = async (req, res) => {
  try {
    const updatedForm = await Form.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
    if (!updatedForm) return errorResponse(res, "Form not found", 404);

    await logUserAction({ userId: req.user?._id, action: "UPDATE", model: "Form", details: { formId: updatedForm._id, updatedFields: req.body }, req });

    return res.json({
      success: true,
      message: "Form updated successfully",
      data: updatedForm,
    });
  } catch (err) {
    return errorResponse(res, "Failed to update form", 500, err);
  }
};

// UPDATE form status
const updateFormStatus = async (req, res) => {
  try {
    const { status } = req.body;
    if (typeof status !== "boolean") return errorResponse(res, "Invalid status value", 400);

    const updatedForm = await Form.findByIdAndUpdate(req.params.id, { status }, { new: true, runValidators: true });
    if (!updatedForm) return errorResponse(res, "Form not found", 404);

    await logUserAction({ userId: req.user?._id, action: "UPDATE_STATUS", model: "Form", details: { formId: updatedForm._id, status }, req });

    return res.json({
      success: true,
      message: "Form status updated successfully",
      data: updatedForm,
    });
  } catch (err) {
    return errorResponse(res, "Failed to update form status", 500, err);
  }
};

// SUBMIT a form
const submitForm = async (req, res) => {
  try {
    const { data } = req.body;
    const submittedBy = req.user?._id || "User";
    const formId = req.params.formId;

    const form = await Form.findById(formId);
    if (!form) return errorResponse(res, "Form not found", 404);

    const transformedData = Object.keys(data).map((fieldId) => {
      const field = form.fields.find(f => f.fieldId === fieldId);
      return {
        fieldId,
        label: field ? field.label : fieldId,
        value: data[fieldId]
      };
    });

    const submission = await FormSubmission.create({ formId, data: transformedData, submittedBy });

    await logUserAction({ userId: submittedBy, action: "SUBMIT", model: "FormSubmission", details: { submissionId: submission._id, formId }, req });

    return res.json({
      success: true,
      message: "Form submitted successfully",
      data: submission,
    });
  } catch (err) {
    return errorResponse(res, "Failed to submit form", 500, err);
  }
};

// GET submissions for a form
const getFormSubmissionsById = async (req, res) => {
  try {
    const formId = req.params.formId;
    const submissions = await FormSubmission.find({ formId });

    if (!submissions || submissions.length === 0) return errorResponse(res, "No submissions found for this form", 404);

    await logUserAction({ userId: req.user?._id, action: "READ_SUBMISSIONS", model: "FormSubmission", details: { formId, count: submissions.length }, req });

    return res.json({
      success: true,
      message: "Form submissions fetched successfully",
      submissions,
    });
  } catch (err) {
    return errorResponse(res, "Failed to fetch form submissions", 500, err);
  }
};

// SOFT DELETE form
const deleteForm = async (req, res) => {
  try {
    const userId = req.user?._id;
    const deletedForm = await Form.findByIdAndUpdate(req.params.id, { isDeleted: true, updatedBy: userId || null }, { new: true });
    if (!deletedForm) return errorResponse(res, "Form not found", 404);

    await logUserAction({ userId, action: "DELETE", model: "Form", details: { formId: deletedForm._id }, req });

    return res.json({
      success: true,
      message: "Form deleted successfully",
      data: deletedForm,
    });
  } catch (err) {
    return errorResponse(res, "Failed to delete form", 500, err);
  }
};

module.exports = { 
  createForm, 
  getForms, 
  getFormById, 
  updateForm, 
  updateFormStatus, 
  submitForm, 
  getFormSubmissionsById, 
  deleteForm 
};
