import { createZoomMeeting } from "../middlewares/zoom.js";
import { Booking } from "../models/Booking.js";
import { Teacher } from "../models/Teacher.js";

// ======================= Create Booking =======================
export const createBooking = async (req, res) => {
  try {
    const { studentId, teacherId, date, time, duration } = req.body;
    // console.log(time, date);

    if (!studentId || !teacherId || !date || !time || !duration) {
      return res
        .status(400)
        .json({ success: false, message: "Missing required fields" });
    }

    const startOfDay = new Date(date);
    startOfDay.setHours(0, 0, 0, 0);
    const endOfDay = new Date(date);
    endOfDay.setHours(23, 59, 59, 999);

    // const existing = await Booking.findOne({
    //   teacherId,
    //   date: { $gte: startOfDay, $lte: endOfDay },
    //   time,
    //   status: { $in: ["confirmed", "pending"] },
    // });

    if (existing) {
      return res
        .status(409)
        .json({ success: false, message: "Slot already booked" });
    }

    const teacher = await Teacher.findById(teacherId).populate(
      "userId",
      "email name",
    );
    if (!teacher) {
      return res
        .status(404)
        .json({ success: false, message: "Teacher not found" });
    }

    const zoomMeeting = await createZoomMeeting({
      topic: `Session with ${teacher.userId.name}`,
      startTime: new Date(date + "T" + time).toISOString(),
      duration,
    });

    const booking = await Booking.create({
      studentId,
      teacherId,
      date,
      time,
      duration,
      zoomMeetingId: zoomMeeting.id,
      zoomJoinUrl: zoomMeeting.join_url,
      zoomStartUrl: zoomMeeting.start_url,
      status: "confirmed",
    });

    // console.log("✅ Booking created:", booking._id);
    res.status(201).json({ success: true, data: booking });
  } catch (err) {
    console.error("❌ Booking error:", err);
    res.status(500).json({ success: false, message: "Booking failed" });
  }
};

// ======================= Zoom Webhook — Recording Completed =======================
export const handleZoomWebhook = async (req, res) => {
  try {
    const event = req.body;
    // console.log("📡 Zoom Webhook received:", event.event);

    // ✅ Zoom URL validation challenge (required by Zoom)
    if (event.event === "endpoint.url_validation") {
      const hashForValidate = require("crypto")
        .createHmac("sha256", process.env.ZOOM_WEBHOOK_SECRET_TOKEN)
        .update(event.payload.plainToken)
        .digest("hex");

      return res.status(200).json({
        plainToken: event.payload.plainToken,
        encryptedToken: hashForValidate,
      });
    }

    // ✅ Recording completed
    if (event.event === "recording.completed") {
      const meetingId = event.payload?.object?.id?.toString();
      const recordings = event.payload?.object?.recording_files || [];

      // MP4 video recording dhundo
      const videoFile = recordings.find(
        (f) => f.file_type === "MP4" && f.status === "completed",
      );

      const recordingUrl = videoFile?.play_url || videoFile?.download_url;

      if (!recordingUrl) {
        // console.log("⚠️ No MP4 recording found in webhook");
        return res.status(200).json({ received: true });
      }

      // Booking dhundo by zoomMeetingId
      const booking = await Booking.findOne({ zoomMeetingId: meetingId });

      if (booking) {
        booking.recordingUrl = recordingUrl;
        booking.status = "completed";
        await booking.save();
        // console.log("✅ Recording saved for booking:", booking._id, recordingUrl);
      } else {
        console.log("⚠️ No booking found for Zoom meeting:", meetingId);
      }
    }

    res.status(200).json({ received: true });
  } catch (error) {
    console.error("❌ Webhook error:", error.message);
    res.status(500).json({ error: "Webhook failed" });
  }
};

// ======================= Get Recordings (Student Replays) =======================
export const getRecordings = async (req, res) => {
  try {
    // Sirf completed bookings jo recording URL rakhhti hain
    const bookings = await Booking.find({
      studentId: req.query.studentId || { $exists: true },
      recordingUrl: { $ne: "", $exists: true },
      status: "completed",
    })
      .populate("studentId", "name email")
      .populate({
        path: "teacherId",
        select: "bio skills userId",
        populate: { path: "userId", select: "name email" },
      })
      .sort({ date: -1 });

    // Replays format mein return karo
    const recordings = bookings.map((b) => ({
      id: b._id,
      title: `Lesson with ${b.teacherId?.userId?.name || "Teacher"}`,
      description: `${b.duration} minute ${b.teacherId?.skills || "music"} lesson`,
      date: b.date,
      time: b.time,
      duration: b.duration,
      recordedLessons: [
        {
          id: b._id,
          title: `${b.date?.toISOString().split("T")[0]} — ${b.time}`,
          videoUrl: b.recordingUrl,
        },
      ],
    }));

    res.status(200).json({ success: true, data: recordings });
  } catch (err) {
    console.error("❌ Get recordings error:", err);
    res
      .status(500)
      .json({ success: false, message: "Failed to fetch recordings" });
  }
};

