import Task from "./TaskModel.js";
import crypto from "crypto";
import cron from "node-cron";
import { sendPushNotification } from "../../Utils/sendPushNotification.js";
import SalesCoOrdinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js";
import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js";
// Function to update task statuses
export const updateOverdueTasks = async () => {
  try {
    const currentDate = new Date();
    const currentDateOnly = new Date(currentDate.setHours(0, 0, 0, 0));

    // Find tasks where dueDate is before the current date and status is "New"
    const overdueTasks = await Task.find({
      taskDueDate: { $lt: currentDateOnly },
      taskStatus: "New",
    });

    // Update tasks to "Pending"
    for (const task of overdueTasks) {
      task.taskStatus = "Pending";
      await task.save();
      // Fetch the Sales Coordinator who is assigned the task
      const salesCoordinator = await SalesCoOrdinator.findById(
        task.taskAssignedTo
      );

      if (salesCoordinator) {
        const fcmToken = salesCoordinator.fcm_token;
        if (fcmToken) {
          // Send push notification
          const message = `Your task "${task.task}" is Pending.`;
          await sendPushNotification(fcmToken, "Task Status Updated", message);
        }
      }
    }

    console.log('Overdue tasks updated to "Pending".');
  } catch (error) {
    console.error("Error updating overdue tasks:", error);
  }
};

// Schedule the cron job to run daily at midnight
// cron.schedule("5 9 * * *", updateOverdueTasks, {
//   timezone: "Asia/Kolkata",
// });

// cron.schedule("30 9 * * *", updateOverdueTasks);

const parseDate = (dateStr) => {
  const [day, month, year] = dateStr.split("/").map(Number);
  // Create a date object in local timezone
  const localDate = new Date(year, month - 1, day);
  // Convert to a date with time set to the start of the day in UTC
  return new Date(Date.UTC(year, month - 1, day));
};

export const assignTask = async (req, res) => {
  try {
    const {
      task,
      note,
      taskPriority,
      taskDueDate,
      taskAssignedTo,
      addedFor,
      addedForId,
      tradename,
    } = req.body;

    // Convert the taskDueDate from DD/MM/YYYY string to Date object
    const dueDate = parseDate(taskDueDate);
    const currentDate = new Date();

    // Set the time of the currentDate to the start of the day for comparison
    const currentDateOnly = new Date(
      Date.UTC(
        currentDate.getUTCFullYear(),
        currentDate.getUTCMonth(),
        currentDate.getUTCDate()
      )
    );

    // Check if the due date is in the past
    if (dueDate < currentDateOnly) {
      return res.status(400).json({
        success: false,
        message: "Due date cannot be earlier than the current date.",
      });
    }

    const currentYear = new Date().getFullYear().toString().slice(-2);
    const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase();
    const uniqueId = `${currentYear}-${randomChars}`;

    // Create a new task
    const newTask = await Task.create({
      taskId: uniqueId,
      task,
      note,
      taskStatus: "New",
      taskPriority,
      taskDueDate: dueDate, // Save the date as a Date object
      taskAssignedTo,
      taskAssignedBy: req.user._id,
      addedFor,
      addedForId,
      tradename,
    });
    // Fetch the FCM token of the assigned sales coordinator
    const salesCoordinator = await SalesCoOrdinator.findById(taskAssignedTo);

    if (!salesCoordinator) {
      return res.status(404).json({
        success: false,
        message: "Sales Coordinator not found.",
      });
    }

    const fcmToken = salesCoordinator.fcm_token;

    if (fcmToken) {
      // Send push notification
      const message = `You have been assigned a new task: ${task}`;
      await sendPushNotification(fcmToken, "New Task Assigned", message);
    }
    res.status(201).json({
      success: true,
      message: "Task assigned successfully",
      task: newTask,
    });
  } catch (error) {
    res.status(400).json({
      success: false,
      message: error.message,
    });
  }
};

export const getTasksByStatus = async (req, res) => {
  try {
    await updateOverdueTasks();
    const { status } = req.params; // This should be "New", "Pending", or "Completed"

    // Validate the provided status
    if (!["New", "Pending", "Completed"].includes(status)) {
      return res.status(400).json({
        success: false,
        message: "Invalid status type provided.",
      });
    }

    // Find tasks assigned to the user, filtered by status, and sorted by creation date (newest to oldest)
    const tasks = await Task.find({
      taskAssignedTo: req.user._id,
      taskStatus: status,
    }).sort({ createdAt: -1 }); // Sort by createdAt in descending order (-1 means newest first)

    res.status(200).json({
      success: true,
      tasks,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message,
    });
  }
};
const getStartAndEndOfDay = (date) => {
  const startOfDay = new Date(date);
  startOfDay.setUTCHours(0, 0, 0, 0); // Start of the day UTC

  const endOfDay = new Date(date);
  endOfDay.setUTCHours(23, 59, 59, 999); // End of the day UTC

  return { startOfDay, endOfDay };
};

