const Document = require("../models/documentModel");
const { errorResponse } = require("../utils/errorResponseHandler");
const { logUserAction } = require("../utils/userActionLogger");
const path = require("path");
const fs = require("fs");

// const createDocument = async (req, res) => {
//   try {
//     const userId = req.user?._id;
//     const file = req.file;

//     const {
//       documentCode,
//       name,
//       category,
//       description,
//       issueDate,
//       expiryDate,
//       status,
//       orgId,
//       policyId,
//       branchId,
//     } = req.body;

//     if (!documentCode || !name || !category || !issueDate || !orgId) {
//       return errorResponse(res, "Required fields are missing", 400);
//     }

//     const existingDoc = await Document.findOne({ documentCode });
//     if (existingDoc) {
//       return errorResponse(res, "Document code already exists", 409);
//     }

//     const document = await Document.create({
//       documentCode,
//       name,
//       category,
//       description: description || null,
//       issueDate,
//       expiryDate: expiryDate || null,
//       status: status || "Active",

//       policyId: policyId || null,
//       branchId: branchId || null,

//       file: file
//         ? {
//           fileName: file.originalname,
//           fileUrl: `/uploads/documents/${file.filename}`,
//           fileType: file.mimetype,
//           fileSize: file.size,
//         }
//         : null,

//       orgId,
//       createdBy: userId,
//       updatedBy: userId,
//     });

//     await logUserAction({
//       userId,
//       action: "CREATE",
//       model: "Document",
//       details: {
//         documentId: document._id,
//         documentCode,
//         name,
//       },
//       req,
//     });

//     return res.status(201).json({
//       success: true,
//       message: "Document created successfully",
//       data: document,
//     });
//   } catch (err) {
//     console.error("Create Document Error:", err);
//     return res.status(500).json({
//       success: false,
//       message: "Failed to create document",
//       error: err.message,
//     });
//   }
// };

// const createDocument = async (req, res) => {
//   try {
//     const userId = req.user?._id;
//     const file = req.file;

//   const {
//   documentCode,
//   name,
//   category,
//   description,
//   issueDate,
//   expiryDate,
//   status,
// } = req.body;

// const orgId = req.user.orgId; // ✅ TRUST AUTH TOKEN
// console.log(orgId);


//     if (!documentCode || !name || !category || !issueDate || !orgId) {
//       return errorResponse(res, "Required fields are missing", 400);
//     }

//     const existingDoc = await Document.findOne({
//       documentCode,
//       orgId,
//     });

//     if (existingDoc) {
//       return errorResponse(res, "Document code already exists", 409);
//     }

//     const document = await Document.create({
//       documentCode,
//       name,
//       category,
//       description: description || null,
//       issueDate: new Date(issueDate),
//       expiryDate: expiryDate ? new Date(expiryDate) : null,
//       status: status || "Active",

//       // policyId: policyId || undefined,
//       // branchId: branchId || undefined,

//       file: file
//         ? {
//             fileName: file.originalname,
//             fileUrl: `/uploads/documents/${file.filename}`,
//             fileType: file.mimetype,
//             fileSize: file.size,
//           }
//         : null,

//       orgId,
//       createdBy: userId,
//       updatedBy: userId,
//     });

//     await logUserAction({
//       userId,
//       action: "CREATE",
//       model: "Document",
//       details: {
//         documentId: document._id,
//         documentCode,
//         name,
//       },
//       req,
//     });

//     return res.status(201).json({
//       success: true,
//       message: "Document created successfully",
//       data: document,
//     });
//   } catch (err) {
//     console.error("Create Document Error:", err);
//     return res.status(500).json({
//       success: false,
//       message: "Failed to create document",
//       error: err.message,
//     });
//   }
// };


const createDocument = async (req, res) => {
  try {
    const userId = req.user?._id;
    const orgId = req.user?.orgId;
    const file = req.file;

    const {
      documentCode,
      name,
      category,
      description,
      issueDate,
      expiryDate,
      status,
    } = req.body;

    if (!documentCode || !name || !category || !issueDate || !orgId) {
      return errorResponse(res, "Required fields are missing", 400);
    }

    const existingDoc = await Document.findOne({ documentCode, orgId });
    if (existingDoc) {
      return errorResponse(res, "Document code already exists", 409);
    }

    const document = await Document.create({
      documentCode,
      name,
      category,
      description: description || null,
      issueDate: new Date(issueDate),

      expiryDate:
        expiryDate && expiryDate !== "null" && expiryDate !== ""
          ? new Date(expiryDate)
          : null,

      status: status || "Active",

      file: file
        ? {
          fileName: file.originalname,
          fileUrl: `/uploads/images/${file.filename}`,
          fileType: file.mimetype,
          fileSize: file.size,
        }
        : null,

      orgId,
      createdBy: userId,
      updatedBy: userId,
    });

    return res.status(201).json({
      success: true,
      message: "Document created successfully",
      data: document,
    });
  } catch (err) {
    console.error("Create Document Error:", err);
    return res.status(500).json({
      success: false,
      message: "Failed to create document",
      error: err.message,
    });
  }
};


const getAllDocuments = async (req, res) => {
  try {
    let { page = 1, limit = 10 } = req.query;
    page = parseInt(page);
    limit = parseInt(limit);
    const skip = (page - 1) * limit;

    const filter = {
      isDeleted: false,
      orgId: req.user?.orgId, // org-level isolation
    };

    const [documents, total] = await Promise.all([
      Document.find(filter)
        .populate("createdBy", "firstName lastName email")
        .populate("updatedBy", "firstName lastName email")
        // .populate("policyId", "policyId name")
        // .populate("branchId", "branchName location")
        .select(
          "documentCode name category issueDate expiryDate status file createdAt updatedAt"
        )
        .skip(skip)
        .limit(limit)
        .sort({ createdAt: -1 }),

      Document.countDocuments(filter),
    ]);

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

    return res.json({
      success: true,
      total,
      page,
      totalPages: Math.ceil(total / limit),
      data: documents,
    });
  } catch (err) {
    console.error("Get All Documents Error:", err);
    return errorResponse(res, "Failed to fetch documents", 500, err);
  }
};


