import { Booking } from "../models/Booking.js";
import { Teacher } from "../models/Teacher.js";
import Subscription from "../models/Subscription.js";

export const getAdminStats = async (req, res) => {
  try {
    const now = new Date();

    // ── Subscriptions ──────────────────────────────────────────
    const allSubs = await Subscription.find({ paymentStatus: "paid" })
      .populate("user", "name email")
      .lean();

    const activeSubs = allSubs.filter((s) => new Date(s.expiresAt) > now);

    const totalSubscriptionEarnings = allSubs.reduce(
      (sum, s) => sum + (s.price || 0), 0
    );

    const subBreakdown = allSubs.reduce((acc, s) => {
      const plan = s.subscription?.name || "unknown";
      if (!acc[plan]) acc[plan] = { count: 0, revenue: 0 };
      acc[plan].count += 1;
      acc[plan].revenue += s.price || 0;
      return acc;
    }, {});

    // userId -> latest subscription info
    const subByUser = {};
    for (const s of allSubs) {
      const uid = s.user?._id?.toString();
      if (!uid) continue;
      if (
        !subByUser[uid] ||
        new Date(s.purchasedAt) > new Date(subByUser[uid].purchasedAt)
      ) {
        subByUser[uid] = {
          plan: s.subscription?.name || "unknown",
          price: s.price,
          purchasedAt: s.purchasedAt,
          expiresAt: s.expiresAt,
          isActive: new Date(s.expiresAt) > now,
        };
      }
    }

    // ── Bookings ───────────────────────────────────────────────
    const LESSON_PRICE = { 60: 120, 30: 70 };

    const allBookings = await Booking.find({ status: "confirmed" })
      .populate({
        path: "teacherId",
        select: "userId skills",
        populate: { path: "userId", select: "name email" },
      })
      .populate("studentId", "name email")
      .lean();

    const totalLessonEarnings = allBookings.reduce(
      (sum, b) => sum + (LESSON_PRICE[b.duration] || 0), 0
    );

    // ── Student list: anyone with a booking OR a subscription ──
    const studentMap = {};

    for (const b of allBookings) {
      const sid = b.studentId?._id?.toString();
      if (!sid) continue;
      if (!studentMap[sid]) {
        studentMap[sid] = {
          studentId: sid,
          name: b.studentId?.name || "Unknown",
          email: b.studentId?.email || "",
          bookingCount: 0,
          totalSpent: 0,
          subscription: subByUser[sid] || null,
        };
      }
      studentMap[sid].bookingCount += 1;
      studentMap[sid].totalSpent += LESSON_PRICE[b.duration] || 0;
    }

    // Also include subscription-only users (no bookings yet)
    for (const s of allSubs) {
      const uid = s.user?._id?.toString();
      if (!uid || studentMap[uid]) continue;
      studentMap[uid] = {
        studentId: uid,
        name: s.user?.name || "Unknown",
        email: s.user?.email || "",
        bookingCount: 0,
        totalSpent: 0,
        subscription: subByUser[uid],
      };
    }

    const studentList = Object.values(studentMap).sort(
      (a, b) => b.totalSpent - a.totalSpent
    );

    // ── Per-teacher stats ──────────────────────────────────────
    const teacherMap = {};
    for (const b of allBookings) {
      const tid = b.teacherId?._id?.toString();
      if (!tid) continue;
      if (!teacherMap[tid]) {
        teacherMap[tid] = {
          teacherId: tid,
          name: b.teacherId?.userId?.name || "Unknown",
          skills: b.teacherId?.skills || "",
          lessons: 0,
          earnings: 0,
          upcoming: [],
        };
      }
      teacherMap[tid].lessons += 1;
      teacherMap[tid].earnings += LESSON_PRICE[b.duration] || 0;
      teacherMap[tid].upcoming.push({
        studentName: b.studentId?.name || "Unknown",
        date: b.date,
        time: b.time,
        duration: b.duration,
        zoomJoinUrl: b.zoomJoinUrl || null,
      });
    }

    const teacherStats = Object.values(teacherMap).sort(
      (a, b) => b.earnings - a.earnings
    );

    // ── Upcoming sessions (next 7 days) ────────────────────────
    const week = new Date();
    week.setDate(week.getDate() + 7);

    const upcomingSessions = allBookings
      .filter((b) => {
        const d = new Date(b.date);
        return d >= now && d <= week;
      })
      .map((b) => ({
        studentName: b.studentId?.name || "Unknown",
        teacherName: b.teacherId?.userId?.name || "Unknown",
        date: b.date,
        time: b.time,
        duration: b.duration,
        zoomJoinUrl: b.zoomJoinUrl || null,
      }))
      .sort((a, b) => new Date(a.date) - new Date(b.date));

    const totalTeachers = await Teacher.countDocuments();

    res.status(200).json({
      success: true,
      data: {
        overview: {
          totalUsers: studentList.length,
          totalTeachers,
          totalBookings: allBookings.length,
          totalSubscriptions: allSubs.length,
          activeSubscriptions: activeSubs.length,
          totalEarnings: totalSubscriptionEarnings + totalLessonEarnings,
          subscriptionEarnings: totalSubscriptionEarnings,
          lessonEarnings: totalLessonEarnings,
        },
        subscriptions: {
          breakdown: subBreakdown,
          list: studentList.map((s) => ({
            userName:     s.name,
            userEmail:    s.email,
            plan:         s.subscription?.plan || null,         // null = no plan
            price:        s.subscription?.price || null,
            totalSpent:   s.totalSpent,
            bookingCount: s.bookingCount,
            purchasedAt:  s.subscription?.purchasedAt || null,
            expiresAt:    s.subscription?.expiresAt || null,
            isActive:     s.subscription?.isActive || false,
          })),
        },
        teacherStats,
        upcomingSessions,
      },
    });
  } catch (err) {
    console.error("❌ Admin stats error:", err);
    res.status(500).json({ success: false, message: "Failed to fetch stats" });
  }
};