const TherapyPlan = require("../models/TherapyPlan");
const User = require("../models/userModel");
const Appointment = require("../models/Appointment");
const { sendEmail } = require("../utils/sendEmail");
const { sendMessage } = require("../utils/sendMessage");

// Create a new therapy plan
const createTherapyPlan = async (req, res) => {
  try {
    const {
      clientId,
      title,
      goals,
      customGoals,
      approaches,
      customApproaches,
      numberOfSessions,
      timeline,
      customTimeline,
      description,
      therapistNotes,
    } = req.body;

    // Verify therapist authorization
    const therapistId = req.user.id;
    const therapist = await User.findById(therapistId);

    if (!therapist || therapist.role !== "doctor") {
      return res.status(403).json({
        success: false,
        message: "Only therapists can create therapy plans",
      });
    }

    // Verify client exists
    const client = await User.findById(clientId);
    if (!client || client.role !== "user") {
      return res.status(404).json({
        success: false,
        message: "Client not found",
      });
    }

    // Check if there's already an active plan for this client-therapist pair
    const existingPlan = await TherapyPlan.findOne({
      client: clientId,
      therapist: therapistId,
      isActive: true,
      isArchived: false,
      planStatus: { $in: ["Plan Not Sent", "Draft Created", "Plan Sent"] },
    });

    if (existingPlan) {
      return res.status(400).json({
        success: false,
        message: "An active therapy plan already exists for this client",
      });
    }

    // Create new therapy plan
    const therapyPlan = new TherapyPlan({
      client: clientId,
      therapist: therapistId,
      title,
      goals: goals || [],
      customGoals: customGoals || [],
      approaches: approaches || [],
      customApproaches: customApproaches || [],
      numberOfSessions,
      timeline,
      customTimeline,
      description,
      therapistNotes,
      planStatus: "Draft Created",
    });

    await therapyPlan.save();

    // Populate the response
    await therapyPlan.populate([
      { path: "client", select: "fullname email mobile" },
      { path: "therapist", select: "fullname email" },
    ]);

    res.status(201).json({
      success: true,
      message: "Therapy plan created successfully",
      data: therapyPlan,
    });
  } catch (error) {
    console.error("Error creating therapy plan:", error);
    res.status(500).json({
      success: false,
      message: "Failed to create therapy plan",
      error: error.message,
    });
  }
};

// Get therapy plans for a therapist
const getTherapistPlans = async (req, res) => {
  try {
    const therapistId = req.user.id;
    const { status, page = 1, limit = 10, clientId } = req.query;

    // Build query
    let query = {
      therapist: therapistId,
      isArchived: false,
    };

    if (status) {
      query.planStatus = status;
    }

    if (clientId) {
      query.client = clientId;
    }

    // Calculate pagination
    const skip = (page - 1) * limit;

    // Get plans with pagination
    const plans = await TherapyPlan.find(query)
      .populate([
        { path: "client", select: "fullname email mobile" },
        { path: "therapist", select: "fullname email" },
      ])
      .sort({ createdAt: -1 })
      .skip(skip)
      .limit(parseInt(limit));

    // Get total count
    const totalPlans = await TherapyPlan.countDocuments(query);

    // Get status summary
    const statusSummary = await TherapyPlan.aggregate([
      { $match: { therapist: therapistId, isArchived: false } },
      { $group: { _id: "$planStatus", count: { $sum: 1 } } },
    ]);

    res.status(200).json({
      success: true,
      data: {
        plans,
        pagination: {
          currentPage: parseInt(page),
          totalPages: Math.ceil(totalPlans / limit),
          totalPlans,
          hasNext: page * limit < totalPlans,
          hasPrev: page > 1,
        },
        statusSummary: statusSummary.reduce((acc, item) => {
          acc[item._id] = item.count;
          return acc;
        }, {}),
      },
    });
  } catch (error) {
    console.error("Error fetching therapist plans:", error);
    res.status(500).json({
      success: false,
      message: "Failed to fetch therapy plans",
      error: error.message,
    });
  }
};

