import mongoose from "mongoose";
import cloudinary from "../../Utils/cloudinary.js";
import { KYC } from "./KycModel.js";
import User from "../user/userModel.js";
import { createKYC, rejectKYC } from "../../Utils/rejectKyc.js";
import SalesCoOrdinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js";
import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js";
import { Notification } from "../Notification/notificationModal.js";
import RetailDistributor from "../RetailDistributor/RetailDistributorModel.js";
import { generatePassword } from "../../Utils/generatepassword.js";
import sendEmail, { sendOtp } from "../../Utils/sendEmail.js";
export const createKyc = async (req, res) => {
  const {
    name,
    email,
    trade_name,
    address,
    state,
    city,
    district,
    pincode,
    mobile_number,
    principal_distributer,
    pan_number,
    aadhar_number,
    gst_number,

    notes,
  } = req.body;

  const {
    selfie_entrance_img,
    pan_img,
    aadhar_img,
    gst_img,
    pesticide_license_img,
  } = req.files;

  let fertilizer_license_img;
  if (req.files && req.files.fertilizer_license_img) {
    fertilizer_license_img = req.files.fertilizer_license_img;
  }

  if (!req?.user) return res.status(400).json({ message: "Please login!" });
  const userType = req.userType;
  try {
    if (!mongoose.Types.ObjectId.isValid(req.user._id)) {
      return res.status(400).json({ message: "Please login again" });
    }
    const isExits = await KYC.find({ email: email });
    if (isExits.length > 0) {
      throw new Error("Email already exists");
    }
    // Upload images to Cloudinary and store only public_id and url
    const uploadImage = async (image, folder) => {
      if (!image) return null;
      const result = await cloudinary.v2.uploader.upload(image.tempFilePath, {
        folder,
      });
      return {
        public_id: result.public_id,
        url: result.secure_url,
      };
    };

    const panImg = await uploadImage(pan_img, "KYC/pan");
    const aadharImg = await uploadImage(aadhar_img, "KYC/aadhar");
    const gstImg = await uploadImage(gst_img, "KYC/gst");
    const pesticideLicenseImg = await uploadImage(
      pesticide_license_img,
      "KYC/pesticide_license"
    );
    const fertilizerLicenseImg = await uploadImage(
      fertilizer_license_img,
      "KYC/fertilizer_license"
    );
    const selfieEntranceImg = await uploadImage(
      selfie_entrance_img,
      "KYC/selfie_entrance"
    );

    // Create KYC document
    const kyc = await KYC.create({
      name,
      email,
      trade_name,
      address,
      state,
      city,
      district,
      pincode,
      mobile_number,
      principal_distributer,
      pan_number,
      pan_img: panImg,
      aadhar_number,
      aadhar_img: aadharImg,
      gst_number,
      gst_img: gstImg,
      pesticide_license_img: pesticideLicenseImg,
      fertilizer_license_img: fertilizerLicenseImg || {},
      selfie_entrance_img: selfieEntranceImg,
      addedBy: req.user._id,
      userType: userType,
      notes,
    });

    if (principal_distributer) {
      await createKYC(
        kyc.principal_distributer,
        "KYC Created",
        `${trade_name} sent request to approve the KYC .`
      );
      await Notification.create({
        title: "KYC Created",
        msg: `KYC created for the trade name ${name}`,
        kyc_ref: kyc._id,
        added_for: kyc.principal_distributer,
      });
    }
    if (kyc) {
      return res
        .status(201)
        .json({ success: true, kyc, message: "KYC created" });
    }
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message ? error.message : "Something went wrong",
    });
  }
};
export const createretaildistributor = async (req, res) => {
  const {
    name,
    email,
    trade_name,
    address,
    state,
    city,
    district,
    pincode,
    mobile_number,
    pan_number,
    aadhar_number,
    gst_number,
  } = req.body;

  try {
    if (!mongoose.Types.ObjectId.isValid(req.user._id)) {
      return res.status(400).json({ message: "Please login again" });
    }

    if (!req.files) {
      return res.status(400).json({ message: "No files were uploaded." });
    }

    const {
      selfieEntranceImg,
      panImg,
      aadharImg,
      gstImg,
      pesticideLicenseImg,
    } = req.files;
    // console.log(req.files);
    const fertilizerLicenseImg = req.files.fertilizerLicenseImg || null;

    if (
      !panImg ||
      !aadharImg ||
      !gstImg ||
      !selfieEntranceImg ||
      !pesticideLicenseImg
    ) {
      return res
        .status(400)
        .json({ message: "Please upload all required images." });
    }

    // Upload images to Cloudinary
    const uploadImage = async (image, folder) => {
      if (!image) return null;
      const result = await cloudinary.v2.uploader.upload(image.tempFilePath, {
        folder,
      });
      return {
        public_id: result.public_id,
        url: result.secure_url,
      };
    };

    const pan_img = await uploadImage(panImg, "KYC/pan");
    const aadhar_img = await uploadImage(aadharImg, "KYC/aadhar");
    const gst_img = await uploadImage(gstImg, "KYC/gst");
    const pesticide_license_img = await uploadImage(
      pesticideLicenseImg,
      "KYC/pesticide_license"
    );
    const fertilizer_license_img = await uploadImage(
      fertilizerLicenseImg,
      "KYC/fertilizer_license"
    );
    const selfie_entrance_img = await uploadImage(
      selfieEntranceImg,
      "KYC/selfie_entrance"
    );

    // Create KYC document
    const kycData = {
      name,
      email,
      trade_name,
      address,
      state,
      city,
      district,
      pincode,
      mobile_number,
      pan_number,
      pan_img,
      aadhar_number,
      aadhar_img,
      gst_number,
      gst_img,
      pesticide_license_img,
      fertilizer_license_img: fertilizer_license_img || null, // Optional field
      selfie_entrance_img,
      status: "approved",
    };

    const kyc = await KYC.create(kycData);
    if (!kyc) {
      return res.status(400).json({ message: "Failed to create KYC." });
    }

    // Generate password
    const password = generatePassword(name, email);
    // Create RetailDistributor document
    const retailDistributorData = {
      name,
      email,
      mobile_number,
      kyc: kyc._id,
      password,
    };
    const retailDistributor = new RetailDistributor(retailDistributorData);
    await retailDistributor.save();
    // Send email with the new password
    await sendEmail({
      to: `${email}`, // Change to your recipient
      from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender
      subject: `Cheminova Account Created`,
      html: `Your Retail Distributor Account is created successfully.
          <br/>name is: <strong>${name}</strong>
          <br/>
          <br/>MobileNumber is: <strong>${mobile_number}</strong><br/>
          <br/>Email is: <strong>${email}</strong><br/>
          <br/>password is: <strong>${password}</strong><br/><br/>If you have not requested this email, please ignore it.`,
    });
    // Send response
    res.status(201).json({
      success: true,
      kyc,
      retailDistributor,
      message: "Retail Distributor created successfully",
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message ? error.message : "Something went wrong!",
    });
  }
};

