import type { Express } from "express";
import express from "express";
import { createServer, type Server } from "http";
import { storage } from "./storage";
import { setupAuth, isAuthenticated, getSetting, upsertSetting, getAllSettings } from "./auth";
import { userProfiles } from "@shared/schema";
import { db } from "./db";
import { eq } from "drizzle-orm";
import multer from "multer";
import path from "path";
import fs from "fs";

const uploadsDir = path.resolve(process.cwd(), "uploads");
if (!fs.existsSync(uploadsDir)) fs.mkdirSync(uploadsDir, { recursive: true });

const uploadStorage = multer.diskStorage({
  destination: (_req, _file, cb) => cb(null, uploadsDir),
  filename: (_req, file, cb) => {
    const ext = path.extname(file.originalname);
    const name = `${Date.now()}-${Math.random().toString(36).substring(2, 8)}${ext}`;
    cb(null, name);
  },
});
const upload = multer({
  storage: uploadStorage,
  limits: { fileSize: 5 * 1024 * 1024 },
  fileFilter: (_req, file, cb) => {
    const allowed = /\.(jpg|jpeg|png|gif|svg|ico|webp)$/i;
    if (allowed.test(path.extname(file.originalname))) {
      cb(null, true);
    } else {
      cb(new Error("Only image files are allowed"));
    }
  },
});

const libraryUpload = multer({
  storage: uploadStorage,
  limits: { fileSize: 50 * 1024 * 1024 },
  fileFilter: (_req, file, cb) => {
    if (file.fieldname === "thumbnail") {
      const imgAllowed = /\.(jpg|jpeg|png|gif|svg|webp)$/i;
      if (imgAllowed.test(path.extname(file.originalname))) {
        cb(null, true);
      } else {
        cb(new Error("Thumbnail must be an image file"));
      }
    } else if (file.fieldname === "file") {
      const docAllowed = /\.(pdf|doc|docx|ppt|pptx|xls|xlsx)$/i;
      if (docAllowed.test(path.extname(file.originalname))) {
        cb(null, true);
      } else {
        cb(new Error("Only document files (PDF, DOC, PPT, XLS) are allowed"));
      }
    } else {
      cb(new Error("Unexpected field"));
    }
  },
});