// controllers/org/documentController.js

const getDocumentById = async (req, res) => {
  try {

    //  Org-level + soft-delete safety
    const document = await Document.findOne({
      _id: req.params.id,
      orgId: req.user?.orgId,
      isDeleted: false,
    })
      .populate("createdBy", "firstName lastName email")
      .populate("updatedBy", "firstName lastName email")
      .select(
        `
        documentCode
        name
        category
        description
        issueDate
        expiryDate
        status
        isExpirable
        notifiedBeforeExpiry
        file
        createdAt
        updatedAt
        `
      );

    if (!document) {
      return errorResponse(res, "Document not found", 404);
    }

    // 🧾 Audit log
    await logUserAction({
      userId: req.user?._id,
      action: "READ",
      model: "Document",
      details: { documentId: document._id },
      req,
    });

    return res.json({
      success: true,
      data: document,
    });
  } catch (err) {
    console.error("Get Document By ID Error:", err);
    return errorResponse(res, "Failed to fetch document", 500, err);
  }
};


const deleteDocument = async (req, res) => {
  try {
    const userId = req.user?._id;

    const document = await Document.findByIdAndUpdate(
      req.params.id,
      { isDeleted: true, updatedBy: userId },
      { new: true }
    );

    if (!document) return errorResponse(res, "Task not found", 404);

    await logUserAction({
      userId,
      action: "DELETE",
      model: "Document",
      details: { documentId: document._id },
      req,
    });

    return res.json({
      success: true,
      message: "Document deleted successfully",
      data: document,
    });

  } catch (err) {
    return errorResponse(res, "Failed to delete document", 500, err);
  }
};

// const updateDocument = async (req, res) => {
//   try {
//     const documentId = req.params.id;
//     const userId = req.user?._id;

//     const existingDoc = await Document.findById(documentId);
//     if (!existingDoc) {
//       return errorResponse(res, "Document not found", 404);
//     }
//     const updatedData = {
//       documentCode: req.body.documentCode ?? existingDoc.documentCode,
//       name: req.body.name ?? existingDoc.name,
//       category: req.body.category ?? existingDoc.category,
//       issueDate: req.body.issueDate ?? existingDoc.issueDate,
//       expiryDate: req.body.expiryDate ?? existingDoc.expiryDate,
//       status: req.body.status ?? existingDoc.status,
//       updatedBy: userId,
//     };
//     if (req.file) {
//       updatedData.fileUrl = req.file.path; // or req.file.filename 
//     }
//     const updatedDocument = await Document.findByIdAndUpdate(
//       documentId,
//       { $set: updatedData },
//       { new: true, runValidators: true }
//     );
//     await logUserAction({
//       userId,
//       action: "UPDATE",
//       model: "Document",
//       details: {
//         documentId: updatedDocument._id,
//         updatedFields: Object.keys(updatedData),
//       },
//       req,
//     });
//     return res.status(200).json({
//       success: true,
//       message: "Document updated successfully",
//       data: updatedDocument,
//     });

//   } catch (err) {
//     console.error("Update Document Error:", err);
//     return errorResponse(res, "Failed to update document", 500, err);
//   }
// };
// const path = require("path");
// const fs = require("fs");

const updateDocument = async (req, res) => {
  try {
    const documentId = req.params.id;
    const userId = req.user?._id;

    const existingDoc = await Document.findById(documentId);
    if (!existingDoc) {
      return errorResponse(res, "Document not found", 404);
    }

    const updatedData = {
      documentCode: req.body.documentCode ?? existingDoc.documentCode,
      name: req.body.name ?? existingDoc.name,
      category: req.body.category ?? existingDoc.category,
      issueDate: req.body.issueDate ?? existingDoc.issueDate,
      expiryDate: req.body.expiryDate ?? existingDoc.expiryDate,
      status: req.body.status ?? existingDoc.status,
      updatedBy: userId,
    };

    // ✅ FILE REPLACEMENT LOGIC (ONLY HERE)
    if (req.file) {
      if (existingDoc.file?.fileUrl) {
        const oldPath = path.join(__dirname, "..", existingDoc.file.fileUrl);
        if (fs.existsSync(oldPath)) fs.unlinkSync(oldPath);
      }

      updatedData.file = {
        fileName: req.file.filename, // ✅ multer-generated name
        fileUrl: `/uploads/${req.file.mimetype.startsWith("image") ? "images" : "docs"
          }/${req.file.filename}`,
        fileType: req.file.mimetype,
        fileSize: req.file.size, // bytes
      };

    }

    const updatedDocument = await Document.findByIdAndUpdate(
      documentId,
      { $set: updatedData },
      { new: true, runValidators: true }
    );

    await logUserAction({
      userId,
      action: "UPDATE",
      model: "Document",
      details: {
        documentId: updatedDocument._id,
        updatedFields: Object.keys(updatedData),
      },
      req,
    });

    return res.status(200).json({
      success: true,
      message: "Document updated successfully",
      data: updatedDocument,
    });
  } catch (err) {
    console.error("Update Document Error:", err);
    return errorResponse(res, "Failed to update document", 500, err);
  }
};



module.exports = {
  createDocument,
  getAllDocuments,
  deleteDocument,
  updateDocument,
  getDocumentById,
};
