const Razorpay = require("razorpay");
const crypto = require("crypto");
const Payment = require("../../models/payment");
const Appointment = require("../../models/Appointment");
const User = require("../../models/userModel");
const sendMessage = require("../../utils/sendMessage");
const {
  sendAppointmentConfirmation,
} = require("../../utils/mendingMindTemplates");
const JoinEvent = require("../../models/JoinEvent");

const razorpay = new Razorpay({
  key_id: process.env.RAZORPAY_KEY_ID,
  key_secret: process.env.RAZORPAY_KEY_SECRET,
});

const initiatePayment = async (req, res) => {
  try {
    const { appointmentId, amount } = req.body;
    const patientId = req.user.id;

    // Validate input
    if (!appointmentId || !amount || !Number.isFinite(amount) || amount <= 0) {
      return res.status(400).json({
        message: "Valid appointmentId and amount (in Rupees) are required.",
      });
    }
    // Check appointment
    const appointment = await Appointment.findById(appointmentId);
    if (!appointment || appointment.patient.toString() !== patientId) {
      return res
        .status(404)
        .json({ message: "Appointment not found or unauthorized." });
    }

    if (appointment.status !== "pending") {
      return res
        .status(400)
        .json({ message: "Appointment is not in pending state." });
    }

    if (appointment.bundleId) {
      return res.status(400).json({
        message: "Appointment is part of a bundle, no payment required.",
      });
    }

    const existingPayment = await Payment.findOne({
      appointment: appointmentId,
      status: { $in: ["completed"] },
    });
    if (existingPayment) {
      return res.status(400).json({
        message:
          "A payment is already pending or completed for this appointment.",
      });
    }

    const amountInPaise = Math.round(amount * 100);
    const order = await razorpay.orders.create({
      amount: amountInPaise,
      currency: "INR",
      receipt: `appt_${patientId.slice(0, 12)}_${Date.now()
        .toString()
        .slice(-6)}`,
      notes: {
        patientId,
        appointmentId,
        doctorId: appointment.doctor.toString(),
        date: appointment.date.toISOString().split("T")[0],
        startTime: appointment.timeSlot.startTime,
        endTime: appointment.timeSlot.endTime,
        founder: appointment.founder.toString(),
      },
    });

    // Create payment record
    const payment = await Payment.create({
      appointment: appointment._id,
      patient: patientId,
      orderId: order.id,
      amount: order.amount,
      currency: order.currency,
      status: "pending",
    });

    return res.status(200).json({
      message: "Proceed to payment.",
      order: {
        id: order.id,
        amount: order.amount,
        currency: order.currency,
      },
      appointmentId: appointment._id,
      paymentId: payment._id,
      key: process.env.RAZORPAY_KEY_ID,
    });
  } catch (error) {
    console.error("Error initiating payment:", error);
    return res.status(500).json({
      message: "An error occurred while initiating payment.",
      error:
        process.env.NODE_ENV === "production" ? "Server error" : error.message,
    });
  }
};