// Get All KYC
export const getAllKyc = async (req, res) => {
  try {
    // Fetch all KYC documents from the database
    // console.log("req came here ");
    // console.log(req.user._id);
    const kycs = await KYC.find({ principal_distributer: req.user._id })
      .populate("principal_distributer", "name")
      .populate("addedBy");
    // console.log(kycs);
    // Send the fetched data as a response
    res.status(200).json(kycs);
  } catch (error) {
    // Handle any errors that occur during the fetch operation
    console.log(error);
    res.status(500).json({ message: "Server Error", error });
  }
};
// Get all KYC Rejected
export const getAllKycRejected = async (req, res) => {
  try {
    // Fetch all KYC documents from the database
    // console.log("req came here ");

    const kycs = await KYC.find({ status: "reject", addedBy: req.user._id })
      .sort({ createdAt: -1 })
      .populate("principal_distributer", "name")
      .populate("addedBy");
    // console.log(kycs);
    // Send the fetched data as a response
    res.status(200).json(kycs);
  } catch (error) {
    // Handle any errors that occur during the fetch operation
    console.log(error);
    res.status(500).json({ message: "Server Error", error });
  }
};
// Get All KYC Approved
export const getAllKycApproved = async (req, res) => {
  try {
    // Extract query parameters from the request
    const { page = 1, show = 10, name, principaldistributor } = req.query;
    const skip = (page - 1) * show;

    // Build the main query object
    const query = { status: "approved" };

    // If a trade name is provided, add it to the query
    if (name) {
      query.trade_name = new RegExp(name, "i"); // Case-insensitive search for trade name
    }

    // If a principal distributor name is provided, find the matching distributor IDs
    let principalDistributerIds = [];
    if (principaldistributor) {
      const matchingDistributors = await mongoose.model("User").find(
        {
          name: new RegExp(principaldistributor, "i"), // Case-insensitive search for principal distributor name
        },
        "_id"
      ); // Only return the _id field

      principalDistributerIds = matchingDistributors.map(
        (distributor) => distributor._id
      );

      // If matching distributors are found, add the IDs to the main query
      if (principalDistributerIds.length > 0) {
        query.principal_distributer = { $in: principalDistributerIds };
      }
    }

    // Find the KYC records with pagination and populate specific fields
    const kycs = await KYC.find(query)
      .sort({ createdAt: -1 })
      .populate("principal_distributer", "name") // Only include the 'name' field
      .populate("addedBy")
      .skip(skip)
      .limit(parseInt(show));

    // Get total count of documents that match the query
    const total_data = await KYC.countDocuments(query);

    // Send the response with pagination data
    res.status(200).json({
      success: true,
      total_data,
      total_pages: Math.ceil(total_data / show),
      kycs,
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: "Server Error", error });
  }
};

