import { Express, Request, Response } from "express";
import { z } from "zod";
import { storage } from "./storage";
import { v4 as uuidv4 } from "uuid";

// Validation schema for video sessions
const videoSessionSchema = z.object({
  appointmentId: z.number().optional(),
  sessionName: z.string().min(3),
  description: z.string().optional(),
  scheduledStartTime: z.string().refine(val => !isNaN(Date.parse(val)), {
    message: "التاريخ غير صالح. يجب أن يكون بصيغة ISO"
  }),
  scheduledEndTime: z.string().refine(val => !isNaN(Date.parse(val)), {
    message: "التاريخ غير صالح. يجب أن يكون بصيغة ISO"
  }),
  hostId: z.number(),
  attendees: z.array(z.number()).optional(),
});

export const setupVideoConference = (app: Express) => {
  // Create a new video session
  app.post("/api/video-sessions", async (req: Request, res: Response) => {
    try {
      if (!req.user) {
        return res.status(401).json({ message: "يجب تسجيل الدخول لإنشاء جلسة فيديو" });
      }
      
      const validatedData = videoSessionSchema.parse(req.body);
      
      // Generate a unique session ID
      const sessionId = uuidv4();
      
      const videoSession = await storage.createVideoSession({
        ...validatedData,
        sessionId,
        createdBy: req.user.id,
        status: "scheduled",
      });
      
      res.status(201).json(videoSession);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "خطأ في البيانات المدخلة", details: error.errors });
      }
      console.error("Error creating video session:", error);
      res.status(500).json({ message: "فشل في إنشاء جلسة فيديو" });
    }
  });
  
  // Join a video session
  app.post("/api/video-sessions/:sessionId/join", async (req: Request, res: Response) => {
    try {
      if (!req.user) {
        return res.status(401).json({ message: "يجب تسجيل الدخول للانضمام إلى جلسة فيديو" });
      }
      
      const { sessionId } = req.params;
      const session = await storage.getVideoSessionBySessionId(sessionId);
      
      if (!session) {
        return res.status(404).json({ message: "جلسة الفيديو غير موجودة" });
      }
      
      // Check if user is authorized to join
      const isHost = session.hostId === req.user.id;
      const isCreator = session.createdBy === req.user.id;
      
      // Check if user is an attendee
      let isAttendee = false;
      if (session.attendees) {
        const attendeesList = typeof session.attendees === 'string' 
          ? JSON.parse(session.attendees) 
          : session.attendees;
          
        if (Array.isArray(attendeesList) && attendeesList.includes(req.user.id)) {
          isAttendee = true;
        }
      }
      
      if (!isHost && !isCreator && !isAttendee) {
        return res.status(403).json({ message: "غير مصرح بالانضمام إلى هذه الجلسة" });
      }
      
      // Check if the session is active
      if (session.status !== "active") {
        return res.status(400).json({ message: "جلسة الفيديو غير نشطة" });
      }
      
      res.json({
        ...session,
        userRole: isHost ? "host" : "participant",
      });
    } catch (error) {
      console.error("Error joining video session:", error);
      res.status(500).json({ message: "فشل في الانضمام إلى جلسة الفيديو" });
    }
  });
  
  // Start a video session
  app.post("/api/video-sessions/:sessionId/start", async (req: Request, res: Response) => {
    try {
      if (!req.user) {
        return res.status(401).json({ message: "يجب تسجيل الدخول لبدء جلسة فيديو" });
      }
      
      const { sessionId } = req.params;
      const session = await storage.getVideoSessionBySessionId(sessionId);
      
      if (!session) {
        return res.status(404).json({ message: "جلسة الفيديو غير موجودة" });
      }
      
      // Only the host or creator can start the session
      if (session.hostId !== req.user.id && session.createdBy !== req.user.id) {
        return res.status(403).json({ message: "غير مصرح ببدء هذه الجلسة" });
      }
      
      // Change status to active
      const updatedSession = await storage.updateVideoSessionStatus(session.id, "active");
      
      res.json(updatedSession);
    } catch (error) {
      console.error("Error starting video session:", error);
      res.status(500).json({ message: "فشل في بدء جلسة الفيديو" });
    }
  });
  
  // End a video session
  app.post("/api/video-sessions/:sessionId/end", async (req: Request, res: Response) => {
    try {
      if (!req.user) {
        return res.status(401).json({ message: "يجب تسجيل الدخول لإنهاء جلسة فيديو" });
      }
      
      const { sessionId } = req.params;
      const session = await storage.getVideoSessionBySessionId(sessionId);
      
      if (!session) {
        return res.status(404).json({ message: "جلسة الفيديو غير موجودة" });
      }
      
      // Only the host or creator can end the session
      if (session.hostId !== req.user.id && session.createdBy !== req.user.id) {
        return res.status(403).json({ message: "غير مصرح بإنهاء هذه الجلسة" });
      }
      
      // Mark the session as completed
      const endedSession = await storage.endVideoSession(session.id, new Date());
      
      res.json(endedSession);
    } catch (error) {
      console.error("Error ending video session:", error);
      res.status(500).json({ message: "فشل في إنهاء جلسة الفيديو" });
    }
  });
  
  // WebSocket event handlers for realtime communication
  // This should be called from the WebSocket server in routes.ts
  
  // List all upcoming video sessions
  app.get("/api/video-sessions/upcoming", async (req: Request, res: Response) => {
    try {
      // Implementation will depend on storage implementation
      // This would return sessions where the scheduled start time is in the future
      // and the status is "scheduled"
      res.json([]);
    } catch (error) {
      console.error("Error fetching upcoming sessions:", error);
      res.status(500).json({ message: "فشل في جلب جلسات الفيديو القادمة" });
    }
  });
  
  // Handle video session status change through WebSocket
  // This is an internal function to be called from the WebSocket server
  const handleVideoSessionStatusUpdate = async (
    sessionId: string, 
    userId: number, 
    status: "active" | "paused" | "completed"
  ) => {
    try {
      const session = await storage.getVideoSessionBySessionId(sessionId);
      
      if (!session) {
        return { error: "جلسة الفيديو غير موجودة" };
      }
      
      // Verify authorization
      if (session.hostId !== userId && session.createdBy !== userId) {
        return { error: "غير مصرح بتغيير حالة هذه الجلسة" };
      }
      
      const updatedSession = await storage.updateVideoSessionStatus(session.id, status);
      
      return { success: true, session: updatedSession };
    } catch (error) {
      console.error("Error updating video session status:", error);
      return { error: "فشل في تحديث حالة جلسة الفيديو" };
    }
  };
  
  // Make the handler available through the app locals
  app.locals.videoConference = {
    handleVideoSessionStatusUpdate,
  };
};