const verifyPayment = async (req, res) => {
  try {
    const {
      razorpay_payment_id,
      razorpay_order_id,
      razorpay_signature,
      appointmentId,
      paymentId,
    } = req.body;

    // Validate input
    if (
      !razorpay_payment_id ||
      !razorpay_order_id ||
      !razorpay_signature ||
      !appointmentId ||
      !paymentId
    ) {
      return res.status(400).json({
        message: "Missing payment details, appointment ID, or payment ID.",
      });
    }

    // Verify Razorpay signature
    const generatedSignature = crypto
      .createHmac("sha256", process.env.RAZORPAY_KEY_SECRET)
      .update(`${razorpay_order_id}|${razorpay_payment_id}`)
      .digest("hex");

    if (generatedSignature !== razorpay_signature) {
      await Promise.all([
        Payment.findByIdAndUpdate(paymentId, { status: "failed" }),
        Appointment.findByIdAndUpdate(appointmentId, { status: "cancelled" }),
      ]);
      return res.status(400).json({ message: "Invalid payment signature." });
    }

    // Fetch payment and appointment
    const [payment, appointment] = await Promise.all([
      Payment.findById(paymentId).populate(
        "patient",
        "fullname email countryCode mobile"
      ),
      Appointment.findById(appointmentId).populate("doctor", "fullname email"),
    ]);

    if (
      !payment ||
      !appointment ||
      payment.orderId !== razorpay_order_id ||
      payment.appointment.toString() !== appointmentId
    ) {
      return res
        .status(400)
        .json({ message: "Invalid payment or appointment ID." });
    }

    if (payment.status !== "pending" || appointment.status !== "pending") {
      return res
        .status(400)
        .json({ message: "Payment or appointment is not in pending state." });
    }

    const razorpayPayment = await razorpay.payments.fetch(razorpay_payment_id);
    if (razorpayPayment.status !== "captured") {
      await Promise.all([
        Payment.findByIdAndUpdate(paymentId, { status: "failed" }),
        Appointment.findByIdAndUpdate(appointmentId, { status: "cancelled" }),
      ]);
      return res.status(400).json({ message: "Payment not captured." });
    }

    await Promise.all([
      Payment.findByIdAndUpdate(paymentId, {
        paymentId: razorpay_payment_id,
        razorpaySignature: razorpay_signature,
        status: "completed",
      }),
      Appointment.findByIdAndUpdate(appointmentId, { status: "scheduled" }),
    ]);

    // Fix phone number formatting with proper logic
    const mobile = String(payment.patient.mobile || "").replace(/\D/g, "");
    const countryCode = String(payment.patient.countryCode || "").replace(
      /\D/g,
      ""
    );

    // Format phone number properly for India
    let fullPhone;
    if (mobile.startsWith("91")) {
      fullPhone = `+${mobile}`;
    } else if (countryCode && mobile) {
      fullPhone = `+${countryCode}${mobile}`;
    } else if (mobile.length === 10) {
      // Indian mobile numbers are 10 digits, add +91
      fullPhone = `+91${mobile}`;
    } else {
      fullPhone = `+${mobile}`;
    }

    console.log(
      "📱 Sending payment verification appointment confirmation to:",
      fullPhone
    );
    console.log("🔍 Debug - countryCode:", countryCode, "mobile:", mobile);

    // Send professional appointment confirmation with Google Meet link
    // sendAppointmentConfirmation(
    //   fullPhone,
    //   payment.patient.email,
    //   {
    //     patientName: payment.patient.fullname,
    //     doctorName: appointment.doctor.fullname,
    //     date: appointment.date.toISOString().split("T")[0],
    //     startTime: appointment.timeSlot.startTime,
    //     endTime: appointment.timeSlot.endTime,
    //     meetLink: appointment.meetLink || 'https://meet.google.com/new',
    //     meetingCode: appointment.meetingCode || 'Click link to join',
    //     meetingType: appointment.meetingType || 'google-meet'
    //   },
    //   payment.patient._id
    // ).catch((err) => console.error("Failed to send appointment confirmation:", err));

    return res.status(200).json({
      message: "Payment verified and appointment confirmed.",
      appointment: {
        id: appointment._id,
        date: appointment.date,
        timeSlot: appointment.timeSlot,
        founder: appointment.founder,
        doctor: {
          id: appointment.doctor._id,
          name: appointment.doctor.fullname,
          email: appointment.doctor.email,
        },
      },
    });
  } catch (error) {
    console.error("Error verifying payment:", error);
    return res.status(500).json({
      message: "An error occurred while verifying the payment.",
      error:
        process.env.NODE_ENV === "production" ? "Server error" : error.message,
    });
  }
};

const verifyEventPayment = async (req, res) => {
  try {
    const { razorpay_order_id, razorpay_payment_id, razorpay_signature } =
      req.body;
    console.log("Received Razorpay Payment Data:", {
      razorpay_order_id,
      razorpay_payment_id,
      razorpay_signature,
    });

    if (!razorpay_order_id || !razorpay_payment_id || !razorpay_signature) {
      return res.status(400).json({
        success: false,
        message: "Missing payment verification fields",
      });
    }

    const generatedSignature = crypto
      .createHmac("sha256", process.env.RAZORPAY_KEY_SECRET)
      .update(`${razorpay_order_id}|${razorpay_payment_id}`)
      .digest("hex");

    if (generatedSignature !== razorpay_signature) {
      return res
        .status(400)
        .json({ success: false, message: "Invalid payment signature" });
    }

    // Update Payment record
    const payment = await Payment.findOneAndUpdate(
      { orderId: razorpay_order_id },
      {
        paymentId: razorpay_payment_id,
        razorpaySignature: razorpay_signature,
        status: "completed",
      },
      { new: true }
    );

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

    // Update JoinEvent status
    await JoinEvent.findOneAndUpdate(
      { orderId: razorpay_order_id },
      { paymentStatus: "completed" }
    );

    res.status(200).json({
      success: true,
      message: "Payment verified and recorded successfully",
      data: payment,
    });
  } catch (error) {
    console.error("Payment verification error:", error);
    res
      .status(500)
      .json({ success: false, message: "Server error", error: error.message });
  }
};

module.exports = { initiatePayment, verifyPayment, verifyEventPayment };