export async function registerRoutes(
  httpServer: Server,
  app: Express
): Promise<Server> {
  setupAuth(app);

  app.get("/favicon.png", async (_req, res) => {
    try {
      const settings = await getAllSettings();
      const faviconUrl = settings.brand_favicon_url;
      if (faviconUrl && faviconUrl.startsWith("/uploads/")) {
        const faviconPath = path.resolve(process.cwd(), faviconUrl.slice(1));
        if (fs.existsSync(faviconPath)) {
          res.setHeader("Cache-Control", "public, max-age=3600");
          return res.sendFile(faviconPath);
        }
      }
      const defaultFavicon = path.resolve(process.cwd(), "client/public/favicon.png");
      if (fs.existsSync(defaultFavicon)) {
        return res.sendFile(defaultFavicon);
      }
      res.status(404).end();
    } catch {
      res.status(404).end();
    }
  });

  app.get("/favicon.ico", async (_req, res) => {
    try {
      const settings = await getAllSettings();
      const faviconUrl = settings.brand_favicon_url;
      if (faviconUrl && faviconUrl.startsWith("/uploads/")) {
        const faviconPath = path.resolve(process.cwd(), faviconUrl.slice(1));
        if (fs.existsSync(faviconPath)) {
          res.setHeader("Cache-Control", "public, max-age=3600");
          return res.sendFile(faviconPath);
        }
      }
      const defaultFavicon = path.resolve(process.cwd(), "client/public/favicon.png");
      if (fs.existsSync(defaultFavicon)) {
        return res.sendFile(defaultFavicon);
      }
      res.status(404).end();
    } catch {
      res.status(404).end();
    }
  });

  app.use("/uploads", express.static(uploadsDir));

  app.get("/api/profile", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      let profile = await storage.getProfile(userId);
      if (!profile) {
        const user = req.user;
        const isOAuth = user.authProvider && user.authProvider !== "email";

        if (isOAuth && !user.userType && !user.dateOfBirth) {
          return res.json({ needsOnboarding: true });
        }

        let role = "student";
        if (user.userType === "teacher") {
          role = "teacher";
        } else if (user.userType === "parent") {
          role = "parent";
        } else if (user.dateOfBirth) {
          const ageThresholdSetting = await getSetting("age_threshold_for_role");
          const ageThreshold = parseInt(ageThresholdSetting || "20");
          const birthDate = new Date(user.dateOfBirth);
          const ageDiff = Date.now() - birthDate.getTime();
          const ageDate = new Date(ageDiff);
          const age = Math.abs(ageDate.getUTCFullYear() - 1970);
          if (age <= ageThreshold) {
            const defaultRoleSetting = await getSetting("default_registration_role");
            role = defaultRoleSetting || "student";
          }
        } else {
          const defaultRoleSetting = await getSetting("default_registration_role");
          role = defaultRoleSetting || "student";
        }

        profile = await storage.upsertProfile({ userId, role: role as "student" | "teacher" | "parent" | "admin" });
      }
      res.json(profile);
    } catch (error) {
      console.error("Error fetching profile:", error);
      res.status(500).json({ message: "Failed to fetch profile" });
    }
  });

  app.post("/api/auth/complete-onboarding", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { dateOfBirth, userType, parentRelation } = req.body;

      if (!dateOfBirth) {
        return res.status(400).json({ message: "تاريخ الميلاد مطلوب" });
      }

      const parsedDate = new Date(dateOfBirth);
      if (isNaN(parsedDate.getTime())) {
        return res.status(400).json({ message: "تاريخ الميلاد غير صالح" });
      }

      if (userType && !["teacher", "parent"].includes(userType)) {
        return res.status(400).json({ message: "نوع الحساب غير صالح" });
      }

      if (userType === "parent" && parentRelation && !["father", "mother", "other"].includes(parentRelation)) {
        return res.status(400).json({ message: "صلة القرابة غير صالحة" });
      }

      const { users } = await import("@shared/models/auth");
      await db.update(users).set({
        dateOfBirth: new Date(dateOfBirth),
        userType: userType || null,
        parentRelation: parentRelation || null,
        updatedAt: new Date(),
      }).where(eq(users.id, userId));

      const birthDate = new Date(dateOfBirth);
      const ageDiff = Date.now() - birthDate.getTime();
      const ageDate = new Date(ageDiff);
      const age = Math.abs(ageDate.getUTCFullYear() - 1970);

      const ageThresholdSetting = await getSetting("age_threshold_for_role");
      const ageThreshold = parseInt(ageThresholdSetting || "20");

      let role = "student";
      const isAdult = age > ageThreshold;
      if (isAdult && userType === "teacher") {
        role = "teacher";
      } else if (isAdult && userType === "parent") {
        role = "parent";
      } else {
        const defaultRoleSetting = await getSetting("default_registration_role");
        role = defaultRoleSetting || "student";
      }

      const profile = await storage.upsertProfile({
        userId,
        role: role as "student" | "teacher" | "parent" | "admin",
      });

      res.json(profile);
    } catch (error) {
      console.error("Onboarding error:", error);
      res.status(500).json({ message: "فشل في إكمال البيانات" });
    }
  });

  app.get("/api/curricula", async (_req, res) => {
    try {
      const result = await storage.getCurricula();
      res.json(result);
    } catch (error) {
      console.error("Error fetching curricula:", error);
      res.status(500).json({ message: "Failed to fetch curricula" });
    }
  });

  app.get("/api/my-curricula", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile) {
        return res.json([]);
      }
      const assignedIds = profile.assignedCurricula || [];
      if (assignedIds.length === 0) {
        return res.json([]);
      }
      const allCurricula = await storage.getCurricula();
      const filtered = allCurricula.filter(c => assignedIds.includes(c.id));
      res.json(filtered);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch assigned curricula" });
    }
  });

  app.get("/api/curricula/:id", async (req, res) => {
    try {
      const curriculum = await storage.getCurriculum(req.params.id);
      if (!curriculum) return res.status(404).json({ message: "Not found" });
      res.json(curriculum);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch curriculum" });
    }
  });

  app.get("/api/curricula/:id/grades", async (req, res) => {
    try {
      const result = await storage.getGradesByCurriculum(req.params.id);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch grades" });
    }
  });

  app.get("/api/curricula/:id/subjects", async (req, res) => {
    try {
      const grades = await storage.getGradesByCurriculum(req.params.id);
      const allSubjects: any[] = [];
      for (const grade of grades) {
        const subjects = await storage.getSubjectsByGrade(grade.id);
        allSubjects.push(...subjects);
      }
      res.json(allSubjects);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch subjects for curriculum" });
    }
  });

  app.get("/api/subjects", async (_req, res) => {
    try {
      const allSubjects = await storage.getAllSubjects();
      res.json(allSubjects);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch subjects" });
    }
  });

  app.get("/api/subjects/:id", async (req, res) => {
    try {
      const subject = await storage.getSubject(req.params.id);
      if (!subject) return res.status(404).json({ message: "Not found" });
      res.json(subject);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch subject" });
    }
  });

  app.get("/api/subjects/:id/lessons", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const grouped = await storage.getSubjectLessonsGrouped(req.params.id);

      const enrichLesson = async (lesson: any) => {
        const progress = await storage.getProgress(userId, lesson.id);
        return {
          ...lesson,
          progress: progress ? {
            isCompleted: progress.isCompleted,
            progressPercent: progress.progressPercent,
          } : undefined,
        };
      };

      const sections = await Promise.all(
        grouped.sections.map(async (section) => ({
          ...section,
          lessons: await Promise.all(section.lessons.map(enrichLesson)),
        }))
      );

      const ungrouped = await Promise.all(grouped.ungrouped.map(enrichLesson));

      res.json({ sections, ungrouped });
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch lessons" });
    }
  });

  app.get("/api/lessons/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const lesson = await storage.getLesson(req.params.id);
      if (!lesson) return res.status(404).json({ message: "Not found" });

      const subject = await storage.getSubject(lesson.subjectId);
      const progress = await storage.getProgress(userId, lesson.id);
      const bookmark = await storage.getBookmark(userId, lesson.id);
      const adjacent = await storage.getAdjacentLessons(lesson.subjectId, lesson.orderIndex);

      if (!progress) {
        await storage.upsertProgress({
          userId,
          lessonId: lesson.id,
          progressPercent: 10,
          timeSpentMinutes: 0,
        });
      }

      res.json({
        ...lesson,
        subject: subject ? { id: subject.id, nameAr: subject.nameAr, nameEn: subject.nameEn, color: subject.color } : undefined,
        progress: progress ? {
          isCompleted: progress.isCompleted,
          progressPercent: progress.progressPercent,
          timeSpentMinutes: progress.timeSpentMinutes,
          videoPosition: progress.videoPosition,
        } : { isCompleted: false, progressPercent: 10, timeSpentMinutes: 0, videoPosition: 0 },
        isBookmarked: !!bookmark,
        prevLesson: adjacent.prev ? { id: adjacent.prev.id, nameAr: adjacent.prev.nameAr } : null,
        nextLesson: adjacent.next ? { id: adjacent.next.id, nameAr: adjacent.next.nameAr } : null,
      });
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch lesson" });
    }
  });

  app.get("/api/lessons/:id/assessments", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.getAssessmentsByLesson(req.params.id);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch assessments" });
    }
  });

  app.get("/api/lessons/:id/resources", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.getResourcesByLesson(req.params.id);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch resources" });
    }
  });

  app.get("/api/lessons/:id/notes", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getNotesByLesson(userId, req.params.id);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch notes" });
    }
  });

  app.post("/api/lessons/:id/notes", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { content, videoTimestamp } = req.body;
      if (!content || !content.trim()) return res.status(400).json({ message: "Content is required" });
      const note = await storage.createNote({
        userId,
        lessonId: req.params.id,
        content: content.trim(),
        videoTimestamp: videoTimestamp || null,
      });
      res.json(note);
    } catch (error) {
      res.status(500).json({ message: "Failed to create note" });
    }
  });

  app.patch("/api/notes/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { content } = req.body;
      if (!content || !content.trim()) return res.status(400).json({ message: "Content is required" });
      const note = await storage.updateNote(req.params.id, userId, content.trim());
      if (!note) return res.status(404).json({ message: "Not found" });
      res.json(note);
    } catch (error) {
      res.status(500).json({ message: "Failed to update note" });
    }
  });

  app.delete("/api/notes/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      await storage.deleteNote(req.params.id, userId);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete note" });
    }
  });

  app.post("/api/lessons/:id/bookmark", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.toggleBookmark(userId, req.params.id);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to toggle bookmark" });
    }
  });

  app.get("/api/bookmarks", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getUserBookmarks(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch bookmarks" });
    }
  });

  app.get("/api/lessons/:id/qna", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.getQnaByLesson(req.params.id);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch Q&A" });
    }
  });

  app.post("/api/lessons/:id/qna", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { content, parentId } = req.body;
      if (!content || !content.trim()) return res.status(400).json({ message: "Content is required" });

      const profile = await storage.getProfile(userId);
      const isInstructor = profile?.role === "teacher" || profile?.role === "admin";

      const qna = await storage.createQna({
        lessonId: req.params.id,
        userId,
        content: content.trim(),
        parentId: parentId || null,
        isInstructorAnswer: isInstructor && !!parentId,
      });
      res.json(qna);
    } catch (error) {
      res.status(500).json({ message: "Failed to create Q&A" });
    }
  });

  app.get("/api/notifications", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getNotifications(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch notifications" });
    }
  });

  app.get("/api/notifications/unread-count", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const count = await storage.getUnreadNotificationCount(userId);
      res.json({ count });
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch count" });
    }
  });

  app.post("/api/notifications/:id/read", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      await storage.markNotificationRead(req.params.id, userId);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to mark read" });
    }
  });

  app.post("/api/notifications/read-all", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      await storage.markAllNotificationsRead(userId);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to mark all read" });
    }
  });

  app.post("/api/lessons/:id/complete", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const progress = await storage.upsertProgress({
        userId,
        lessonId: req.params.id,
        isCompleted: true,
        progressPercent: 100,
        timeSpentMinutes: 15,
      });
      res.json(progress);
    } catch (error) {
      res.status(500).json({ message: "Failed to complete lesson" });
    }
  });

  app.post("/api/lessons/:id/progress", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { progressPercent, videoPosition, timeSpentMinutes } = req.body;
      const progress = await storage.upsertProgress({
        userId,
        lessonId: req.params.id,
        progressPercent: progressPercent || undefined,
        videoPosition: videoPosition || undefined,
        timeSpentMinutes: timeSpentMinutes || undefined,
      });
      res.json(progress);
    } catch (error) {
      res.status(500).json({ message: "Failed to update progress" });
    }
  });

  app.post("/api/assessments/:id/submit", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const assessment = await storage.getAssessment(req.params.id);
      if (!assessment) return res.status(404).json({ message: "Not found" });

      const { answers } = req.body;
      const questions = assessment.questions as any[];
      let correct = 0;

      questions.forEach((q: any, i: number) => {
        if (answers[`q${i}`] === q.correctAnswer) correct++;
      });

      const score = Math.round((correct / questions.length) * 100);

      const existingResults = await storage.getAssessmentResults(userId);
      const attemptNumber = existingResults.filter((r) => r.assessmentId === assessment.id).length + 1;

      const result = await storage.createAssessmentResult({
        userId,
        assessmentId: assessment.id,
        score,
        answers,
        attemptNumber,
      });

      res.json({ score, correct, total: questions.length, result });
    } catch (error) {
      res.status(500).json({ message: "Failed to submit assessment" });
    }
  });

  app.get("/api/dashboard/stats", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const stats = await storage.getDashboardStats(userId);
      res.json(stats);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch stats" });
    }
  });

  app.get("/api/dashboard/today-summary", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const summary = await storage.getTodaySummary(userId);
      res.json(summary);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch today summary" });
    }
  });

  app.get("/api/dashboard/recent-lessons", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getRecentLessons(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch recent lessons" });
    }
  });

  app.get("/api/my-lessons", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getUserLessonsWithProgress(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch lessons" });
    }
  });

  app.get("/api/progress/by-subject", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getProgressBySubject(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch progress" });
    }
  });

  app.get("/api/progress/weekly-activity", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getWeeklyActivity(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch weekly activity" });
    }
  });

  app.get("/api/progress/streak", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getStudyStreak(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch study streak" });
    }
  });

  app.get("/api/subscription", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const sub = await storage.getSubscription(userId);
      if (!sub) {
        const newSub = await storage.createSubscription({
          userId,
          plan: "monthly",
          status: "trial",
        });
        return res.json(newSub);
      }
      res.json(sub);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch subscription" });
    }
  });

  app.get("/api/reports", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getReports(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch reports" });
    }
  });

  app.get("/api/forums", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.getForums();
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch forums" });
    }
  });

  app.get("/api/forums/:id/posts", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.getForumPosts(req.params.id);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch posts" });
    }
  });

  app.post("/api/forums/:id/posts", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { titleAr, titleEn, contentAr, contentEn } = req.body;
      if (!titleAr || !contentAr) return res.status(400).json({ message: "Title and content are required" });
      const post = await storage.createPost({
        forumId: req.params.id,
        userId,
        titleAr: titleAr.trim(),
        titleEn: titleEn?.trim() || null,
        contentAr: contentAr.trim(),
        contentEn: contentEn?.trim() || null,
      });
      res.json(post);
    } catch (error) {
      res.status(500).json({ message: "Failed to create post" });
    }
  });

  app.get("/api/posts/:id/replies", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.getPostReplies(req.params.id);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch replies" });
    }
  });

  app.post("/api/posts/:id/replies", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { content } = req.body;
      if (!content || !content.trim()) return res.status(400).json({ message: "Content is required" });
      const profile = await storage.getProfile(userId);
      const isInstructor = profile?.role === "teacher" || profile?.role === "admin";
      const reply = await storage.createReply({
        postId: req.params.id,
        userId,
        content: content.trim(),
        isInstructorReply: isInstructor,
      });
      res.json(reply);
    } catch (error) {
      res.status(500).json({ message: "Failed to create reply" });
    }
  });

  app.get("/api/badges", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.getBadgeDefinitions();
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch badges" });
    }
  });

  app.get("/api/my-badges", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const result = await storage.getUserBadges(userId);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch user badges" });
    }
  });

  app.get("/api/leaderboard", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.getLeaderboard(20);
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch leaderboard" });
    }
  });

  app.get("/api/my-points", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const total = await storage.getUserPoints(userId);
      res.json({ total });
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch points" });
    }
  });

  app.get("/api/library", isAuthenticated, async (req: any, res) => {
    try {
      const { category, subjectId, curriculumId } = req.query;
      const result = await storage.getLibraryItems(
        category as string | undefined,
        subjectId as string | undefined,
        curriculumId as string | undefined
      );
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch library items" });
    }
  });

  app.get("/api/library/progress/batch", isAuthenticated, async (req: any, res) => {
    try {
      const itemIds = (req.query.ids as string || "").split(",").filter(Boolean);
      const progress = await storage.getUserReadingProgressBatch(req.user.id, itemIds);
      res.json(progress);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch reading progress" });
    }
  });

  app.get("/api/library/:id", isAuthenticated, async (req: any, res) => {
    try {
      const item = await storage.getLibraryItem(req.params.id);
      if (!item) return res.status(404).json({ message: "Not found" });
      res.json(item);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch library item" });
    }
  });

  app.post("/api/admin/library", isAuthenticated, libraryUpload.fields([
    { name: "file", maxCount: 1 },
    { name: "thumbnail", maxCount: 1 },
  ]), async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || !["admin", "supervisor"].includes(profile.role)) {
        return res.status(403).json({ message: "Unauthorized" });
      }
      const files = req.files as { [fieldname: string]: Express.Multer.File[] };
      const fileUrl = files?.file?.[0] ? `/uploads/${files.file[0].filename}` : null;
      const thumbnailUrl = files?.thumbnail?.[0] ? `/uploads/${files.thumbnail[0].filename}` : null;
      const { titleAr, titleEn, descriptionAr, descriptionEn, category, curriculumId, subjectId, gradeId, authorAr, authorEn } = req.body;
      const item = await storage.createLibraryItem({
        titleAr, titleEn: titleEn || null, descriptionAr: descriptionAr || null,
        descriptionEn: descriptionEn || null, category,
        fileUrl, thumbnailUrl,
        curriculumId: curriculumId || null, subjectId: subjectId || null,
        gradeId: gradeId || null, authorAr: authorAr || null, authorEn: authorEn || null,
      });
      res.json(item);
    } catch (error) {
      res.status(500).json({ message: "Failed to create library item" });
    }
  });

  app.patch("/api/admin/library/:id", isAuthenticated, libraryUpload.fields([
    { name: "file", maxCount: 1 },
    { name: "thumbnail", maxCount: 1 },
  ]), async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || !["admin", "supervisor"].includes(profile.role)) {
        return res.status(403).json({ message: "Unauthorized" });
      }
      const files = req.files as { [fieldname: string]: Express.Multer.File[] };
      const updates: any = {};
      const { titleAr, titleEn, descriptionAr, descriptionEn, category, curriculumId, subjectId, gradeId, authorAr, authorEn } = req.body;
      if (titleAr !== undefined) updates.titleAr = titleAr;
      if (titleEn !== undefined) updates.titleEn = titleEn || null;
      if (descriptionAr !== undefined) updates.descriptionAr = descriptionAr || null;
      if (descriptionEn !== undefined) updates.descriptionEn = descriptionEn || null;
      if (category !== undefined) updates.category = category;
      if (curriculumId !== undefined) updates.curriculumId = curriculumId || null;
      if (subjectId !== undefined) updates.subjectId = subjectId || null;
      if (gradeId !== undefined) updates.gradeId = gradeId || null;
      if (authorAr !== undefined) updates.authorAr = authorAr || null;
      if (authorEn !== undefined) updates.authorEn = authorEn || null;
      if (files?.file?.[0]) updates.fileUrl = `/uploads/${files.file[0].filename}`;
      if (files?.thumbnail?.[0]) updates.thumbnailUrl = `/uploads/${files.thumbnail[0].filename}`;
      const item = await storage.updateLibraryItem(req.params.id, updates);
      res.json(item);
    } catch (error) {
      res.status(500).json({ message: "Failed to update library item" });
    }
  });

  app.delete("/api/admin/library/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || !["admin", "supervisor"].includes(profile.role)) {
        return res.status(403).json({ message: "Unauthorized" });
      }
      await storage.deleteLibraryItem(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete library item" });
    }
  });

  app.get("/api/library/:id/progress", isAuthenticated, async (req: any, res) => {
    try {
      const progress = await storage.getReadingProgress(req.user.id, req.params.id);
      res.json(progress || { currentPage: 1, totalPages: 0 });
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch reading progress" });
    }
  });

  app.post("/api/library/:id/progress", isAuthenticated, async (req: any, res) => {
    try {
      const page = parseInt(req.body.currentPage);
      const total = parseInt(req.body.totalPages);
      if (isNaN(page) || isNaN(total) || page < 1 || total < 1 || page > total) {
        return res.status(400).json({ message: "Invalid page values" });
      }
      const progress = await storage.upsertReadingProgress(
        req.user.id, req.params.id, page, total
      );
      res.json(progress);
    } catch (error) {
      res.status(500).json({ message: "Failed to update reading progress" });
    }
  });

  // Admin - User Management
  app.get("/api/admin/users", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const users = await storage.getAllUsers();
      res.json(users);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch users" });
    }
  });

  app.post("/api/admin/users", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const { firstName, lastName, email, password, role, dateOfBirth, parentRelation, assignedCurricula, supervisedSubjects } = req.body;
      if (!firstName || !lastName || !email || !password || !role) {
        return res.status(400).json({ message: "All required fields must be provided" });
      }
      if (!["student", "teacher", "parent", "admin", "supervisor"].includes(role)) {
        return res.status(400).json({ message: "Invalid role" });
      }
      if (password.length < 6) {
        return res.status(400).json({ message: "Password must be at least 6 characters" });
      }
      if (role === "parent" && parentRelation && !["father", "mother", "other"].includes(parentRelation)) {
        return res.status(400).json({ message: "Invalid parent relation" });
      }
      const { eq } = await import("drizzle-orm");
      const { users } = await import("@shared/models/auth");
      const { db } = await import("./db");
      const existingUser = await db.select().from(users).where(eq(users.email, email)).then(r => r[0]);
      if (existingUser) {
        return res.status(400).json({ message: "Email already exists" });
      }
      const bcrypt = await import("bcryptjs");
      const hashedPassword = await bcrypt.default.hash(password, 10);
      const [newUser] = await db.insert(users).values({
        email,
        password: hashedPassword,
        firstName,
        lastName,
        authProvider: "email",
        emailVerified: true,
        dateOfBirth: dateOfBirth ? new Date(dateOfBirth) : null,
        userType: role,
        parentRelation: role === "parent" ? (parentRelation || null) : null,
      }).returning();

      const profileData: any = {
        userId: newUser.id,
        role,
        preferredLanguage: "ar",
      };
      if (Array.isArray(assignedCurricula) && assignedCurricula.length > 0 && (role === "student" || role === "teacher")) {
        profileData.assignedCurricula = assignedCurricula;
      }
      if (Array.isArray(supervisedSubjects) && supervisedSubjects.length > 0 && role === "supervisor") {
        profileData.supervisedSubjects = supervisedSubjects;
      }
      await storage.upsertProfile(profileData);

      res.json(newUser);
    } catch (error: any) {
      console.error("Create user error:", error);
      res.status(500).json({ message: error.message || "Failed to create user" });
    }
  });

  app.patch("/api/admin/users/:id/role", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const { role } = req.body;
      if (!role || !["student", "teacher", "parent", "admin", "supervisor"].includes(role)) {
        return res.status(400).json({ message: "Invalid role" });
      }
      const updated = await storage.updateUserRole(req.params.id, role);
      res.json(updated);
    } catch (error) {
      res.status(500).json({ message: "Failed to update user role" });
    }
  });

  app.patch("/api/admin/users/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const { firstName, lastName, email, phone, bio, preferredLanguage, assignedCurricula, supervisedSubjects, profileImageUrl, role } = req.body;
      const userUpdate: any = {};
      if (firstName !== undefined) userUpdate.firstName = firstName;
      if (lastName !== undefined) userUpdate.lastName = lastName;
      if (email !== undefined) userUpdate.email = email;
      if (profileImageUrl !== undefined) userUpdate.profileImageUrl = profileImageUrl;
      const updated = await storage.updateUser(req.params.id, userUpdate);
      if (role && ["student", "teacher", "parent", "admin", "supervisor"].includes(role)) {
        await storage.updateUserRole(req.params.id, role);
        if (role !== "student" && role !== "teacher") {
          await storage.updateUserProfile(req.params.id, { assignedCurricula: [] });
        }
        if (role !== "supervisor") {
          await storage.updateUserProfile(req.params.id, { supervisedSubjects: [] });
        }
      }
      const profileUpdate: any = {};
      if (phone !== undefined) profileUpdate.phone = phone;
      if (bio !== undefined) profileUpdate.bio = bio;
      if (preferredLanguage !== undefined) profileUpdate.preferredLanguage = preferredLanguage;
      if (assignedCurricula !== undefined) profileUpdate.assignedCurricula = Array.isArray(assignedCurricula) ? assignedCurricula : [];
      if (supervisedSubjects !== undefined) profileUpdate.supervisedSubjects = Array.isArray(supervisedSubjects) ? supervisedSubjects : [];
      if (Object.keys(profileUpdate).length > 0) {
        await storage.updateUserProfile(req.params.id, profileUpdate);
      }
      res.json(updated);
    } catch (error) {
      res.status(500).json({ message: "Failed to update user" });
    }
  });

  app.post("/api/admin/users/:id/reset-password", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const { newPassword } = req.body;
      if (!newPassword || typeof newPassword !== "string" || newPassword.length < 6) {
        return res.status(400).json({ message: "Password must be at least 6 characters" });
      }
      await storage.resetUserPassword(req.params.id, newPassword);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to reset password" });
    }
  });

  app.delete("/api/admin/users/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      if (req.params.id === userId) {
        return res.status(400).json({ message: "Cannot delete your own account" });
      }
      await storage.deleteUser(req.params.id);
      res.json({ success: true });
    } catch (error: any) {
      console.error("Delete user error:", error);
      res.status(500).json({ message: error.message || "Failed to delete user" });
    }
  });

  app.get("/api/subscription-plans", async (_req: any, res) => {
    try {
      const plans = await storage.getSubscriptionPlans();
      res.json(plans);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch plans" });
    }
  });

  app.post("/api/admin/subscription-plans", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const plan = await storage.createSubscriptionPlan(req.body);
      res.json(plan);
    } catch (error) {
      res.status(500).json({ message: "Failed to create plan" });
    }
  });

  app.patch("/api/admin/subscription-plans/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const plan = await storage.updateSubscriptionPlan(req.params.id, req.body);
      res.json(plan);
    } catch (error) {
      res.status(500).json({ message: "Failed to update plan" });
    }
  });

  app.delete("/api/admin/subscription-plans/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      await storage.deleteSubscriptionPlan(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete plan" });
    }
  });

  app.get("/api/admin/subscriptions", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const subs = await storage.getAllSubscriptions();
      res.json(subs);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch subscriptions" });
    }
  });

  app.post("/api/admin/subscriptions", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const sub = await storage.createAdminSubscription(req.body);
      res.json(sub);
    } catch (error) {
      res.status(500).json({ message: "Failed to create subscription" });
    }
  });

  app.patch("/api/admin/subscriptions/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const sub = await storage.updateSubscription(req.params.id, req.body);
      res.json(sub);
    } catch (error) {
      res.status(500).json({ message: "Failed to update subscription" });
    }
  });

  app.delete("/api/admin/subscriptions/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      await storage.deleteSubscription(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete subscription" });
    }
  });

  // Teacher Routes
  app.get("/api/teacher/students", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const students = await storage.getTeacherStudents(userId);
      res.json(students);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch teacher students" });
    }
  });

  app.get("/api/teacher/stats", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const stats = await storage.getTeacherStats(userId);
      res.json(stats);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch teacher stats" });
    }
  });

  // Parent Routes
  app.get("/api/parent/children", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const children = await storage.getParentChildren(userId);
      res.json(children);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch children" });
    }
  });

  app.post("/api/parent/children", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { childId, email } = req.body;
      let targetChildId = childId;
      if (!targetChildId && email) {
        const { users } = await import("@shared/schema");
        const { db } = await import("./db");
        const { eq } = await import("drizzle-orm");
        const [user] = await db.select().from(users).where(eq(users.email, email));
        if (!user) return res.status(404).json({ message: "User not found" });
        targetChildId = user.id;
      }
      if (!targetChildId) return res.status(400).json({ message: "childId or email is required" });
      const link = await storage.addChild(userId, targetChildId);
      res.json(link);
    } catch (error) {
      res.status(500).json({ message: "Failed to add child" });
    }
  });

  app.delete("/api/parent/children/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      await storage.removeChild(userId, req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to remove child" });
    }
  });

  // Attendance Routes
  app.post("/api/attendance/sessions", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const { subjectId, sessionDate, titleAr, titleEn, notes } = req.body;
      if (!subjectId) return res.status(400).json({ message: "subjectId is required" });
      const session = await storage.createAttendanceSession({
        subjectId,
        teacherId: userId,
        sessionDate: sessionDate ? new Date(sessionDate) : new Date(),
        titleAr: titleAr || null,
        titleEn: titleEn || null,
        notes: notes || null,
      });
      res.json(session);
    } catch (error) {
      res.status(500).json({ message: "Failed to create attendance session" });
    }
  });

  app.get("/api/attendance/sessions", isAuthenticated, async (req: any, res) => {
    try {
      const { subjectId, teacherId } = req.query;
      const sessions = await storage.getAttendanceSessions(
        subjectId as string | undefined,
        teacherId as string | undefined
      );
      res.json(sessions);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch attendance sessions" });
    }
  });

  app.get("/api/attendance/sessions/:id", isAuthenticated, async (req: any, res) => {
    try {
      const session = await storage.getAttendanceSession(req.params.id);
      if (!session) return res.status(404).json({ message: "Not found" });
      res.json(session);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch attendance session" });
    }
  });

  app.post("/api/attendance/sessions/:id/records", isAuthenticated, async (req: any, res) => {
    try {
      const { records } = req.body;
      if (!records || !Array.isArray(records)) return res.status(400).json({ message: "records array is required" });
      await storage.markAttendance(req.params.id, records);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to mark attendance" });
    }
  });

  app.get("/api/attendance/student/:id", isAuthenticated, async (req: any, res) => {
    try {
      const attendance = await storage.getStudentAttendance(req.params.id);
      res.json(attendance);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch student attendance" });
    }
  });

  app.get("/api/attendance/student/:id/stats", isAuthenticated, async (req: any, res) => {
    try {
      const stats = await storage.getAttendanceStats(req.params.id);
      res.json(stats);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch attendance stats" });
    }
  });

  app.get("/api/attendance/my", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const attendance = await storage.getStudentAttendance(userId);
      res.json(attendance);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch attendance" });
    }
  });

  app.get("/api/attendance/my/stats", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const stats = await storage.getAttendanceStats(userId);
      res.json(stats);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch attendance stats" });
    }
  });

  app.get("/api/admin/settings", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const settings = await getAllSettings();
      const safeSettings: Record<string, string> = {};
      for (const [key, value] of Object.entries(settings)) {
        if (key.includes("secret")) {
          safeSettings[key] = value ? "••••••••" : "";
        } else {
          safeSettings[key] = value;
        }
      }
      res.json(safeSettings);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch settings" });
    }
  });

  app.post("/api/admin/settings", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "غير مصرح" });
      }
      const { settings } = req.body;
      if (!settings || typeof settings !== "object") {
        return res.status(400).json({ message: "بيانات غير صالحة" });
      }
      for (const [key, value] of Object.entries(settings)) {
        if (typeof value === "string" && value !== "••••••••") {
          await upsertSetting(key, value);
        }
      }
      res.json({ message: "تم حفظ الإعدادات بنجاح" });
    } catch (error) {
      res.status(500).json({ message: "Failed to save settings" });
    }
  });

  app.post("/api/admin/upload", isAuthenticated, upload.single("file"), async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") {
        return res.status(403).json({ message: "Forbidden" });
      }
      if (!req.file) {
        return res.status(400).json({ message: "No file uploaded" });
      }
      const url = `/uploads/${req.file.filename}`;
      res.json({ url });
    } catch (error) {
      res.status(500).json({ message: "Failed to upload file" });
    }
  });

  app.get("/api/branding", async (_req: any, res) => {
    try {
      const settings = await getAllSettings();
      res.json({
        logo_url: settings.brand_logo_url || "",
        favicon_url: settings.brand_favicon_url || "",
        primary_color: settings.brand_primary_color || "",
        secondary_color: settings.brand_secondary_color || "",
        accent_color: settings.brand_accent_color || "",
        sidebar_color: settings.brand_sidebar_color || "",
        org_name_ar: settings.org_name_ar || "",
        org_name_en: settings.org_name_en || "",
      });
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch branding" });
    }
  });

  // Content Management - Admin/Teacher
  app.post("/api/admin/curricula", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const curriculum = await storage.createCurriculum(req.body);
      res.json(curriculum);
    } catch (error) {
      res.status(500).json({ message: "Failed to create curriculum" });
    }
  });

  app.post("/api/admin/grades", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const grade = await storage.createGrade(req.body);
      res.json(grade);
    } catch (error) {
      res.status(500).json({ message: "Failed to create grade" });
    }
  });

  app.post("/api/admin/subjects", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const subject = await storage.createSubject(req.body);
      res.json(subject);
    } catch (error) {
      res.status(500).json({ message: "Failed to create subject" });
    }
  });

  app.post("/api/admin/sections", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const section = await storage.createSection(req.body);
      res.json(section);
    } catch (error) {
      res.status(500).json({ message: "Failed to create section" });
    }
  });

  app.post("/api/admin/lessons", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const lesson = await storage.createLesson(req.body);
      res.json(lesson);
    } catch (error) {
      res.status(500).json({ message: "Failed to create lesson" });
    }
  });

  app.post("/api/admin/assessments", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const assessment = await storage.createAssessment(req.body);
      res.json(assessment);
    } catch (error) {
      res.status(500).json({ message: "Failed to create assessment" });
    }
  });

  app.delete("/api/admin/curricula/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      await storage.deleteCurriculum(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete curriculum" });
    }
  });

  app.delete("/api/admin/grades/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      await storage.deleteGrade(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete grade" });
    }
  });

  app.delete("/api/admin/subjects/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      await storage.deleteSubject(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete subject" });
    }
  });

  app.delete("/api/admin/sections/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      await storage.deleteSection(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete section" });
    }
  });

  app.delete("/api/admin/lessons/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      await storage.deleteLesson(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete lesson" });
    }
  });

  app.delete("/api/admin/assessments/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      await storage.deleteAssessment(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete assessment" });
    }
  });

  app.patch("/api/admin/curricula/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const result = await storage.updateCurriculum(req.params.id, req.body);
      if (!result) return res.status(404).json({ message: "Not found" });
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to update curriculum" });
    }
  });

  app.patch("/api/admin/grades/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const result = await storage.updateGrade(req.params.id, req.body);
      if (!result) return res.status(404).json({ message: "Not found" });
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to update grade" });
    }
  });

  app.patch("/api/admin/subjects/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const result = await storage.updateSubject(req.params.id, req.body);
      if (!result) return res.status(404).json({ message: "Not found" });
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to update subject" });
    }
  });

  app.patch("/api/admin/sections/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const result = await storage.updateSection(req.params.id, req.body);
      if (!result) return res.status(404).json({ message: "Not found" });
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to update section" });
    }
  });

  app.patch("/api/admin/lessons/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const result = await storage.updateLesson(req.params.id, req.body);
      if (!result) return res.status(404).json({ message: "Not found" });
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to update lesson" });
    }
  });

  app.patch("/api/admin/assessments/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const result = await storage.updateAssessment(req.params.id, req.body);
      if (!result) return res.status(404).json({ message: "Not found" });
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to update assessment" });
    }
  });

  app.post("/api/admin/resources", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      const resource = await storage.createResource(req.body);
      res.json(resource);
    } catch (error) {
      res.status(500).json({ message: "Failed to create resource" });
    }
  });

  app.delete("/api/admin/resources/:id", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const profile = await storage.getProfile(userId);
      if (!profile || (profile.role !== "admin" && profile.role !== "teacher")) return res.status(403).json({ message: "Forbidden" });
      await storage.deleteResource(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete resource" });
    }
  });

  // ==================== Virtual School Routes ====================

  // Schedule Periods (admin)
  app.get("/api/schedule-periods", isAuthenticated, async (_req: any, res) => {
    try {
      const periods = await storage.getSchedulePeriods();
      res.json(periods);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch schedule periods" });
    }
  });

  app.post("/api/admin/schedule-periods", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const period = await storage.createSchedulePeriod(req.body);
      res.json(period);
    } catch (error) {
      res.status(500).json({ message: "Failed to create schedule period" });
    }
  });

  app.patch("/api/admin/schedule-periods/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const period = await storage.updateSchedulePeriod(req.params.id, req.body);
      res.json(period);
    } catch (error) {
      res.status(500).json({ message: "Failed to update schedule period" });
    }
  });

  app.delete("/api/admin/schedule-periods/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      await storage.deleteSchedulePeriod(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete schedule period" });
    }
  });

  // School Classes (admin)
  app.get("/api/school-classes", isAuthenticated, async (_req: any, res) => {
    try {
      const classes = await storage.getSchoolClasses();
      res.json(classes);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch school classes" });
    }
  });

  app.get("/api/school-classes/:id", isAuthenticated, async (req: any, res) => {
    try {
      const cls = await storage.getSchoolClass(req.params.id);
      if (!cls) return res.status(404).json({ message: "Class not found" });
      res.json(cls);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch class" });
    }
  });

  app.post("/api/admin/school-classes", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const cls = await storage.createSchoolClass(req.body);
      res.json(cls);
    } catch (error) {
      res.status(500).json({ message: "Failed to create class" });
    }
  });

  app.patch("/api/admin/school-classes/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const cls = await storage.updateSchoolClass(req.params.id, req.body);
      res.json(cls);
    } catch (error) {
      res.status(500).json({ message: "Failed to update class" });
    }
  });

  app.delete("/api/admin/school-classes/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      await storage.deleteSchoolClass(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete class" });
    }
  });

  // Class Enrollments (admin)
  app.get("/api/school-classes/:id/enrollments", isAuthenticated, async (req: any, res) => {
    try {
      const enrollments = await storage.getClassEnrollments(req.params.id);
      res.json(enrollments);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch enrollments" });
    }
  });

  app.post("/api/admin/class-enrollments", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const enrollment = await storage.createClassEnrollment(req.body);
      res.json(enrollment);
    } catch (error) {
      res.status(500).json({ message: "Failed to create enrollment" });
    }
  });

  app.delete("/api/admin/class-enrollments/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      await storage.deleteClassEnrollment(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete enrollment" });
    }
  });

  // Class Teachers (admin)
  app.get("/api/school-classes/:id/teachers", isAuthenticated, async (req: any, res) => {
    try {
      const teachersList = await storage.getClassTeachers(req.params.id);
      const enriched = await Promise.all(teachersList.map(async (ct) => {
        const u = await storage.getUser(ct.teacherId);
        return { ...ct, teacherName: u ? `${u.firstName || ""} ${u.lastName || ""}`.trim() : "" };
      }));
      res.json(enriched);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch class teachers" });
    }
  });

  app.post("/api/admin/class-teachers", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const teacher = await storage.createClassTeacher(req.body);
      res.json(teacher);
    } catch (error) {
      res.status(500).json({ message: "Failed to assign teacher" });
    }
  });

  app.delete("/api/admin/class-teachers/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      await storage.deleteClassTeacher(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to remove teacher" });
    }
  });

  // Class Schedules (admin)
  app.get("/api/school-classes/:id/schedule", isAuthenticated, async (req: any, res) => {
    try {
      const schedule = await storage.getClassSchedules(req.params.id);
      res.json(schedule);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch schedule" });
    }
  });

  app.post("/api/admin/class-schedules", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const schedule = await storage.createClassSchedule(req.body);
      res.json(schedule);
    } catch (error) {
      res.status(500).json({ message: "Failed to create schedule entry" });
    }
  });

  app.patch("/api/admin/class-schedules/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const schedule = await storage.updateClassSchedule(req.params.id, req.body);
      res.json(schedule);
    } catch (error) {
      res.status(500).json({ message: "Failed to update schedule entry" });
    }
  });

  app.delete("/api/admin/class-schedules/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      await storage.deleteClassSchedule(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete schedule entry" });
    }
  });

  // Weekly Plans (teacher)
  app.get("/api/weekly-plans", isAuthenticated, async (req: any, res) => {
    try {
      const { teacherId, classId } = req.query;
      const plans = await storage.getWeeklyPlans(teacherId as string, classId as string);
      res.json(plans);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch weekly plans" });
    }
  });

  app.get("/api/weekly-plans/:id", isAuthenticated, async (req: any, res) => {
    try {
      const plan = await storage.getWeeklyPlan(req.params.id);
      if (!plan) return res.status(404).json({ message: "Plan not found" });
      const items = await storage.getWeeklyPlanItems(plan.id);
      res.json({ ...plan, items });
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch weekly plan" });
    }
  });

  app.post("/api/weekly-plans", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "teacher" && profile.role !== "admin")) return res.status(403).json({ message: "Forbidden" });
      const plan = await storage.createWeeklyPlan({ ...req.body, teacherId: req.user.id });
      res.json(plan);
    } catch (error) {
      res.status(500).json({ message: "Failed to create weekly plan" });
    }
  });

  app.patch("/api/weekly-plans/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "teacher" && profile.role !== "admin")) return res.status(403).json({ message: "Forbidden" });
      const plan = await storage.updateWeeklyPlan(req.params.id, req.body);
      res.json(plan);
    } catch (error) {
      res.status(500).json({ message: "Failed to update weekly plan" });
    }
  });

  app.delete("/api/weekly-plans/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "teacher" && profile.role !== "admin")) return res.status(403).json({ message: "Forbidden" });
      await storage.deleteWeeklyPlan(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete weekly plan" });
    }
  });

  // Weekly Plan Items
  app.get("/api/weekly-plans/:id/items", isAuthenticated, async (req: any, res) => {
    try {
      const items = await storage.getWeeklyPlanItems(req.params.id);
      res.json(items);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch plan items" });
    }
  });

  app.post("/api/weekly-plan-items", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "teacher" && profile.role !== "admin")) return res.status(403).json({ message: "Forbidden" });
      const item = await storage.createWeeklyPlanItem(req.body);
      res.json(item);
    } catch (error) {
      res.status(500).json({ message: "Failed to create plan item" });
    }
  });

  app.patch("/api/weekly-plan-items/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "teacher" && profile.role !== "admin")) return res.status(403).json({ message: "Forbidden" });
      const item = await storage.updateWeeklyPlanItem(req.params.id, req.body);
      res.json(item);
    } catch (error) {
      res.status(500).json({ message: "Failed to update plan item" });
    }
  });

  app.delete("/api/weekly-plan-items/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "teacher" && profile.role !== "admin")) return res.status(403).json({ message: "Forbidden" });
      await storage.deleteWeeklyPlanItem(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete plan item" });
    }
  });

  // Leave Requests
  app.get("/api/leave-requests", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile) return res.status(403).json({ message: "Forbidden" });
      const { status } = req.query;
      let filters: any = {};
      if (status) filters.status = status;
      if (profile.role === "parent") {
        filters.parentId = req.user.id;
      } else if (profile.role === "student") {
        filters.studentId = req.user.id;
      }
      const requests = await storage.getLeaveRequests(filters);
      res.json(requests);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch leave requests" });
    }
  });

  app.post("/api/leave-requests", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "parent") return res.status(403).json({ message: "Only parents can create leave requests" });
      const request = await storage.createLeaveRequest({ ...req.body, parentId: req.user.id });
      res.json(request);
    } catch (error) {
      res.status(500).json({ message: "Failed to create leave request" });
    }
  });

  app.patch("/api/leave-requests/:id/review", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "teacher" && profile.role !== "admin")) {
        return res.status(403).json({ message: "Only teachers and admins can review leave requests" });
      }
      const { status, reviewNotes } = req.body;
      if (!status || !["approved", "rejected"].includes(status)) {
        return res.status(400).json({ message: "Invalid status" });
      }
      const request = await storage.updateLeaveRequest(req.params.id, {
        status,
        reviewNotes,
        reviewedBy: req.user.id,
        reviewedAt: new Date(),
      });
      res.json(request);
    } catch (error) {
      res.status(500).json({ message: "Failed to review leave request" });
    }
  });

  // Student timetable
  app.get("/api/my-timetable", isAuthenticated, async (req: any, res) => {
    try {
      const classId = await storage.getStudentClassId(req.user.id);
      if (!classId) return res.json([]);
      const schedule = await storage.getClassSchedules(classId);
      res.json(schedule);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch timetable" });
    }
  });

  app.get("/api/my-class", isAuthenticated, async (req: any, res) => {
    try {
      const userId = req.user.id;
      const classes = await storage.getSchoolClasses();
      for (const cls of classes) {
        const enrollments = await storage.getClassEnrollments(cls.id);
        if (enrollments.some((e: any) => e.studentId === userId)) {
          return res.json(cls);
        }
      }
      res.json(null);
    } catch (error) {
      res.status(500).json({ message: "Failed to find class" });
    }
  });

  app.get("/api/virtual-school/enabled", async (_req: any, res) => {
    try {
      const setting = await getSetting("virtual_school_enabled");
      res.json({ enabled: setting === "true" });
    } catch (error) {
      res.json({ enabled: false });
    }
  });

  // ========================
  // Supervisor endpoints
  // ========================
  app.get("/api/supervisor/stats", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "supervisor") return res.status(403).json({ message: "Forbidden" });

      const supervisedCurricula = profile.supervisedSubjects || [];
      if (supervisedCurricula.length === 0) {
        return res.json({ totalSubjects: 0, totalTeachers: 0, totalStudents: 0, totalLessons: 0, totalInteractive: 0, publishedLessons: 0, draftLessons: 0 });
      }

      const allCurricula = await storage.getCurricula();
      const myCurricula = allCurricula.filter(c => supervisedCurricula.includes(c.id));
      let totalSubjects = 0;
      let totalLessons = 0;
      for (const curr of myCurricula) {
        const gradesData = await storage.getGradesByCurriculum(curr.id);
        for (const grade of gradesData) {
          totalSubjects += grade.subjects.length;
          for (const subj of grade.subjects) {
            const subjLessons = await storage.getLessonsBySubject(subj.id);
            totalLessons += subjLessons.length;
          }
        }
      }

      const interactives = await storage.getInteractiveLessons({ creatorId: req.user.id });
      const published = interactives.filter((l: any) => l.isPublished).length;

      const allUsers = await storage.getAllUsers();
      const teachers = allUsers.filter((u: any) => u.role === "teacher");
      const students = allUsers.filter((u: any) => u.role === "student");

      res.json({
        totalSubjects,
        totalTeachers: teachers.length,
        totalStudents: students.length,
        totalLessons,
        totalInteractive: interactives.length,
        publishedLessons: published,
        draftLessons: interactives.length - published,
      });
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch supervisor stats" });
    }
  });

  app.get("/api/supervisor/teachers", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "supervisor") return res.status(403).json({ message: "Forbidden" });
      const allUsers = await storage.getAllUsers();
      const teachers = allUsers.filter((u: any) => u.role === "teacher");
      res.json(teachers);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch teachers" });
    }
  });

  // ========================
  // Interactive Lessons CRUD
  // ========================
  app.get("/api/interactive-lessons", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile) return res.status(403).json({ message: "Forbidden" });

      const { educationalStage } = req.query;
      const filters: any = {};

      if (profile.role === "supervisor") {
        filters.creatorId = req.user.id;
      } else if (profile.role === "admin") {
        // admin can see all
      } else if (profile.role === "student") {
        // students see published lessons for their grade
      } else {
        return res.status(403).json({ message: "Forbidden" });
      }

      if (educationalStage && educationalStage !== "all") {
        filters.educationalStage = educationalStage;
      }

      const lessons = await storage.getInteractiveLessons(filters);
      res.json(lessons);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch interactive lessons" });
    }
  });

  app.get("/api/interactive-lessons/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      const lesson = await storage.getInteractiveLesson(req.params.id);
      if (!lesson) return res.status(404).json({ message: "Not found" });
      if (!lesson.isPublished && profile?.role !== "supervisor" && profile?.role !== "admin") {
        return res.status(403).json({ message: "Forbidden" });
      }
      if (!lesson.isPublished && profile?.role === "supervisor" && lesson.creatorId !== req.user.id) {
        return res.status(403).json({ message: "Forbidden" });
      }
      res.json(lesson);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch interactive lesson" });
    }
  });

  app.post("/api/interactive-lessons", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "supervisor" && profile.role !== "admin")) {
        return res.status(403).json({ message: "Only supervisors and admins can create interactive lessons" });
      }
      const lesson = await storage.createInteractiveLesson({
        ...req.body,
        creatorId: req.user.id,
      });
      res.json(lesson);
    } catch (error) {
      console.error("Create interactive lesson error:", error);
      res.status(500).json({ message: "Failed to create interactive lesson" });
    }
  });

  app.patch("/api/interactive-lessons/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "supervisor" && profile.role !== "admin")) {
        return res.status(403).json({ message: "Forbidden" });
      }
      const existing = await storage.getInteractiveLesson(req.params.id);
      if (!existing) return res.status(404).json({ message: "Not found" });
      if (profile.role === "supervisor" && existing.creatorId !== req.user.id) {
        return res.status(403).json({ message: "Forbidden" });
      }
      const lesson = await storage.updateInteractiveLesson(req.params.id, req.body);
      res.json(lesson);
    } catch (error) {
      res.status(500).json({ message: "Failed to update interactive lesson" });
    }
  });

  app.delete("/api/interactive-lessons/:id", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || (profile.role !== "supervisor" && profile.role !== "admin")) {
        return res.status(403).json({ message: "Forbidden" });
      }
      const existing = await storage.getInteractiveLesson(req.params.id);
      if (!existing) return res.status(404).json({ message: "Not found" });
      if (profile.role === "supervisor" && existing.creatorId !== req.user.id) {
        return res.status(403).json({ message: "Forbidden" });
      }
      await storage.deleteInteractiveLesson(req.params.id);
      res.json({ success: true });
    } catch (error) {
      res.status(500).json({ message: "Failed to delete interactive lesson" });
    }
  });

  app.post("/api/interactive-lessons/:id/submit", isAuthenticated, async (req: any, res) => {
    try {
      const result = await storage.createInteractiveLessonResult({
        ...req.body,
        userId: req.user.id,
        interactiveLessonId: req.params.id,
      });
      res.json(result);
    } catch (error) {
      res.status(500).json({ message: "Failed to submit result" });
    }
  });

  // Subjects tree for supervisor assignment
  app.get("/api/admin/subjects-tree", isAuthenticated, async (req: any, res) => {
    try {
      const profile = await storage.getProfile(req.user.id);
      if (!profile || profile.role !== "admin") return res.status(403).json({ message: "Forbidden" });
      const allCurricula = await storage.getCurricula();
      const tree = [];
      for (const curr of allCurricula) {
        const gradesData = await storage.getGradesByCurriculum(curr.id);
        tree.push({
          ...curr,
          grades: gradesData,
        });
      }
      res.json(tree);
    } catch (error) {
      res.status(500).json({ message: "Failed to fetch subjects tree" });
    }
  });

  return httpServer;
}