// Get Single KYC
export const getKycById = async (req, res) => {
  try {
    // Get the KYC ID from the request parameters
    const { id } = req.params;

    // Fetch the KYC document from the database by ID
    const kyc = await KYC.findById(id)
      .populate("principal_distributer", "name")
      .populate("addedBy");

    // Check if the KYC document exists
    if (!kyc) {
      return res.status(404).json({ message: "KYC document not found" });
    }

    // Send the fetched KYC document as a response
    res.status(200).json(kyc);
  } catch (error) {
    // Handle any errors that occur during the fetch operation
    res.status(500).json({ message: "Server Error", error });
  }
};

export const updateKycStatus = async (req, res) => {
  const { status, rejectionReason, user } = req.body;
  const { id } = req.params;

  try {
    // Find the KYC document by ID
    const kyc = await KYC.findById(id);

    if (!kyc) {
      return res.status(404).json({ message: "KYC record not found" });
    }

    // Check if the user has access
    if (kyc.principal_distributer.toString() !== req.user._id.toString()) {
      return res.status(403).json({ message: "Access denied" });
    }

    const trade_name = kyc.trade_name;

    if (status === "approved") {
      kyc.status = status;

      await rejectKYC(
        kyc.addedBy,
        "KYC Approved",
        `Your KYC for ${trade_name} has been approved.`
      );
      await Notification.create({
        title: "KYC Approved",
        msg: `Your KYC for ${trade_name} has been approved.`,
        kyc_ref: kyc._id,
        added_for: kyc.addedBy,
      });

      // Generate a secure password for RetailDistributor
      const password = generatePassword(kyc.name, kyc.email);

      // Create RetailDistributor document
      const retailDistributorData = {
        name: kyc.name,
        email: kyc.email,
        mobile_number: kyc.mobile_number,
        principal_distributer: kyc.principal_distributer,
        addedBy: kyc.addedBy,
        userType: kyc.userType,
        kyc: kyc._id,
        password,
      };

      const retailDistributor = new RetailDistributor(retailDistributorData);
      await retailDistributor.save();

      // Send email with the new password
      await sendEmail({
        to: kyc.email,
        from: process.env.SEND_EMAIL_FROM,
        subject: `Cheminova Account Created`,
        html: `Your Retail Distributor Account is created successfully.
          <br/>name is: <strong>${kyc.name}</strong>
          <br/>Mobile Number is: <strong>${kyc.mobile_number}</strong><br/>
          <br/>Email is: <strong>${kyc.email}</strong><br/>
          <br/>password is: <strong>${password}</strong><br/><br/>If you have not requested this email, please ignore it.`,
      });
    }

    if (status === "reject") {
      await rejectKYC(
        kyc.addedBy,
        "KYC application Rejected",
        `KYC for ${trade_name} has been rejected. Reason: ${rejectionReason}`
      );
      await Notification.create({
        title: "KYC Rejected",
        msg: `KYC for ${trade_name} has been rejected. Reason: ${rejectionReason}`,
        kyc_ref: kyc._id,
        added_for: kyc.addedBy,
      });
    }

    // Update rejection reason in notes if status is rejected
    if (kyc.status === "reject" || status === "reject") {
      if (status) {
        kyc.status = status;
      }

      kyc.notes.push({
        message: rejectionReason,
        user: user,
        replyDate: new Date(),
      });
    }

    // Save the updated KYC document
    await kyc.save();

    // Populate principal_distributer and addedBy fields
    const updatedKyc = await KYC.findById(kyc._id)
      .populate("principal_distributer", "name") // Populate specific fields if needed
      .populate("addedBy");

    // Send the populated KYC in the response
    res
      .status(200)
      .json({ message: "KYC status updated successfully", kyc: updatedKyc });
  } catch (error) {
    console.log(error);
    res.status(500).json({ message: "Error updating KYC status", error });
  }
};