// Get therapy plans for a client
const getClientPlans = async (req, res) => {
  try {
    const clientId = req.user.id;
    const { status, page = 1, limit = 10 } = req.query;

    // Build query
    let query = {
      client: clientId,
      isArchived: false,
      planStatus: { $ne: "Draft Created" }, // Don't show drafts to clients
    };

    if (status) {
      query.planStatus = status;
    }

    // Calculate pagination
    const skip = (page - 1) * limit;

    // Get plans with pagination
    const plans = await TherapyPlan.find(query)
      .populate([{ path: "therapist", select: "fullname email" }])
      .sort({ createdAt: -1 })
      .skip(skip)
      .limit(parseInt(limit));

    // Get total count
    const totalPlans = await TherapyPlan.countDocuments(query);

    res.status(200).json({
      success: true,
      data: {
        plans,
        pagination: {
          currentPage: parseInt(page),
          totalPages: Math.ceil(totalPlans / limit),
          totalPlans,
          hasNext: page * limit < totalPlans,
          hasPrev: page > 1,
        },
      },
    });
  } catch (error) {
    console.error("Error fetching client plans:", error);
    res.status(500).json({
      success: false,
      message: "Failed to fetch therapy plans",
      error: error.message,
    });
  }
};

// Get all therapy plans (Admin only)
const getAllPlans = async (req, res) => {
  try {
    // Admin authorization is handled by middleware

    const { status, therapistId, clientId, page = 1, limit = 10 } = req.query;

    // Build query
    let query = { isArchived: false };

    if (status) {
      query.planStatus = status;
    }

    if (therapistId) {
      query.therapist = therapistId;
    }

    if (clientId) {
      query.client = clientId;
    }

    // Calculate pagination
    const skip = (page - 1) * limit;

    // Get plans with pagination
    const plans = await TherapyPlan.find(query)
      .populate([
        { path: "client", select: "fullname email mobile" },
        { path: "therapist", select: "fullname email" },
      ])
      .sort({ createdAt: -1 })
      .skip(skip)
      .limit(parseInt(limit));

    // Get total count
    const totalPlans = await TherapyPlan.countDocuments(query);

    // Get comprehensive statistics
    const stats = await TherapyPlan.aggregate([
      { $match: { isArchived: false } },
      {
        $group: {
          _id: null,
          totalPlans: { $sum: 1 },
          plansSent: {
            $sum: { $cond: [{ $eq: ["$planStatus", "Plan Sent"] }, 1, 0] },
          },
          plansAccepted: {
            $sum: {
              $cond: [
                {
                  $in: [
                    "$planStatus",
                    ["Plan Accepted- Individual", "Plan Accepted- Package"],
                  ],
                },
                1,
                0,
              ],
            },
          },
          noResponse: {
            $sum: {
              $cond: [{ $eq: ["$planStatus", "No Response (7+ Days)"] }, 1, 0],
            },
          },
          drafts: {
            $sum: { $cond: [{ $eq: ["$planStatus", "Draft Created"] }, 1, 0] },
          },
        },
      },
    ]);

    res.status(200).json({
      success: true,
      data: {
        plans,
        pagination: {
          currentPage: parseInt(page),
          totalPages: Math.ceil(totalPlans / limit),
          totalPlans,
          hasNext: page * limit < totalPlans,
          hasPrev: page > 1,
        },
        statistics: stats[0] || {
          totalPlans: 0,
          plansSent: 0,
          plansAccepted: 0,
          noResponse: 0,
          drafts: 0,
        },
      },
    });
  } catch (error) {
    console.error("Error fetching all plans:", error);
    res.status(500).json({
      success: false,
      message: "Failed to fetch therapy plans",
      error: error.message,
    });
  }
};