// ======================= Confirm Booking From Stripe =======================
export const confirmBookingFromStripe = async (req, res) => {
  try {
    const { sessionId } = req.body;
    if (!sessionId) {
      return res
        .status(400)
        .json({ success: false, message: "Session ID required" });
    }

    const booking = await Booking.findOneAndUpdate(
      { stripeSessionId: sessionId },
      { status: "confirmed" },
      { new: true },
    );

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

    res.status(200).json({ success: true, data: booking });
  } catch (err) {
    console.error("❌ Confirm booking error:", err);
    res
      .status(500)
      .json({ success: false, message: "Failed to confirm booking" });
  }
};

// ======================= Get Bookings =======================
export const getBookings = async (req, res) => {
  try {
    const { studentId, teacherId } = req.query;
    let filter = {};
    if (studentId) filter.studentId = studentId;
    if (teacherId) filter.teacherId = teacherId;

    const bookings = await Booking.find(filter)
      .populate("studentId", "name email phone")
      .populate({
        path: "teacherId",
        select: "bio skills hourlyRate userId",
        populate: { path: "userId", select: "name email" },
      });

    res.status(200).json({ success: true, data: bookings });
  } catch (err) {
    console.error("❌ Get bookings error:", err);
    res
      .status(500)
      .json({ success: false, message: "Failed to fetch bookings" });
  }
};

// ======================= Get Single Booking =======================
export const getBookingById = async (req, res) => {
  try {
    const { id } = req.params;
    const booking = await Booking.findById(id)
      .populate("studentId", "name email phone")
      .populate("teacherId", "bio skills hourlyRate");

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

    res.status(200).json({ success: true, data: booking });
  } catch (err) {
    console.error("❌ Get booking error:", err);
    res
      .status(500)
      .json({ success: false, message: "Failed to fetch booking" });
  }
};

// ======================= Get Booked Slots =======================
export const getBookedSlots = async (req, res) => {
  try {
    const { teacherId, date } = req.query;

    if (!teacherId || !date) {
      return res
        .status(400)
        .json({ success: false, message: "teacherId and date required" });
    }

    const [year, month, day] = date.split("-").map(Number);
    const startOfDay = new Date(Date.UTC(year, month - 1, day, 0, 0, 0, 0));
    const endOfDay = new Date(Date.UTC(year, month - 1, day, 23, 59, 59, 999));

    const bookings = await Booking.find({
      teacherId,
      date: { $gte: startOfDay, $lte: endOfDay },
      status: { $in: ["confirmed", "pending"] },
    }).select("time duration");

    console.log("✅ Booked slots:", bookings.length, "for date:", date);
    const bookedTimes = bookings.map((b) => b.time.trim());
    res.status(200).json({ success: true, bookedTimes });
  } catch (err) {
    console.error("❌ Booked slots error:", err);
    res
      .status(500)
      .json({ success: false, message: "Failed to fetch booked slots" });
  }
};

// ======================= Update Booking =======================
export const updateBooking = async (req, res) => {
  try {
    const { id } = req.params;
    const updateData = req.body;

    if (updateData.date && updateData.time && updateData.teacherId) {
      const startOfDay = new Date(updateData.date);
      startOfDay.setHours(0, 0, 0, 0);
      const endOfDay = new Date(updateData.date);
      endOfDay.setHours(23, 59, 59, 999);

      const conflict = await Booking.findOne({
        _id: { $ne: id },
        teacherId: updateData.teacherId,
        date: { $gte: startOfDay, $lte: endOfDay },
        time: updateData.time,
      });

      if (conflict) {
        return res
          .status(409)
          .json({ success: false, message: "Slot already booked" });
      }
    }

    const booking = await Booking.findByIdAndUpdate(id, updateData, {
      new: true,
    });
    if (!booking) {
      return res
        .status(404)
        .json({ success: false, message: "Booking not found" });
    }

    res.status(200).json({ success: true, data: booking });
  } catch (err) {
    console.error("❌ Update booking error:", err);
    res
      .status(500)
      .json({ success: false, message: "Failed to update booking" });
  }
};

// ======================= Delete Booking =======================
export const deleteBooking = async (req, res) => {
  try {
    const { id } = req.params;
    const booking = await Booking.findByIdAndDelete(id);

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

    res
      .status(200)
      .json({ success: true, message: "Booking deleted successfully" });
  } catch (err) {
    console.error("❌ Delete booking error:", err);
    res
      .status(500)
      .json({ success: false, message: "Failed to delete booking" });
  }
};