export const getAllPrincipalDistributers = async (req, res) => {
  try {
    // Define the filter for the query
    let filter = { role: "principal-Distributor" };
    // Check the user type and adjust the filter accordingly
    if (req.userType === "SalesCoOrdinator") {
      // If userType is "SalesCoOrdinator", filter by req.user.mappedBy
      filter.mappedby = req.user.mappedby;
    } else {
      // Otherwise, filter by req.user._id
      filter.mappedby = req.user._id;
    }
    // console.log(filter);
    // Fetch the principal distributors based on the filter
    const principalDistributers = await User.find(filter);
    // console.log(principalDistributers);
    // Send the fetched data as a response
    if (principalDistributers.length > 0) {
      res.status(200).json(principalDistributers);
    } else {
      res.status(404).json({ message: "No Principal Distributors found" });
    }
  } catch (error) {
    // Handle any errors that occur during the fetch operation
    res.status(500).json({ message: "Server Error", error });
  }
};

// Fcm token storing
export const saveFCMTokenForSC = async (req, res) => {
  const { fcmToken } = req.body;
  const userId = req.user._id;

  try {
    // Fetch the current FCM token for the user
    const user = await SalesCoOrdinator.findById(userId);

    if (!user) {
      return res.status(404).send("User not found");
    }

    // Check if the new FCM token is different from the current one
    if (user.fcm_token && user.fcm_token === fcmToken) {
      return res.status(200).send("FCM Token is already up to date");
    }

    // Update the FCM token
    user.fcm_token = fcmToken;
    await user.save();

    res.status(200).send("FCM Token saved successfully");
  } catch (error) {
    console.error("Error saving FCM Token:", error);
    res.status(500).send("Internal Server Error");
  }
};

export const saveFCMTokenForTM = async (req, res) => {
  const { fcmToken } = req.body;
  const userId = req.user._id;

  try {
    // Fetch the current FCM token for the user
    const user = await TerritoryManager.findById(userId);

    if (!user) {
      return res.status(404).send("User not found");
    }

    // Check if the new FCM token is different from the current one
    if (user.fcm_token && user.fcm_token === fcmToken) {
      return res.status(200).send("FCM Token is already up to date");
    }

    // Update the FCM token
    user.fcm_token = fcmToken;
    await user.save();

    res.status(200).send("FCM Token saved successfully");
  } catch (error) {
    console.error("Error saving FCM Token:", error);
    res.status(500).send("Internal Server Error");
  }
};