// Get a specific therapy plan
const getTherapyPlan = async (req, res) => {
  try {
    const { planId } = req.params;
    const userId = req.user.id;
    const userRole = req.user.role;

    const plan = await TherapyPlan.findById(planId).populate([
      { path: "client", select: "fullname email mobile" },
      { path: "therapist", select: "fullname email" },
      { path: "modifications.modifiedBy", select: "fullname email" },
    ]);

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

    // Check authorization
    const isAuthorized =
      userRole === "admin" ||
      plan.therapist._id.toString() === userId ||
      (plan.client._id.toString() === userId &&
        plan.planStatus !== "Draft Created");

    if (!isAuthorized) {
      return res.status(403).json({
        success: false,
        message: "Not authorized to view this therapy plan",
      });
    }

    res.status(200).json({
      success: true,
      data: plan,
    });
  } catch (error) {
    console.error("Error fetching therapy plan:", error);
    res.status(500).json({
      success: false,
      message: "Failed to fetch therapy plan",
      error: error.message,
    });
  }
};

// Update therapy plan
const updateTherapyPlan = async (req, res) => {
  try {
    const { planId } = req.params;
    const therapistId = req.user.id;
    const updateData = req.body;

    const plan = await TherapyPlan.findById(planId);

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

    // Check if therapist owns this plan
    if (plan.therapist.toString() !== therapistId) {
      return res.status(403).json({
        success: false,
        message: "Not authorized to update this therapy plan",
      });
    }

    // Check if plan can be modified
    if (!plan.canBeModified()) {
      return res.status(400).json({
        success: false,
        message: "Plan cannot be modified in current status",
      });
    }

    // Store original data for modification history
    const originalData = plan.toObject();

    // Update the plan
    Object.keys(updateData).forEach((key) => {
      if (key !== "_id" && key !== "createdAt" && key !== "updatedAt") {
        plan[key] = updateData[key];
      }
    });

    // Add modification record
    plan.modifications.push({
      modifiedBy: therapistId,
      changes: updateData,
      reason: updateData.modificationReason || "Plan updated",
    });

    await plan.save();

    // Populate the response
    await plan.populate([
      { path: "client", select: "fullname email mobile" },
      { path: "therapist", select: "fullname email" },
    ]);

    res.status(200).json({
      success: true,
      message: "Therapy plan updated successfully",
      data: plan,
    });
  } catch (error) {
    console.error("Error updating therapy plan:", error);
    res.status(500).json({
      success: false,
      message: "Failed to update therapy plan",
      error: error.message,
    });
  }
};

// Send therapy plan to client
const sendTherapyPlan = async (req, res) => {
  try {
    const { planId } = req.params;
    const therapistId = req.user.id;

    const plan = await TherapyPlan.findById(planId).populate([
      { path: "client", select: "fullname email mobile" },
      { path: "therapist", select: "fullname email" },
    ]);

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

    // Check if therapist owns this plan
    if (plan.therapist._id.toString() !== therapistId) {
      return res.status(403).json({
        success: false,
        message: "Not authorized to send this therapy plan",
      });
    }

    // Send the plan
    await plan.sendToClient();

    // Send email notification to client
    // try {
    //   const emailContent = `
    //     Dear ${plan.client.fullname},

    //     Your therapist ${plan.therapist.fullname} has created a personalized therapy plan for you.

    //     Plan Title: ${plan.title}
    //     Number of Sessions: ${plan.numberOfSessions}
    //     Timeline: ${plan.timeline}

    //     Please log in to your account to review and respond to the therapy plan.

    //     Best regards,
    //     Mending Mind Team
    //   `;

    //   await sendEmail(
    //     plan.client.email,
    //     "New Therapy Plan Available",
    //     emailContent
    //   );
    // } catch (emailError) {
    //   console.error("Error sending email notification:", emailError);
    // }

    // Send SMS notification if mobile number exists
    if (plan.client.mobile) {
      try {
        const smsContent = `Hi ${plan.client.fullname}, your therapist has sent you a new therapy plan. Please check your account to review it. - Mending Mind`;
        // await sendMessage(plan.client.mobile, smsContent);
      } catch (smsError) {
        console.error("Error sending SMS notification:", smsError);
      }
    }

    res.status(200).json({
      success: true,
      message: "Therapy plan sent to client successfully",
      data: plan,
    });
  } catch (error) {
    console.error("Error sending therapy plan:", error);
    res.status(500).json({
      success: false,
      message: "Failed to send therapy plan",
      error: error.message,
    });
  }
};