export const getTasksByDates = async (req, res) => {
  try {
    await updateOverdueTasks();
    
    // Initialize filter object
    const filter = {};
    
    // Determine the filter based on user type
    if (req.userType === "SalesCoOrdinator") {
      filter.taskAssignedTo = req.user._id;  // Use `=` to assign values, and `===` for comparison
    } else {
      filter.taskAssignedBy = req.user._id;
    }

    // Get the date from the query
    const { Date: queryDate } = req.query;
    let taskDate;

    // If date is provided in query, parse it; otherwise, use today's date
    if (queryDate) {
      taskDate = parseDate(queryDate);
    } else {
      // Get today's date in UTC
      taskDate = new Date();
    }

    // Get the start and end of the day in UTC
    const { startOfDay, endOfDay } = getStartAndEndOfDay(taskDate);

    // Find tasks for the user, filtered by createdAt within the start and end of the day
    const tasks = await Task.find({
      ...filter,  // Use the filter object for querying
      createdAt: { $gte: startOfDay, $lte: endOfDay },
    })
      .populate({
        path: req.userType === "SalesCoOrdinator" ? "taskAssignedTo" : "taskAssignedBy", // Change path based on user type
        select: "name mobileNumber email",
      })
      .sort({ createdAt: -1 });

    res.status(200).json({
      success: true,
      tasks,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message,
    });
  }
};
export const getAllTasksByStatus = async (req, res) => {
  try {
    await updateOverdueTasks();
    const { status } = req.params; // This should be "New", "Pending", or "Completed"

    // Validate the provided status
    if (!["New", "Pending", "Completed"].includes(status)) {
      return res.status(400).json({
        success: false,
        message: "Invalid status type provided.",
      });
    }

    // Find tasks assigned to the user, filtered by status, and sorted by creation date (newest to oldest)
    const tasks = await Task.find({
      taskAssignedBy: req.user._id,
      taskStatus: status,
    })
      .populate({
        path: "taskAssignedTo",
        select: "name mobileNumber email",
      })
      .sort({ createdAt: -1 }); // Sort by createdAt in descending order (-1 means newest first)

    res.status(200).json({
      success: true,
      tasks,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message,
    });
  }
};
export const getTasksbytask = async (req, res) => {
  try {
    await updateOverdueTasks();
    const { task } = req.params;

    // Validate the provided status
    if (
      ![
        "Visit RD/PD",
        "Update Sales Data",
        "Update Inventory Data",
        "Collect KYC",
      ].includes(task)
    ) {
      return res.status(400).json({
        success: false,
        message: "Invalid task type provided.",
      });
    }
    const tasks = await Task.find({
      taskAssignedTo: req.user._id,
      task: task,
    }).sort({ createdAt: -1 });

    res.status(200).json({
      success: true,
      tasks,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message,
    });
  }
};
export const updateTaskStatus = async (req, res) => {
  try {
    const { taskId } = req.params;

    const task = await Task.findOne({
      _id: taskId,
      taskAssignedTo: req.user._id,
    });

    if (!task) {
      return res.status(404).json({
        success: false,
        message: "Task not found or you're not authorized to update this task.",
      });
    }

    // Update the task status to "Completed"
    task.taskStatus = "Completed";
    await task.save();
    // Fetch the Sales Coordinator who completed the task
    const salesCoordinator = await SalesCoOrdinator.findById(req.user._id);

    if (!salesCoordinator) {
      return res.status(404).json({
        success: false,
        message: "Sales Coordinator not found.",
      });
    }

    //  Fetch the FCM token of the Territory Manager
    const territoryManager = await TerritoryManager.findById(
      task.taskAssignedBy
    );

    if (!territoryManager) {
      return res.status(404).json({
        success: false,
        message: "Territory Manager not found.",
      });
    }

    const fcmToken = territoryManager.fcm_token;

    if (fcmToken) {
      // Send push notification
      const message = `Task "${task.task}" has been completed by ${salesCoordinator.name}.`;
      await sendPushNotification(fcmToken, "Task Completed", message);
    }
    res.status(200).json({
      success: true,
      message: "Task status updated to Completed.",
      task,
    });
  } catch (error) {
    res.status(400).json({
      success: false,
      message: error.message,
    });
  }
};