// Client responds to therapy plan
const respondToTherapyPlan = async (req, res) => {
  try {
    const { planId } = req.params;
    const { response, acceptanceType, notes } = req.body;
    const clientId = req.user.id;

    const plan = await TherapyPlan.findById(planId).populate([
      { path: "client", select: "fullname email mobile" },
      { path: "therapist", select: "fullname email" },
    ]);

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

    // Check if client owns this plan
    if (plan.client._id.toString() !== clientId) {
      return res.status(403).json({
        success: false,
        message: "Not authorized to respond to this therapy plan",
      });
    }

    // Check if plan is in correct status
    if (plan.planStatus !== "Plan Sent") {
      return res.status(400).json({
        success: false,
        message: "Plan is not available for response",
      });
    }

    // Add client notes if provided
    if (notes) {
      plan.clientNotes = notes;
    }

    // Handle response
    if (response === "Accepted") {
      await plan.acceptPlan(acceptanceType);
    } else if (response === "Rejected") {
      await plan.rejectPlan(notes);
    } else {
      // Update response status for other types
      plan.clientResponse = response;
      plan.clientResponseDate = new Date();
      await plan.save();
    }

    // Send notification to therapist
    // try {
    //   const emailContent = `
    //     Dear ${plan.therapist.fullname},

    //     Your client ${
    //       plan.client.fullname
    //     } has responded to the therapy plan "${plan.title}".

    //     Response: ${response}
    //     ${notes ? `Client Notes: ${notes}` : ""}

    //     Please log in to your dashboard to view the details.

    //     Best regards,
    //     Mending Mind Team
    //   `;

    //   await sendEmail(
    //     plan.therapist.email,
    //     "Client Response to Therapy Plan",
    //     emailContent
    //   );
    // } catch (emailError) {
    //   console.error("Error sending therapist notification:", emailError);
    // }

    res.status(200).json({
      success: true,
      message: "Response recorded successfully",
      data: plan,
    });
  } catch (error) {
    console.error("Error responding to therapy plan:", error);
    res.status(500).json({
      success: false,
      message: "Failed to record response",
      error: error.message,
    });
  }
};

// Archive therapy plan
const archiveTherapyPlan = async (req, res) => {
  try {
    const { planId } = req.params;
    const { reason } = req.body;
    const userId = req.user.id;
    const userRole = req.user.role;

    const plan = await TherapyPlan.findById(planId);

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

    // Check authorization (therapist or admin)
    const isAuthorized =
      userRole === "admin" || plan.therapist.toString() === userId;

    if (!isAuthorized) {
      return res.status(403).json({
        success: false,
        message: "Not authorized to archive this therapy plan",
      });
    }

    await plan.archivePlan(reason);

    res.status(200).json({
      success: true,
      message: "Therapy plan archived successfully",
      data: plan,
    });
  } catch (error) {
    console.error("Error archiving therapy plan:", error);
    res.status(500).json({
      success: false,
      message: "Failed to archive therapy plan",
      error: error.message,
    });
  }
};

// Get therapist's clients
const getTherapistClients = async (req, res) => {
  try {
    const therapistId = req.user.id;
    const userRole = req.user.role;

    // Verify therapist authorization
    if (userRole !== "doctor") {
      return res.status(403).json({
        success: false,
        message: "Only therapists can access this endpoint",
      });
    }

    // Get clients who have had appointments with this therapist
    const appointments = await Appointment.find({
      doctor: therapistId,
    }).populate("patient", "fullname email mobile");

    // Extract unique clients
    const clientsMap = new Map();
    appointments.forEach((appointment) => {
      if (appointment.patient && appointment.patient._id) {
        clientsMap.set(appointment.patient._id.toString(), appointment.patient);
      }
    });

    const uniqueClients = Array.from(clientsMap.values());

    res.status(200).json({
      success: true,
      data: uniqueClients,
      message:
        uniqueClients.length === 0
          ? "No clients found. Only clients who have booked sessions with you will appear here."
          : undefined,
    });
  } catch (error) {
    console.error("Error fetching therapist clients:", error);
    res.status(500).json({
      success: false,
      message: "Failed to fetch clients",
      error: error.message,
    });
  }
};

// Get therapy plan statistics
const getTherapyPlanStats = async (req, res) => {
  try {
    const userId = req.user.id;
    const userRole = req.user.role;

    let matchQuery = { isArchived: false };

    // If therapist, filter by their plans only
    if (userRole === "doctor") {
      matchQuery.therapist = userId;
    }

    const stats = await TherapyPlan.aggregate([
      { $match: matchQuery },
      {
        $group: {
          _id: null,
          totalPlans: { $sum: 1 },
          drafts: {
            $sum: { $cond: [{ $eq: ["$planStatus", "Draft Created"] }, 1, 0] },
          },
          plansSent: {
            $sum: { $cond: [{ $eq: ["$planStatus", "Plan Sent"] }, 1, 0] },
          },
          plansAcceptedIndividual: {
            $sum: {
              $cond: [
                { $eq: ["$planStatus", "Plan Accepted- Individual"] },
                1,
                0,
              ],
            },
          },
          plansAcceptedPackage: {
            $sum: {
              $cond: [{ $eq: ["$planStatus", "Plan Accepted- Package"] }, 1, 0],
            },
          },
          noResponse: {
            $sum: {
              $cond: [{ $eq: ["$planStatus", "No Response (7+ Days)"] }, 1, 0],
            },
          },
          clientDidntShow: {
            $sum: {
              $cond: [{ $eq: ["$planStatus", "Client Didn't Show"] }, 1, 0],
            },
          },
          avgSessionsCompleted: { $avg: "$sessionsCompleted" },
          totalSessionsCompleted: { $sum: "$sessionsCompleted" },
        },
      },
    ]);

    // Get response rate statistics
    const responseStats = await TherapyPlan.aggregate([
      { $match: { ...matchQuery, planStatus: { $ne: "Draft Created" } } },
      {
        $group: {
          _id: "$clientResponse",
          count: { $sum: 1 },
        },
      },
    ]);

    res.status(200).json({
      success: true,
      data: {
        planStats: stats[0] || {
          totalPlans: 0,
          drafts: 0,
          plansSent: 0,
          plansAcceptedIndividual: 0,
          plansAcceptedPackage: 0,
          noResponse: 0,
          clientDidntShow: 0,
          avgSessionsCompleted: 0,
          totalSessionsCompleted: 0,
        },
        responseStats: responseStats.reduce((acc, item) => {
          acc[item._id] = item.count;
          return acc;
        }, {}),
      },
    });
  } catch (error) {
    console.error("Error fetching therapy plan stats:", error);
    res.status(500).json({
      success: false,
      message: "Failed to fetch statistics",
      error: error.message,
    });
  }
};

module.exports = {
  createTherapyPlan,
  getTherapistPlans,
  getClientPlans,
  getAllPlans,
  getTherapyPlan,
  updateTherapyPlan,
  sendTherapyPlan,
  respondToTherapyPlan,
  archiveTherapyPlan,
  getTherapyPlanStats,
  getTherapistClients,
};
