import type { Express } from "express";
import express from "express";
import { createServer, type Server } from "http";
import { storage } from "./storage";
import { setupLocalAuth, requireAuth, hashPassword } from "./local-auth";
import {
  insertTeamSchema,
  insertPlayerSchema,
  insertCoachSchema,
  insertTeamCoachSchema,
  insertMembershipFeeSchema,
  insertPaymentActivitySchema,
  insertPaymentNotificationSchema,
  insertAutomaticPaymentScheduleSchema,
  insertMemberStatusHistorySchema,
} from "@shared/schema";
import { z } from "zod";
import multer from "multer";
import path from "path";
import fs from "fs";
import { createSampleData } from "./sample-data";
import { randomBytes } from "crypto";

// Setup multer for file uploads
const uploadDir = path.join(process.cwd(), "uploads");
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true });
}

const upload = multer({
  storage: multer.diskStorage({
    destination: uploadDir,
    filename: (req, file, cb) => {
      const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
      cb(null, file.fieldname + "-" + uniqueSuffix + path.extname(file.originalname));
    },
  }),
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
  fileFilter: (req, file, cb) => {
    const allowedTypes = /jpeg|jpg|png|gif/;
    const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
    const mimetype = allowedTypes.test(file.mimetype);
    if (mimetype && extname) {
      return cb(null, true);
    } else {
      cb(new Error("Only image files are allowed"));
    }
  },
});

export async function registerRoutes(app: Express): Promise<Server> {
  // Local auth setup
  setupLocalAuth(app);

  // Serve uploaded files
  app.use("/uploads", express.static(uploadDir));

  // Password reset request endpoint
  app.post("/api/auth/request-password-reset", async (req, res) => {
    try {
      const { email } = z.object({ email: z.string().email() }).parse(req.body);
      
      const user = await storage.getUserByEmail(email);
      if (!user || user.authType !== "local") {
        // Don't reveal if user exists for security
        return res.json({ message: "If an account with that email exists, a reset link has been sent." });
      }

      // Generate secure token
      const token = randomBytes(32).toString('hex');
      const expiresAt = new Date(Date.now() + 60 * 60 * 1000); // 1 hour

      await storage.createPasswordResetToken({
        userId: user.id,
        token,
        expiresAt,
      });

      // In a real application, you would send an email here
      // For demo purposes, we'll log the token
      console.log(`Password reset token for ${email}: ${token}`);
      console.log(`Reset URL: http://localhost:5000/reset-password?token=${token}`);

      res.json({ 
        message: "If an account with that email exists, a reset link has been sent."
      });
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid email address" });
      }
      console.error("Error requesting password reset:", error);
      res.status(500).json({ message: "Failed to process password reset request" });
    }
  });

  // Password reset verification endpoint
  app.get("/api/auth/verify-reset-token/:token", async (req, res) => {
    try {
      const { token } = req.params;
      const resetToken = await storage.getPasswordResetToken(token);
      
      if (!resetToken) {
        return res.status(400).json({ message: "Invalid or expired reset token" });
      }

      res.json({ valid: true, userId: resetToken.userId });
    } catch (error) {
      console.error("Error verifying reset token:", error);
      res.status(500).json({ message: "Failed to verify reset token" });
    }
  });

  // Password reset completion endpoint
  app.post("/api/auth/reset-password", async (req, res) => {
    try {
      const { token, newPassword } = z.object({
        token: z.string(),
        newPassword: z.string().min(8)
      }).parse(req.body);

      const resetToken = await storage.getPasswordResetToken(token);
      if (!resetToken) {
        return res.status(400).json({ message: "Invalid or expired reset token" });
      }

      // Hash the new password
      const hashedPassword = await hashPassword(newPassword);

      // Update user password
      await storage.updateUserPassword(resetToken.userId, hashedPassword);
      
      // Mark token as used
      await storage.markPasswordResetTokenAsUsed(resetToken.id);

      res.json({ message: "Password reset successfully" });
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid request data" });
      }
      console.error("Error resetting password:", error);
      res.status(500).json({ message: "Failed to reset password" });
    }
  });

  // Auth routes are now handled in local-auth.ts

  // User profile management routes
  app.put("/api/auth/user", requireAuth, async (req: any, res) => {
    try {
      const userId = req.user?.id;
      const updateData = req.body;
      
      const updatedUser = await storage.updateUser(userId, updateData);
      res.json(updatedUser);
    } catch (error) {
      console.error("Error updating user:", error);
      res.status(500).json({ message: "Failed to update user" });
    }
  });

  // Get user's club roles
  app.get("/api/user/roles", requireAuth, async (req: any, res) => {
    try {
      const userId = req.user?.id;
      const roles = await storage.getUserClubRoles(userId);
      res.json(roles);
    } catch (error) {
      console.error("Error fetching user roles:", error);
      res.status(500).json({ message: "Failed to fetch user roles" });
    }
  });

  // Add new club role for user
  app.post("/api/user/roles", requireAuth, async (req: any, res) => {
    try {
      const userId = req.user?.id;
      const roleData = { ...req.body, userId };
      
      const newRole = await storage.createUserClubRole(roleData);
      res.json(newRole);
    } catch (error) {
      console.error("Error creating user role:", error);
      res.status(500).json({ message: "Failed to create user role" });
    }
  });

  // Update user club role
  app.put("/api/user/roles/:roleId", requireAuth, async (req: any, res) => {
    try {
      const userId = req.user?.id;
      const roleId = parseInt(req.params.roleId);
      const updateData = req.body;
      
      // Verify role belongs to user
      const existingRole = await storage.getUserClubRole(roleId);
      if (!existingRole || existingRole.userId !== userId) {
        return res.status(404).json({ message: "Role not found" });
      }
      
      const updatedRole = await storage.updateUserClubRole(roleId, updateData);
      res.json(updatedRole);
    } catch (error) {
      console.error("Error updating user role:", error);
      res.status(500).json({ message: "Failed to update user role" });
    }
  });

  // Delete user club role
  app.delete("/api/user/roles/:roleId", requireAuth, async (req: any, res) => {
    try {
      const userId = req.user?.id;
      const roleId = parseInt(req.params.roleId);
      
      // Verify role belongs to user
      const existingRole = await storage.getUserClubRole(roleId);
      if (!existingRole || existingRole.userId !== userId) {
        return res.status(404).json({ message: "Role not found" });
      }
      
      await storage.deleteUserClubRole(roleId);
      res.json({ message: "Role deleted successfully" });
    } catch (error) {
      console.error("Error deleting user role:", error);
      res.status(500).json({ message: "Failed to delete user role" });
    }
  });

  // Subscription and Membership Fee Management Routes
  
  // Membership fees
  app.get("/api/membership-fees", requireAuth, async (req, res) => {
    try {
      const organizationId = req.query.organizationId ? parseInt(req.query.organizationId as string) : undefined;
      const fees = await storage.getMembershipFees(organizationId);
      res.json(fees);
    } catch (error) {
      console.error("Error fetching membership fees:", error);
      res.status(500).json({ message: "Failed to fetch membership fees" });
    }
  });

  app.post("/api/membership-fees", requireAuth, async (req, res) => {
    try {
      const feeData = req.body;
      const fee = await storage.createMembershipFee(feeData);
      
      // Schedule automatic payment reminder
      const reminderDate = new Date(fee.dueDate);
      reminderDate.setDate(reminderDate.getDate() - 3); // 3 days before due date
      
      if (reminderDate > new Date()) {
        await storage.schedulePaymentReminder(fee.id, reminderDate);
      }
      
      res.json(fee);
    } catch (error) {
      console.error("Error creating membership fee:", error);
      res.status(500).json({ message: "Failed to create membership fee" });
    }
  });

  app.get("/api/membership-fees/overdue", requireAuth, async (req, res) => {
    try {
      const overdueFees = await storage.getOverdueFees();
      res.json(overdueFees);
    } catch (error) {
      console.error("Error fetching overdue fees:", error);
      res.status(500).json({ message: "Failed to fetch overdue fees" });
    }
  });

  app.get("/api/membership-fees/user/:userId", requireAuth, async (req, res) => {
    try {
      const userId = req.params.userId;
      const fees = await storage.getUserMembershipFees(userId);
      res.json(fees);
    } catch (error) {
      console.error("Error fetching user membership fees:", error);
      res.status(500).json({ message: "Failed to fetch user membership fees" });
    }
  });

  app.put("/api/membership-fees/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const feeData = req.body;
      const fee = await storage.updateMembershipFee(id, feeData);
      res.json(fee);
    } catch (error) {
      console.error("Error updating membership fee:", error);
      res.status(500).json({ message: "Failed to update membership fee" });
    }
  });

  // Payment activities
  app.get("/api/payment-activities", requireAuth, async (req, res) => {
    try {
      const membershipFeeId = req.query.membershipFeeId ? parseInt(req.query.membershipFeeId as string) : undefined;
      const activities = await storage.getPaymentActivities(membershipFeeId);
      res.json(activities);
    } catch (error) {
      console.error("Error fetching payment activities:", error);
      res.status(500).json({ message: "Failed to fetch payment activities" });
    }
  });

  app.post("/api/payment-activities", requireAuth, async (req, res) => {
    try {
      const activityData = req.body;
      const activity = await storage.createPaymentActivity(activityData);
      
      // If payment is completed, update membership fee status and reactivate member if suspended
      if (activity.status === 'completed') {
        await storage.updateMembershipFee(activity.membershipFeeId, { status: 'paid' });
        
        if (activity.userId) {
          const user = await storage.getUser(activity.userId);
          if (user && user.status === 'suspended') {
            await storage.reactivateMember(activity.userId, activity.organizationId);
          }
        }
      }
      
      res.json(activity);
    } catch (error) {
      console.error("Error creating payment activity:", error);
      res.status(500).json({ message: "Failed to create payment activity" });
    }
  });

  app.get("/api/payment-activities/user/:userId", requireAuth, async (req, res) => {
    try {
      const userId = req.params.userId;
      const activities = await storage.getPaymentHistory(userId);
      res.json(activities);
    } catch (error) {
      console.error("Error fetching payment history:", error);
      res.status(500).json({ message: "Failed to fetch payment history" });
    }
  });

  app.put("/api/payment-activities/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const activityData = req.body;
      const activity = await storage.updatePaymentActivity(id, activityData);
      res.json(activity);
    } catch (error) {
      console.error("Error updating payment activity:", error);
      res.status(500).json({ message: "Failed to update payment activity" });
    }
  });

  // Payment notifications
  app.get("/api/payment-notifications/pending", requireAuth, async (req, res) => {
    try {
      const notifications = await storage.getPendingNotifications();
      res.json(notifications);
    } catch (error) {
      console.error("Error fetching pending notifications:", error);
      res.status(500).json({ message: "Failed to fetch pending notifications" });
    }
  });

  app.post("/api/payment-notifications", requireAuth, async (req, res) => {
    try {
      const notificationData = req.body;
      const notification = await storage.createPaymentNotification(notificationData);
      res.json(notification);
    } catch (error) {
      console.error("Error creating payment notification:", error);
      res.status(500).json({ message: "Failed to create payment notification" });
    }
  });

  app.put("/api/payment-notifications/:id/status", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const { status } = req.body;
      await storage.updateNotificationStatus(id, status);
      res.json({ message: "Notification status updated" });
    } catch (error) {
      console.error("Error updating notification status:", error);
      res.status(500).json({ message: "Failed to update notification status" });
    }
  });

  // Automatic payment schedules
  app.get("/api/automatic-payment-schedules", requireAuth, async (req, res) => {
    try {
      const schedules = await storage.getActivePaymentSchedules();
      res.json(schedules);
    } catch (error) {
      console.error("Error fetching payment schedules:", error);
      res.status(500).json({ message: "Failed to fetch payment schedules" });
    }
  });

  app.post("/api/automatic-payment-schedules", requireAuth, async (req, res) => {
    try {
      const scheduleData = req.body;
      const schedule = await storage.createAutomaticPaymentSchedule(scheduleData);
      res.json(schedule);
    } catch (error) {
      console.error("Error creating payment schedule:", error);
      res.status(500).json({ message: "Failed to create payment schedule" });
    }
  });

  app.put("/api/automatic-payment-schedules/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const scheduleData = req.body;
      const schedule = await storage.updatePaymentSchedule(id, scheduleData);
      res.json(schedule);
    } catch (error) {
      console.error("Error updating payment schedule:", error);
      res.status(500).json({ message: "Failed to update payment schedule" });
    }
  });

  app.delete("/api/automatic-payment-schedules/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.suspendPaymentSchedule(id);
      res.json({ message: "Payment schedule suspended" });
    } catch (error) {
      console.error("Error suspending payment schedule:", error);
      res.status(500).json({ message: "Failed to suspend payment schedule" });
    }
  });

  // Member status management
  app.get("/api/member-status/:userId", requireAuth, async (req, res) => {
    try {
      const userId = req.params.userId;
      const history = await storage.getMemberStatusHistory(userId);
      res.json(history);
    } catch (error) {
      console.error("Error fetching member status history:", error);
      res.status(500).json({ message: "Failed to fetch member status history" });
    }
  });

  app.post("/api/member-status/suspend", requireAuth, async (req, res) => {
    try {
      const { userId, organizationId, membershipFeeId } = req.body;
      await storage.suspendMemberForNonPayment(userId, organizationId, membershipFeeId);
      res.json({ message: "Member suspended for non-payment" });
    } catch (error) {
      console.error("Error suspending member:", error);
      res.status(500).json({ message: "Failed to suspend member" });
    }
  });

  app.post("/api/member-status/reactivate", requireAuth, async (req, res) => {
    try {
      const { userId, organizationId } = req.body;
      await storage.reactivateMember(userId, organizationId);
      res.json({ message: "Member reactivated" });
    } catch (error) {
      console.error("Error reactivating member:", error);
      res.status(500).json({ message: "Failed to reactivate member" });
    }
  });

  // Process overdue payments and automatic suspensions
  app.post("/api/process-overdue-payments", requireAuth, async (req, res) => {
    try {
      const overdueFees = await storage.getOverdueFees();
      let processedCount = 0;
      
      for (const fee of overdueFees) {
        const gracePeriodEnd = new Date(fee.dueDate);
        gracePeriodEnd.setDate(gracePeriodEnd.getDate() + (fee.gracePeriodDays || 7));
        
        if (new Date() > gracePeriodEnd && fee.userId) {
          // Update fee status to overdue
          await storage.updateMembershipFee(fee.id, { status: 'overdue' });
          
          // Suspend member
          await storage.suspendMemberForNonPayment(fee.userId, fee.organizationId, fee.id);
          
          // Send final notice notification
          await storage.createPaymentNotification({
            membershipFeeId: fee.id,
            userId: fee.userId,
            organizationId: fee.organizationId,
            notificationType: 'final_notice',
            method: 'email',
            scheduledFor: new Date(),
            subject: 'Final Payment Notice - Account Suspended',
            message: `Your account has been suspended due to overdue payment of $${(fee.amount / 100).toFixed(2)}. Please contact us to resolve this issue.`,
            emailAddress: '',
          });
          
          processedCount++;
        }
      }
      
      res.json({ message: `Processed ${processedCount} overdue payments` });
    } catch (error) {
      console.error("Error processing overdue payments:", error);
      res.status(500).json({ message: "Failed to process overdue payments" });
    }
  });

  // Dashboard routes
  app.get("/api/dashboard/stats", requireAuth, async (req, res) => {
    try {
      const stats = await storage.getDashboardStats();
      res.json(stats);
    } catch (error) {
      console.error("Error fetching dashboard stats:", error);
      res.status(500).json({ message: "Failed to fetch dashboard stats" });
    }
  });

  // Team routes
  app.get("/api/teams", requireAuth, async (req, res) => {
    try {
      const teams = await storage.getTeams();
      res.json(teams);
    } catch (error) {
      console.error("Error fetching teams:", error);
      res.status(500).json({ message: "Failed to fetch teams" });
    }
  });

  app.get("/api/teams/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const team = await storage.getTeam(id);
      if (!team) {
        return res.status(404).json({ message: "Team not found" });
      }
      res.json(team);
    } catch (error) {
      console.error("Error fetching team:", error);
      res.status(500).json({ message: "Failed to fetch team" });
    }
  });

  app.post("/api/teams", requireAuth, upload.single("logo"), async (req, res) => {
    try {
      const teamData = insertTeamSchema.parse(req.body);
      if (req.file) {
        teamData.logoUrl = `/uploads/${req.file.filename}`;
      }
      const team = await storage.createTeam(teamData);
      res.json(team);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid team data", errors: error.errors });
      }
      console.error("Error creating team:", error);
      res.status(500).json({ message: "Failed to create team" });
    }
  });

  app.put("/api/teams/:id", requireAuth, upload.single("logo"), async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const teamData = insertTeamSchema.partial().parse(req.body);
      if (req.file) {
        teamData.logoUrl = `/uploads/${req.file.filename}`;
      }
      const team = await storage.updateTeam(id, teamData);
      res.json(team);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid team data", errors: error.errors });
      }
      console.error("Error updating team:", error);
      res.status(500).json({ message: "Failed to update team" });
    }
  });

  app.delete("/api/teams/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteTeam(id);
      res.json({ message: "Team deleted successfully" });
    } catch (error) {
      console.error("Error deleting team:", error);
      res.status(500).json({ message: "Failed to delete team" });
    }
  });

  // Player routes
  app.get("/api/players", requireAuth, async (req, res) => {
    try {
      const players = await storage.getPlayers();
      res.json(players);
    } catch (error) {
      console.error("Error fetching players:", error);
      res.status(500).json({ message: "Failed to fetch players" });
    }
  });

  app.get("/api/players/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const player = await storage.getPlayer(id);
      if (!player) {
        return res.status(404).json({ message: "Player not found" });
      }
      res.json(player);
    } catch (error) {
      console.error("Error fetching player:", error);
      res.status(500).json({ message: "Failed to fetch player" });
    }
  });

  app.post("/api/players", requireAuth, async (req, res) => {
    try {
      console.log("POST - Creating player");
      console.log("POST - Request body:", req.body);
      
      // Validate with schema - the client sends JSON data
      const validatedData = insertPlayerSchema.parse(req.body);
      
      const player = await storage.createPlayer(validatedData);
      console.log("POST - Created player:", player);
      res.json(player);
    } catch (error) {
      if (error instanceof z.ZodError) {
        console.error("POST - Validation error:", error.errors);
        return res.status(400).json({ message: "Invalid player data", errors: error.errors });
      }
      console.error("POST - Error creating player:", error);
      res.status(500).json({ message: "Failed to create player" });
    }
  });

  // Add PATCH route for player updates (used by drag-drop components)
  app.patch("/api/players/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      console.log("PATCH - Updating player ID:", id);
      console.log("PATCH - Request body:", req.body);
      
      const existingPlayer = await storage.getPlayer(id);
      if (!existingPlayer) {
        return res.status(404).json({ message: "Player not found" });
      }
      
      const playerData = insertPlayerSchema.partial().parse({
        ...req.body,
        teamId: req.body.teamId ? parseInt(req.body.teamId) : null,
        jerseyNumber: req.body.jerseyNumber ? parseInt(req.body.jerseyNumber) : null,
        height: req.body.height ? parseInt(req.body.height) : null,
        weight: req.body.weight ? parseInt(req.body.weight) : null,
      });
      
      const player = await storage.updatePlayer(id, playerData);
      res.json(player);
    } catch (error) {
      if (error instanceof z.ZodError) {
        console.error("PATCH - Validation error:", error.errors);
        return res.status(400).json({ message: "Invalid player data", errors: error.errors });
      }
      console.error("PATCH - Error updating player:", error);
      res.status(500).json({ message: "Failed to update player", error: String(error) });
    }
  });

  app.put("/api/players/:id", requireAuth, upload.single("profileImage"), async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      console.log("PUT - Updating player ID:", id);
      console.log("PUT - Request body:", req.body);
      console.log("PUT - File:", req.file ? req.file.filename : "No file");
      
      // Check if player exists first
      const existingPlayer = await storage.getPlayer(id);
      if (!existingPlayer) {
        return res.status(404).json({ message: "Player not found" });
      }
      
      // Prepare player data, preserving existing values when not provided
      const updateData: any = { ...req.body };
      
      // Only update teamId if explicitly provided
      if (req.body.teamId !== undefined && req.body.teamId !== '') {
        updateData.teamId = parseInt(req.body.teamId);
      } else {
        // Remove teamId from update data to preserve existing value
        delete updateData.teamId;
      }
      
      // Handle numeric fields
      if (req.body.jerseyNumber !== undefined && req.body.jerseyNumber !== '') {
        updateData.jerseyNumber = parseInt(req.body.jerseyNumber);
      } else if (req.body.jerseyNumber === '') {
        updateData.jerseyNumber = null;
      }
      
      if (req.body.height !== undefined && req.body.height !== '') {
        updateData.height = parseInt(req.body.height);
      } else if (req.body.height === '') {
        updateData.height = null;
      }
      
      if (req.body.weight !== undefined && req.body.weight !== '') {
        updateData.weight = parseInt(req.body.weight);
      } else if (req.body.weight === '') {
        updateData.weight = null;
      }
      
      const playerData = insertPlayerSchema.partial().parse(updateData);
      
      console.log("PUT - Parsed player data:", playerData);
      
      if (req.file) {
        playerData.profileImageUrl = `/uploads/${req.file.filename}`;
      }
      
      const player = await storage.updatePlayer(id, playerData);
      console.log("PUT - Updated player:", player);
      res.json(player);
    } catch (error) {
      if (error instanceof z.ZodError) {
        console.error("PUT - Validation error:", error.errors);
        return res.status(400).json({ message: "Invalid player data", errors: error.errors });
      }
      console.error("PUT - Error updating player:", error);
      res.status(500).json({ message: "Failed to update player", error: String(error) });
    }
  });

  app.delete("/api/players/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deletePlayer(id);
      res.json({ message: "Player deleted successfully" });
    } catch (error) {
      console.error("Error deleting player:", error);
      res.status(500).json({ message: "Failed to delete player" });
    }
  });

  // Coach routes
  app.get("/api/coaches", requireAuth, async (req, res) => {
    try {
      const coaches = await storage.getCoaches();
      res.json(coaches);
    } catch (error) {
      console.error("Error fetching coaches:", error);
      res.status(500).json({ message: "Failed to fetch coaches" });
    }
  });

  app.get("/api/coaches/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const coach = await storage.getCoach(id);
      if (!coach) {
        return res.status(404).json({ message: "Coach not found" });
      }
      res.json(coach);
    } catch (error) {
      console.error("Error fetching coach:", error);
      res.status(500).json({ message: "Failed to fetch coach" });
    }
  });

  app.post("/api/coaches", requireAuth, upload.single("profileImage"), async (req, res) => {
    try {
      const coachData = insertCoachSchema.parse({
        ...req.body,
        experience: req.body.experience ? parseInt(req.body.experience) : null,
      });
      if (req.file) {
        coachData.profileImageUrl = `/uploads/${req.file.filename}`;
      }
      
      // Check if coach with this email already exists
      const existingCoach = await storage.getCoachByEmail(coachData.email);
      if (existingCoach) {
        return res.status(409).json({ 
          message: "A coach with this email already exists",
          existingCoach 
        });
      }
      
      const coach = await storage.createCoach(coachData);
      res.json(coach);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid coach data", errors: error.errors });
      }
      console.error("Error creating coach:", error);
      res.status(500).json({ message: "Failed to create coach" });
    }
  });

  app.put("/api/coaches/:id", requireAuth, upload.single("profileImage"), async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const coachData = insertCoachSchema.partial().parse({
        ...req.body,
        experience: req.body.experience ? parseInt(req.body.experience) : null,
      });
      if (req.file) {
        coachData.profileImageUrl = `/uploads/${req.file.filename}`;
      }
      const coach = await storage.updateCoach(id, coachData);
      res.json(coach);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid coach data", errors: error.errors });
      }
      console.error("Error updating coach:", error);
      res.status(500).json({ message: "Failed to update coach" });
    }
  });

  app.delete("/api/coaches/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteCoach(id);
      res.json({ message: "Coach deleted successfully" });
    } catch (error) {
      console.error("Error deleting coach:", error);
      res.status(500).json({ message: "Failed to delete coach" });
    }
  });

  // Team-Coach assignment routes
  app.post("/api/teams/:teamId/coaches", requireAuth, async (req, res) => {
    try {
      const teamId = parseInt(req.params.teamId);
      const assignmentData = insertTeamCoachSchema.parse({
        ...req.body,
        teamId,
        coachId: parseInt(req.body.coachId),
      });
      const assignment = await storage.assignCoachToTeam(assignmentData);
      res.json(assignment);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid assignment data", errors: error.errors });
      }
      console.error("Error assigning coach to team:", error);
      res.status(500).json({ message: "Failed to assign coach to team" });
    }
  });

  app.delete("/api/teams/:teamId/coaches/:coachId", requireAuth, async (req, res) => {
    try {
      const teamId = parseInt(req.params.teamId);
      const coachId = parseInt(req.params.coachId);
      
      if (isNaN(teamId) || isNaN(coachId)) {
        return res.status(400).json({ message: "Invalid team ID or coach ID" });
      }
      
      await storage.removeCoachFromTeam(teamId, coachId);
      res.json({ message: "Coach removed from team successfully" });
    } catch (error) {
      console.error("Error removing coach from team:", error);
      res.status(500).json({ message: "Failed to remove coach from team" });
    }
  });

  app.get("/api/teams/:teamId/coaches", requireAuth, async (req, res) => {
    try {
      const teamId = parseInt(req.params.teamId);
      if (isNaN(teamId)) {
        return res.status(400).json({ message: "Invalid team ID" });
      }
      const teamCoaches = await storage.getTeamCoaches(teamId);
      res.json(teamCoaches);
    } catch (error) {
      console.error("Error fetching team coaches:", error);
      res.status(500).json({ message: "Failed to fetch team coaches" });
    }
  });

  // Team statistics endpoints
  app.get("/api/teams/:teamId/player-stats", requireAuth, async (req, res) => {
    try {
      const teamId = parseInt(req.params.teamId);
      if (isNaN(teamId)) {
        return res.status(400).json({ message: "Invalid team ID" });
      }
      
      const players = await storage.getPlayersByTeam(teamId);
      
      // Calculate statistics
      const genderStats: Record<string, number> = players.reduce((acc, player) => {
        const gender = player.gender || 'Unknown';
        acc[gender] = (acc[gender] || 0) + 1;
        return acc;
      }, {} as Record<string, number>);

      const statusStats: Record<string, number> = players.reduce((acc, player) => {
        const status = player.status || 'Unknown';
        acc[status] = (acc[status] || 0) + 1;
        return acc;
      }, {} as Record<string, number>);

      res.json({
        total: players.length,
        byGender: genderStats,
        byStatus: statusStats,
        players: players
      });
    } catch (error) {
      console.error("Error fetching team player statistics:", error);
      res.status(500).json({ message: "Failed to fetch team player statistics" });
    }
  });

  app.get("/api/teams/:teamId/details", requireAuth, async (req, res) => {
    try {
      const teamId = parseInt(req.params.teamId);
      if (isNaN(teamId)) {
        return res.status(400).json({ message: "Invalid team ID" });
      }
      
      const team = await storage.getTeam(teamId);
      if (!team) {
        return res.status(404).json({ message: "Team not found" });
      }
      
      const coaches = await storage.getTeamCoaches(teamId);
      const players = await storage.getPlayersByTeam(teamId);
      
      res.json({
        ...team,
        coaches,
        playerCount: players.length,
        coachCount: coaches.length
      });
    } catch (error) {
      console.error("Error fetching team details:", error);
      res.status(500).json({ message: "Failed to fetch team details" });
    }
  });

  // Profile update endpoint
  app.put("/api/auth/user/profile", requireAuth, upload.single("profileImage"), async (req, res) => {
    try {
      const userId = (req.user as any)?.claims?.sub;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const updateData: any = {
        firstName: req.body.firstName,
        lastName: req.body.lastName,
        email: req.body.email,
      };

      if (req.file) {
        updateData.profileImageUrl = `/uploads/${req.file.filename}`;
      }

      const updatedUser = await storage.upsertUser({ id: userId, ...updateData });
      res.json(updatedUser);
    } catch (error) {
      console.error("Error updating profile:", error);
      res.status(500).json({ message: "Failed to update profile" });
    }
  });

  // Data export endpoint
  app.get("/api/data/export", requireAuth, async (req, res) => {
    try {
      const [teams, players, coaches] = await Promise.all([
        storage.getTeams(),
        storage.getPlayers(),
        storage.getCoaches(),
      ]);

      const exportData = {
        exportDate: new Date().toISOString(),
        version: "1.0",
        data: {
          teams,
          players,
          coaches,
        },
      };

      res.setHeader("Content-Type", "application/json");
      res.setHeader("Content-Disposition", `attachment; filename="sports-data-export-${new Date().toISOString().split('T')[0]}.json"`);
      res.json(exportData);
    } catch (error) {
      console.error("Error exporting data:", error);
      res.status(500).json({ message: "Failed to export data" });
    }
  });

  // Data import endpoint
  app.post("/api/data/import", requireAuth, upload.single("importFile"), async (req, res) => {
    try {
      if (!req.file) {
        return res.status(400).json({ message: "No import file provided" });
      }

      const fileContent = fs.readFileSync(req.file.path, 'utf8');
      const importData = JSON.parse(fileContent);

      if (!importData.data) {
        return res.status(400).json({ message: "Invalid import file format" });
      }

      let importedCount = 0;

      // Import teams
      if (importData.data.teams) {
        for (const team of importData.data.teams) {
          try {
            await storage.createTeam({
              name: team.name,
              sport: team.sport || "Soccer",
              organizationId: 1,
              description: team.description,
              logoUrl: team.logoUrl,
              status: team.status || "active",
            });
            importedCount++;
          } catch (error) {
            console.log(`Skipped team ${team.name} (may already exist)`);
          }
        }
      }

      // Import players
      if (importData.data.players) {
        for (const player of importData.data.players) {
          try {
            await storage.createPlayer({
              firstName: player.firstName,
              lastName: player.lastName,
              email: player.email,
              phone: player.phone || player.phoneNumber,
              dateOfBirth: player.dateOfBirth,
              gender: player.gender,
              position: player.position,
              teamId: player.teamId,
              status: player.status || "active",
              profileImageUrl: player.profileImageUrl,
              jerseyNumber: player.jerseyNumber,
              height: player.height,
              weight: player.weight,
            });
            importedCount++;
          } catch (error) {
            console.log(`Skipped player ${player.firstName} ${player.lastName} (may already exist)`);
          }
        }
      }

      // Import coaches
      if (importData.data.coaches) {
        for (const coach of importData.data.coaches) {
          try {
            await storage.createCoach({
              firstName: coach.firstName,
              lastName: coach.lastName,
              email: coach.email,
              phone: coach.phone || coach.phoneNumber,
              specialization: coach.specialization,
              experience: coach.experience || coach.yearsExperience,
              profileImageUrl: coach.profileImageUrl,
              status: coach.status || "active",
            });
            importedCount++;
          } catch (error) {
            console.log(`Skipped coach ${coach.firstName} ${coach.lastName} (may already exist)`);
          }
        }
      }

      // Clean up uploaded file
      fs.unlinkSync(req.file.path);

      res.json({ 
        message: "Data imported successfully", 
        importedRecords: importedCount,
        totalRecords: (importData.data.teams?.length || 0) + (importData.data.players?.length || 0) + (importData.data.coaches?.length || 0)
      });
    } catch (error) {
      console.error("Error importing data:", error);
      res.status(500).json({ message: "Failed to import data" });
    }
  });

  // Tournament routes
  app.get("/api/tournaments", requireAuth, async (req, res) => {
    try {
      const tournaments = await storage.getTournaments();
      res.json(tournaments);
    } catch (error) {
      console.error("Error fetching tournaments:", error);
      res.status(500).json({ message: "Failed to fetch tournaments" });
    }
  });

  app.get("/api/tournaments/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const tournament = await storage.getTournament(id);
      if (!tournament) {
        return res.status(404).json({ message: "Tournament not found" });
      }
      res.json(tournament);
    } catch (error) {
      console.error("Error fetching tournament:", error);
      res.status(500).json({ message: "Failed to fetch tournament" });
    }
  });

  app.post("/api/tournaments", requireAuth, async (req, res) => {
    try {
      const tournamentData = insertTournamentSchema.parse(req.body);
      const tournament = await storage.createTournament(tournamentData);
      res.status(201).json(tournament);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid tournament data", errors: error.errors });
      }
      console.error("Error creating tournament:", error);
      res.status(500).json({ message: "Failed to create tournament" });
    }
  });

  app.put("/api/tournaments/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const tournamentData = insertTournamentSchema.partial().parse(req.body);
      const tournament = await storage.updateTournament(id, tournamentData);
      res.json(tournament);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid tournament data", errors: error.errors });
      }
      console.error("Error updating tournament:", error);
      res.status(500).json({ message: "Failed to update tournament" });
    }
  });

  app.delete("/api/tournaments/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteTournament(id);
      res.json({ message: "Tournament deleted successfully" });
    } catch (error) {
      console.error("Error deleting tournament:", error);
      res.status(500).json({ message: "Failed to delete tournament" });
    }
  });

  // Match routes
  app.get("/api/matches", requireAuth, async (req, res) => {
    try {
      const matches = await storage.getMatches();
      res.json(matches);
    } catch (error) {
      console.error("Error fetching matches:", error);
      res.status(500).json({ message: "Failed to fetch matches" });
    }
  });

  app.get("/api/tournaments/:tournamentId/matches", requireAuth, async (req, res) => {
    try {
      const tournamentId = parseInt(req.params.tournamentId);
      const matches = await storage.getMatchesByTournament(tournamentId);
      res.json(matches);
    } catch (error) {
      console.error("Error fetching tournament matches:", error);
      res.status(500).json({ message: "Failed to fetch tournament matches" });
    }
  });

  app.post("/api/matches", requireAuth, async (req, res) => {
    try {
      const matchData = insertMatchSchema.parse(req.body);
      const match = await storage.createMatch(matchData);
      res.status(201).json(match);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid match data", errors: error.errors });
      }
      console.error("Error creating match:", error);
      res.status(500).json({ message: "Failed to create match" });
    }
  });

  app.put("/api/matches/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const matchData = insertMatchSchema.partial().parse(req.body);
      const match = await storage.updateMatch(id, matchData);
      res.json(match);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid match data", errors: error.errors });
      }
      console.error("Error updating match:", error);
      res.status(500).json({ message: "Failed to update match" });
    }
  });

  app.delete("/api/matches/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteMatch(id);
      res.json({ message: "Match deleted successfully" });
    } catch (error) {
      console.error("Error deleting match:", error);
      res.status(500).json({ message: "Failed to delete match" });
    }
  });

  // Sample data creation endpoint (for development)
  app.post("/api/create-sample-data", requireAuth, async (req, res) => {
    try {
      console.log("Starting sample data creation...");
      await createSampleData();
      console.log("Sample data creation completed");
      res.json({ message: "Sample data created successfully" });
    } catch (error) {
      console.error("Error creating sample data:", error);
      console.error("Stack trace:", (error as Error).stack);
      res.status(500).json({ message: "Failed to create sample data", error: (error as Error).message });
    }
  });

  // Calendar/Activity routes
  app.get("/api/activities", requireAuth, async (req, res) => {
    try {
      const activities = await storage.getActivities();
      res.json(activities);
    } catch (error) {
      console.error("Error fetching activities:", error);
      res.status(500).json({ message: "Failed to fetch activities" });
    }
  });

  app.get("/api/activities/:id", requireAuth, async (req, res) => {
    try {
      const activity = await storage.getActivity(parseInt(req.params.id));
      if (!activity) {
        return res.status(404).json({ message: "Activity not found" });
      }
      res.json(activity);
    } catch (error) {
      console.error("Error fetching activity:", error);
      res.status(500).json({ message: "Failed to fetch activity" });
    }
  });

  app.post("/api/activities", requireAuth, async (req, res) => {
    try {
      const activity = await storage.createActivity(req.body);
      res.status(201).json(activity);
    } catch (error) {
      console.error("Error creating activity:", error);
      res.status(500).json({ message: "Failed to create activity" });
    }
  });

  app.patch("/api/activities/:id", requireAuth, async (req, res) => {
    try {
      const activity = await storage.updateActivity(parseInt(req.params.id), req.body);
      res.json(activity);
    } catch (error) {
      console.error("Error updating activity:", error);
      res.status(500).json({ message: "Failed to update activity" });
    }
  });

  app.delete("/api/activities/:id", requireAuth, async (req, res) => {
    try {
      await storage.deleteActivity(parseInt(req.params.id));
      res.status(204).send();
    } catch (error) {
      console.error("Error deleting activity:", error);
      res.status(500).json({ message: "Failed to delete activity" });
    }
  });

  app.post("/api/activities/:id/copy", requireAuth, async (req, res) => {
    try {
      const { newDate } = req.body;
      const copiedActivity = await storage.copyActivity(parseInt(req.params.id), new Date(newDate));
      res.status(201).json(copiedActivity);
    } catch (error) {
      console.error("Error copying activity:", error);
      res.status(500).json({ message: "Failed to copy activity" });
    }
  });

  // Activity attendance routes
  app.get("/api/activities/:id/attendance", requireAuth, async (req, res) => {
    try {
      const attendance = await storage.getActivityAttendance(parseInt(req.params.id));
      res.json(attendance);
    } catch (error) {
      console.error("Error fetching activity attendance:", error);
      res.status(500).json({ message: "Failed to fetch activity attendance" });
    }
  });

  app.patch("/api/activity-attendance/:id", requireAuth, async (req, res) => {
    try {
      const attendance = await storage.updateAttendance(parseInt(req.params.id), req.body);
      res.json(attendance);
    } catch (error) {
      console.error("Error updating attendance:", error);
      res.status(500).json({ message: "Failed to update attendance" });
    }
  });

  app.post("/api/activity-attendance", requireAuth, async (req, res) => {
    try {
      const attendance = await storage.createActivityAttendance(req.body);
      res.status(201).json(attendance);
    } catch (error) {
      console.error("Error creating attendance record:", error);
      res.status(500).json({ message: "Failed to create attendance record" });
    }
  });

  // Department routes
  app.get("/api/departments", requireAuth, async (req, res) => {
    try {
      const departments = await storage.getDepartments();
      res.json(departments);
    } catch (error) {
      console.error("Error fetching departments:", error);
      res.status(500).json({ message: "Failed to fetch departments" });
    }
  });

  app.post("/api/departments", requireAuth, async (req, res) => {
    try {
      const department = await storage.createDepartment(req.body);
      res.status(201).json(department);
    } catch (error) {
      console.error("Error creating department:", error);
      res.status(500).json({ message: "Failed to create department" });
    }
  });

  app.patch("/api/departments/:id", requireAuth, async (req, res) => {
    try {
      const department = await storage.updateDepartment(parseInt(req.params.id), req.body);
      res.json(department);
    } catch (error) {
      console.error("Error updating department:", error);
      res.status(500).json({ message: "Failed to update department" });
    }
  });

  app.delete("/api/departments/:id", requireAuth, async (req, res) => {
    try {
      await storage.deleteDepartment(parseInt(req.params.id));
      res.status(204).send();
    } catch (error) {
      console.error("Error deleting department:", error);
      res.status(500).json({ message: "Failed to delete department" });
    }
  });

  // Roster management routes
  app.get("/api/rosters", async (req, res) => {
    try {
      const rosters = await storage.getRosters();
      res.json(rosters);
    } catch (error) {
      console.error("Error fetching rosters:", error);
      res.status(500).json({ message: "Failed to fetch rosters" });
    }
  });

  app.get("/api/rosters/:id", async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const roster = await storage.getRoster(id);
      if (!roster) {
        return res.status(404).json({ message: "Roster not found" });
      }
      res.json(roster);
    } catch (error) {
      console.error("Error fetching roster:", error);
      res.status(500).json({ message: "Failed to fetch roster" });
    }
  });

  app.get("/api/teams/:teamId/rosters", async (req, res) => {
    try {
      const teamId = parseInt(req.params.teamId);
      const rosters = await storage.getRostersByTeam(teamId);
      res.json(rosters);
    } catch (error) {
      console.error("Error fetching team rosters:", error);
      res.status(500).json({ message: "Failed to fetch team rosters" });
    }
  });

  app.post("/api/rosters", requireAuth, async (req, res) => {
    try {
      const { name, teamId, formation, assignments, substitutes, notes } = req.body;
      
      // Create the main roster
      const roster = await storage.createRoster({
        name,
        teamId,
        formation,
        notes,
        createdBy: req.user?.id,
      });

      // Create assignments
      for (const assignment of assignments || []) {
        await storage.createRosterAssignment({
          rosterId: roster.id,
          playerId: assignment.playerId,
          positionId: assignment.positionId,
          isStarter: assignment.isStarter,
          orderIndex: assignment.orderIndex,
        });
      }

      // Create substitutes
      for (let i = 0; i < (substitutes || []).length; i++) {
        await storage.createRosterSubstitute({
          rosterId: roster.id,
          playerId: substitutes[i],
          orderIndex: i,
        });
      }

      res.status(201).json(roster);
    } catch (error) {
      console.error("Error creating roster:", error);
      res.status(500).json({ message: "Failed to create roster" });
    }
  });

  // Club Communication Routes
  
  // News routes
  app.get("/api/news", requireAuth, async (req, res) => {
    try {
      const news = await storage.getClubNews();
      res.json(news);
    } catch (error) {
      console.error("Error fetching news:", error);
      res.status(500).json({ message: "Failed to fetch news" });
    }
  });

  app.get("/api/news/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const news = await storage.getClubNewsById(id);
      if (!news) {
        return res.status(404).json({ message: "News not found" });
      }
      res.json(news);
    } catch (error) {
      console.error("Error fetching news:", error);
      res.status(500).json({ message: "Failed to fetch news" });
    }
  });

  app.post("/api/news", requireAuth, async (req, res) => {
    try {
      const newsData = insertClubNewsSchema.parse(req.body);
      const news = await storage.createClubNews(newsData);
      res.status(201).json(news);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid news data", errors: error.errors });
      }
      console.error("Error creating news:", error);
      res.status(500).json({ message: "Failed to create news" });
    }
  });

  app.put("/api/news/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const newsData = insertClubNewsSchema.partial().parse(req.body);
      const news = await storage.updateClubNews(id, newsData);
      res.json(news);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid news data", errors: error.errors });
      }
      console.error("Error updating news:", error);
      res.status(500).json({ message: "Failed to update news" });
    }
  });

  app.delete("/api/news/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteClubNews(id);
      res.json({ message: "News deleted successfully" });
    } catch (error) {
      console.error("Error deleting news:", error);
      res.status(500).json({ message: "Failed to delete news" });
    }
  });

  // Banners routes
  app.get("/api/banners", requireAuth, async (req, res) => {
    try {
      const banners = await storage.getClubBanners();
      res.json(banners);
    } catch (error) {
      console.error("Error fetching banners:", error);
      res.status(500).json({ message: "Failed to fetch banners" });
    }
  });

  app.get("/api/banners/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const banner = await storage.getClubBannerById(id);
      if (!banner) {
        return res.status(404).json({ message: "Banner not found" });
      }
      res.json(banner);
    } catch (error) {
      console.error("Error fetching banner:", error);
      res.status(500).json({ message: "Failed to fetch banner" });
    }
  });

  app.post("/api/banners", requireAuth, async (req, res) => {
    try {
      const bannerData = insertClubBannerSchema.parse(req.body);
      const banner = await storage.createClubBanner(bannerData);
      res.status(201).json(banner);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid banner data", errors: error.errors });
      }
      console.error("Error creating banner:", error);
      res.status(500).json({ message: "Failed to create banner" });
    }
  });

  app.put("/api/banners/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const bannerData = insertClubBannerSchema.partial().parse(req.body);
      const banner = await storage.updateClubBanner(id, bannerData);
      res.json(banner);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid banner data", errors: error.errors });
      }
      console.error("Error updating banner:", error);
      res.status(500).json({ message: "Failed to update banner" });
    }
  });

  app.delete("/api/banners/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteClubBanner(id);
      res.json({ message: "Banner deleted successfully" });
    } catch (error) {
      console.error("Error deleting banner:", error);
      res.status(500).json({ message: "Failed to delete banner" });
    }
  });

  // Club Terms routes
  app.get("/api/club-terms", requireAuth, async (req, res) => {
    try {
      const terms = await storage.getClubTerms();
      res.json(terms);
    } catch (error) {
      console.error("Error fetching club terms:", error);
      res.status(500).json({ message: "Failed to fetch club terms" });
    }
  });

  app.get("/api/club-terms/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const terms = await storage.getClubTermsById(id);
      if (!terms) {
        return res.status(404).json({ message: "Club terms not found" });
      }
      res.json(terms);
    } catch (error) {
      console.error("Error fetching club terms:", error);
      res.status(500).json({ message: "Failed to fetch club terms" });
    }
  });

  app.post("/api/club-terms", requireAuth, async (req, res) => {
    try {
      const termsData = insertClubTermsSchema.parse(req.body);
      const terms = await storage.createClubTerms(termsData);
      res.status(201).json(terms);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid club terms data", errors: error.errors });
      }
      console.error("Error creating club terms:", error);
      res.status(500).json({ message: "Failed to create club terms" });
    }
  });

  app.put("/api/club-terms/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const termsData = insertClubTermsSchema.partial().parse(req.body);
      const terms = await storage.updateClubTerms(id, termsData);
      res.json(terms);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid club terms data", errors: error.errors });
      }
      console.error("Error updating club terms:", error);
      res.status(500).json({ message: "Failed to update club terms" });
    }
  });

  app.delete("/api/club-terms/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteClubTerms(id);
      res.json({ message: "Club terms deleted successfully" });
    } catch (error) {
      console.error("Error deleting club terms:", error);
      res.status(500).json({ message: "Failed to delete club terms" });
    }
  });

  // Member compliance routes
  app.get("/api/members/:id/compliance", requireAuth, async (req, res) => {
    try {
      const memberId = parseInt(req.params.id);
      const compliance = await storage.checkMemberCompliance(memberId.toString());
      res.json(compliance);
    } catch (error) {
      console.error("Error fetching member compliance:", error);
      res.status(500).json({ message: "Failed to fetch member compliance" });
    }
  });

  app.post("/api/terms-agreements", requireAuth, async (req, res) => {
    try {
      const agreementData = insertMemberTermsAgreementSchema.parse(req.body);
      const agreement = await storage.createMemberTermsAgreement(agreementData);
      res.status(201).json(agreement);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid agreement data", errors: error.errors });
      }
      console.error("Error creating terms agreement:", error);
      res.status(500).json({ message: "Failed to create terms agreement" });
    }
  });

  app.put("/api/rosters/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const { name, formation, notes, isActive } = req.body;
      
      const updatedRoster = await storage.updateRoster(id, {
        name,
        formation,
        notes,
        isActive,
      });
      
      res.json(updatedRoster);
    } catch (error) {
      console.error("Error updating roster:", error);
      res.status(500).json({ message: "Failed to update roster" });
    }
  });

  app.delete("/api/rosters/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteRoster(id);
      res.sendStatus(204);
    } catch (error) {
      console.error("Error deleting roster:", error);
      res.status(500).json({ message: "Failed to delete roster" });
    }
  });

  // Roster assignments routes
  app.get("/api/rosters/:rosterId/assignments", async (req, res) => {
    try {
      const rosterId = parseInt(req.params.rosterId);
      const assignments = await storage.getRosterAssignments(rosterId);
      res.json(assignments);
    } catch (error) {
      console.error("Error fetching roster assignments:", error);
      res.status(500).json({ message: "Failed to fetch roster assignments" });
    }
  });

  app.get("/api/rosters/:rosterId/substitutes", async (req, res) => {
    try {
      const rosterId = parseInt(req.params.rosterId);
      const substitutes = await storage.getRosterSubstitutes(rosterId);
      res.json(substitutes);
    } catch (error) {
      console.error("Error fetching roster substitutes:", error);
      res.status(500).json({ message: "Failed to fetch roster substitutes" });
    }
  });

  // Onboarding completion route
  app.post("/api/onboarding/complete", requireAuth, async (req, res) => {
    try {
      const { clubInfo, preferences, initialData } = req.body;
      
      // Store onboarding preferences (in a real app, you'd store this in a settings table)
      console.log("Onboarding completed with preferences:", preferences);
      
      // Optionally create sample data if requested
      if (initialData.importSampleData) {
        await createSampleData();
      }
      
      res.json({ message: "Onboarding completed successfully" });
    } catch (error) {
      console.error("Error completing onboarding:", error);
      res.status(500).json({ message: "Failed to complete onboarding" });
    }
  });

  // Enhanced Communication Features API Routes

  // Club Events
  app.get("/api/events", async (req, res) => {
    try {
      const events = await storage.getClubEvents();
      res.json(events);
    } catch (error) {
      console.error("Error fetching events:", error);
      res.status(500).json({ message: "Failed to fetch events" });
    }
  });

  app.get("/api/events/:id", async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const event = await storage.getClubEventById(id);
      if (!event) {
        return res.status(404).json({ message: "Event not found" });
      }
      res.json(event);
    } catch (error) {
      console.error("Error fetching event:", error);
      res.status(500).json({ message: "Failed to fetch event" });
    }
  });

  app.post("/api/events", async (req, res) => {
    try {
      const eventData = insertClubEventSchema.parse(req.body);
      const event = await storage.createClubEvent(eventData);
      res.status(201).json(event);
    } catch (error) {
      console.error("Error creating event:", error);
      res.status(500).json({ message: "Failed to create event" });
    }
  });

  app.put("/api/events/:id", async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const eventData = insertClubEventSchema.partial().parse(req.body);
      const event = await storage.updateClubEvent(id, eventData);
      res.json(event);
    } catch (error) {
      console.error("Error updating event:", error);
      res.status(500).json({ message: "Failed to update event" });
    }
  });

  app.delete("/api/events/:id", async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteClubEvent(id);
      res.json({ message: "Event deleted successfully" });
    } catch (error) {
      console.error("Error deleting event:", error);
      res.status(500).json({ message: "Failed to delete event" });
    }
  });

  // Event Registration
  app.get("/api/events/attendees", async (req, res) => {
    try {
      const events = await storage.getClubEvents();
      const attendeeData: Record<number, any[]> = {};
      
      for (const event of events) {
        const attendees = await storage.getEventAttendees(event.id);
        attendeeData[event.id] = attendees;
      }
      
      res.json(attendeeData);
    } catch (error) {
      console.error("Error fetching event attendees:", error);
      res.status(500).json({ message: "Failed to fetch event attendees" });
    }
  });

  app.post("/api/events/register", async (req, res) => {
    try {
      const { eventId, userId } = req.body;
      const attendee = await storage.registerForEvent({
        eventId,
        userId,
        status: "registered"
      });
      res.status(201).json(attendee);
    } catch (error) {
      console.error("Error registering for event:", error);
      res.status(500).json({ message: "Failed to register for event" });
    }
  });

  app.delete("/api/events/:eventId/unregister", async (req, res) => {
    try {
      const eventId = parseInt(req.params.eventId);
      const { userId } = req.body;
      await storage.unregisterFromEvent(eventId, userId);
      res.json({ message: "Successfully unregistered from event" });
    } catch (error) {
      console.error("Error unregistering from event:", error);
      res.status(500).json({ message: "Failed to unregister from event" });
    }
  });

  // Newsletter Templates
  app.get("/api/newsletter-templates", async (req, res) => {
    try {
      const templates = await storage.getNewsletterTemplates();
      res.json(templates);
    } catch (error) {
      console.error("Error fetching newsletter templates:", error);
      res.status(500).json({ message: "Failed to fetch newsletter templates" });
    }
  });

  app.post("/api/newsletter-templates", async (req, res) => {
    try {
      const templateData = insertNewsletterTemplateSchema.parse(req.body);
      const template = await storage.createNewsletterTemplate(templateData);
      res.status(201).json(template);
    } catch (error) {
      console.error("Error creating newsletter template:", error);
      res.status(500).json({ message: "Failed to create newsletter template" });
    }
  });

  app.put("/api/newsletter-templates/:id", async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const templateData = insertNewsletterTemplateSchema.partial().parse(req.body);
      const template = await storage.updateNewsletterTemplate(id, templateData);
      res.json(template);
    } catch (error) {
      console.error("Error updating newsletter template:", error);
      res.status(500).json({ message: "Failed to update newsletter template" });
    }
  });

  app.delete("/api/newsletter-templates/:id", async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteNewsletterTemplate(id);
      res.json({ message: "Newsletter template deleted successfully" });
    } catch (error) {
      console.error("Error deleting newsletter template:", error);
      res.status(500).json({ message: "Failed to delete newsletter template" });
    }
  });

  // News Comments
  app.get("/api/news/:newsId/comments", async (req, res) => {
    try {
      const newsId = parseInt(req.params.newsId);
      const comments = await storage.getNewsComments(newsId);
      res.json(comments);
    } catch (error) {
      console.error("Error fetching news comments:", error);
      res.status(500).json({ message: "Failed to fetch news comments" });
    }
  });

  app.post("/api/news/:newsId/comments", async (req, res) => {
    try {
      const newsId = parseInt(req.params.newsId);
      const commentData = insertNewsCommentSchema.parse({
        ...req.body,
        newsId
      });
      const comment = await storage.createNewsComment(commentData);
      res.status(201).json(comment);
    } catch (error) {
      console.error("Error creating news comment:", error);
      res.status(500).json({ message: "Failed to create news comment" });
    }
  });

  app.put("/api/news/comments/:id/approve", async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const comment = await storage.approveNewsComment(id);
      res.json(comment);
    } catch (error) {
      console.error("Error approving news comment:", error);
      res.status(500).json({ message: "Failed to approve news comment" });
    }
  });

  app.delete("/api/news/comments/:id", async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteNewsComment(id);
      res.json({ message: "News comment deleted successfully" });
    } catch (error) {
      console.error("Error deleting news comment:", error);
      res.status(500).json({ message: "Failed to delete news comment" });
    }
  });

  // Notification Settings
  app.get("/api/notification-settings/:userId", async (req, res) => {
    try {
      const userId = req.params.userId;
      const settings = await storage.getNotificationSettings(userId);
      res.json(settings || {});
    } catch (error) {
      console.error("Error fetching notification settings:", error);
      res.status(500).json({ message: "Failed to fetch notification settings" });
    }
  });

  app.post("/api/notification-settings", async (req, res) => {
    try {
      const settingsData = insertNotificationSettingsSchema.parse(req.body);
      const settings = await storage.createNotificationSettings(settingsData);
      res.status(201).json(settings);
    } catch (error) {
      console.error("Error creating notification settings:", error);
      res.status(500).json({ message: "Failed to create notification settings" });
    }
  });

  app.put("/api/notification-settings/:userId", async (req, res) => {
    try {
      const userId = req.params.userId;
      const settingsData = insertNotificationSettingsSchema.partial().parse(req.body);
      const settings = await storage.updateNotificationSettings(userId, settingsData);
      res.json(settings);
    } catch (error) {
      console.error("Error updating notification settings:", error);
      res.status(500).json({ message: "Failed to update notification settings" });
    }
  });

  // Communication Analytics
  app.post("/api/analytics/communication", async (req, res) => {
    try {
      const analyticsData = insertCommunicationAnalyticsSchema.parse(req.body);
      const analytics = await storage.logCommunicationAnalytics(analyticsData);
      res.status(201).json(analytics);
    } catch (error) {
      console.error("Error logging communication analytics:", error);
      res.status(500).json({ message: "Failed to log communication analytics" });
    }
  });

  app.get("/api/analytics/communication/:contentType/:contentId", async (req, res) => {
    try {
      const { contentType, contentId } = req.params;
      const analytics = await storage.getCommunicationAnalytics(contentType, parseInt(contentId));
      res.json(analytics);
    } catch (error) {
      console.error("Error fetching communication analytics:", error);
      res.status(500).json({ message: "Failed to fetch communication analytics" });
    }
  });

  // Removed gamification features














  // Quick Reaction Coaching Feedback System API Routes

  // Coaching Feedback Reactions
  app.get("/api/coaching-reactions", requireAuth, async (req, res) => {
    try {
      const { active } = req.query;
      let reactions;
      
      if (active === "true") {
        reactions = await storage.getActiveCoachingFeedbackReactions();
      } else {
        reactions = await storage.getCoachingFeedbackReactions();
      }
      
      res.json(reactions);
    } catch (error) {
      console.error("Error fetching coaching reactions:", error);
      res.status(500).json({ message: "Failed to fetch coaching reactions" });
    }
  });

  app.post("/api/coaching-reactions", requireAuth, async (req, res) => {
    try {
      const reactionData = insertCoachingFeedbackReactionSchema.parse(req.body);
      const reaction = await storage.createCoachingFeedbackReaction(reactionData);
      res.status(201).json(reaction);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid reaction data", errors: error.errors });
      }
      console.error("Error creating coaching reaction:", error);
      res.status(500).json({ message: "Failed to create coaching reaction" });
    }
  });

  app.put("/api/coaching-reactions/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const reactionData = insertCoachingFeedbackReactionSchema.partial().parse(req.body);
      const reaction = await storage.updateCoachingFeedbackReaction(id, reactionData);
      res.json(reaction);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid reaction data", errors: error.errors });
      }
      console.error("Error updating coaching reaction:", error);
      res.status(500).json({ message: "Failed to update coaching reaction" });
    }
  });

  app.delete("/api/coaching-reactions/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      await storage.deleteCoachingFeedbackReaction(id);
      res.json({ message: "Coaching reaction deleted successfully" });
    } catch (error) {
      console.error("Error deleting coaching reaction:", error);
      res.status(500).json({ message: "Failed to delete coaching reaction" });
    }
  });

  // Player Feedback Logs
  app.get("/api/players/:playerId/feedback", requireAuth, async (req, res) => {
    try {
      const playerId = parseInt(req.params.playerId);
      const feedbackLogs = await storage.getPlayerFeedbackLogs(playerId);
      res.json(feedbackLogs);
    } catch (error) {
      console.error("Error fetching player feedback:", error);
      res.status(500).json({ message: "Failed to fetch player feedback" });
    }
  });

  app.get("/api/coaches/:coachId/feedback", requireAuth, async (req, res) => {
    try {
      const coachId = req.params.coachId;
      const feedbackLogs = await storage.getCoachFeedbackLogs(coachId);
      res.json(feedbackLogs);
    } catch (error) {
      console.error("Error fetching coach feedback:", error);
      res.status(500).json({ message: "Failed to fetch coach feedback" });
    }
  });

  app.get("/api/sessions/:sessionId/feedback", requireAuth, async (req, res) => {
    try {
      const sessionId = parseInt(req.params.sessionId);
      const sessionType = req.query.type as string || 'training';
      const feedbackLogs = await storage.getSessionFeedbackLogs(sessionId, sessionType);
      res.json(feedbackLogs);
    } catch (error) {
      console.error("Error fetching session feedback:", error);
      res.status(500).json({ message: "Failed to fetch session feedback" });
    }
  });

  app.post("/api/feedback-logs", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }
      
      const logData = insertPlayerFeedbackLogSchema.parse({
        ...req.body,
        coachId: userId
      });
      
      const feedbackLog = await storage.createPlayerFeedbackLog(logData);
      res.status(201).json(feedbackLog);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid feedback data", errors: error.errors });
      }
      console.error("Error creating feedback log:", error);
      res.status(500).json({ message: "Failed to create feedback log" });
    }
  });

  app.get("/api/feedback-logs", requireAuth, async (req, res) => {
    try {
      const { startDate, endDate } = req.query;
      
      if (!startDate || !endDate) {
        return res.status(400).json({ message: "Start date and end date are required" });
      }
      
      const start = new Date(startDate as string);
      const end = new Date(endDate as string);
      
      const feedbackLogs = await storage.getFeedbackLogsByDateRange(start, end);
      res.json(feedbackLogs);
    } catch (error) {
      console.error("Error fetching feedback logs:", error);
      res.status(500).json({ message: "Failed to fetch feedback logs" });
    }
  });

  // Feedback Sessions
  app.get("/api/feedback-sessions", requireAuth, async (req, res) => {
    try {
      const { active, coachId } = req.query;
      let sessions;
      
      if (active === "true") {
        sessions = await storage.getActiveFeedbackSessions(coachId as string);
      } else {
        sessions = await storage.getFeedbackSessions();
      }
      
      res.json(sessions);
    } catch (error) {
      console.error("Error fetching feedback sessions:", error);
      res.status(500).json({ message: "Failed to fetch feedback sessions" });
    }
  });

  app.get("/api/feedback-sessions/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const session = await storage.getFeedbackSession(id);
      
      if (!session) {
        return res.status(404).json({ message: "Feedback session not found" });
      }
      
      res.json(session);
    } catch (error) {
      console.error("Error fetching feedback session:", error);
      res.status(500).json({ message: "Failed to fetch feedback session" });
    }
  });

  app.post("/api/feedback-sessions", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }
      
      console.log("Session creation request body:", req.body);
      
      const sessionData = insertFeedbackSessionSchema.parse({
        ...req.body,
        coachId: userId,
        startTime: new Date(req.body.startTime)
      });
      
      console.log("Parsed session data:", sessionData);
      
      const session = await storage.createFeedbackSession(sessionData);
      res.status(201).json(session);
    } catch (error) {
      if (error instanceof z.ZodError) {
        console.error("Validation errors:", error.errors);
        return res.status(400).json({ message: "Invalid session data", errors: error.errors });
      }
      console.error("Error creating feedback session:", error);
      res.status(500).json({ message: "Failed to create feedback session" });
    }
  });

  app.put("/api/feedback-sessions/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const sessionData = insertFeedbackSessionSchema.partial().parse(req.body);
      const session = await storage.updateFeedbackSession(id, sessionData);
      res.json(session);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({ message: "Invalid session data", errors: error.errors });
      }
      console.error("Error updating feedback session:", error);
      res.status(500).json({ message: "Failed to update feedback session" });
    }
  });

  app.post("/api/feedback-sessions/:id/end", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const session = await storage.endFeedbackSession(id);
      res.json(session);
    } catch (error) {
      console.error("Error ending feedback session:", error);
      res.status(500).json({ message: "Failed to end feedback session" });
    }
  });

  app.get("/api/feedback-sessions/:id/stats", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id);
      const stats = await storage.getFeedbackSessionStats(id);
      res.json(stats);
    } catch (error) {
      console.error("Error fetching session stats:", error);
      res.status(500).json({ message: "Failed to fetch session stats" });
    }
  });

  // Subscription Management API Routes

  // Membership Plans
  app.get("/api/membership-plans", async (req, res) => {
    try {
      const plans = await storage.getMembershipPlans();
      res.json(plans);
    } catch (error) {
      console.error("Error fetching membership plans:", error);
      res.status(500).json({ message: "Failed to fetch membership plans" });
    }
  });

  app.get("/api/membership-plans/active", async (req, res) => {
    try {
      const plans = await storage.getActiveMembershipPlans();
      res.json(plans);
    } catch (error) {
      console.error("Error fetching active membership plans:", error);
      res.status(500).json({ message: "Failed to fetch active membership plans" });
    }
  });

  app.get("/api/membership-plans/:id", async (req, res) => {
    try {
      const plan = await storage.getMembershipPlan(parseInt(req.params.id));
      if (!plan) {
        return res.status(404).json({ message: "Membership plan not found" });
      }
      res.json(plan);
    } catch (error) {
      console.error("Error fetching membership plan:", error);
      res.status(500).json({ message: "Failed to fetch membership plan" });
    }
  });

  app.post("/api/membership-plans", requireAuth, async (req, res) => {
    try {
      const planData = insertMembershipPlanSchema.parse(req.body);
      const plan = await storage.createMembershipPlan(planData);
      res.status(201).json(plan);
    } catch (error) {
      console.error("Error creating membership plan:", error);
      res.status(500).json({ message: "Failed to create membership plan" });
    }
  });

  app.put("/api/membership-plans/:id", requireAuth, async (req, res) => {
    try {
      const planData = insertMembershipPlanSchema.partial().parse(req.body);
      const plan = await storage.updateMembershipPlan(parseInt(req.params.id), planData);
      res.json(plan);
    } catch (error) {
      console.error("Error updating membership plan:", error);
      res.status(500).json({ message: "Failed to update membership plan" });
    }
  });

  app.delete("/api/membership-plans/:id", requireAuth, async (req, res) => {
    try {
      await storage.deleteMembershipPlan(parseInt(req.params.id));
      res.status(204).send();
    } catch (error) {
      console.error("Error deleting membership plan:", error);
      res.status(500).json({ message: "Failed to delete membership plan" });
    }
  });

  // Subscriptions
  app.get("/api/subscriptions", requireAuth, async (req, res) => {
    try {
      const subscriptions = await storage.getSubscriptions();
      res.json(subscriptions);
    } catch (error) {
      console.error("Error fetching subscriptions:", error);
      res.status(500).json({ message: "Failed to fetch subscriptions" });
    }
  });

  app.get("/api/subscriptions/user", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const subscription = await storage.getUserSubscription(userId);
      res.json(subscription);
    } catch (error) {
      console.error("Error fetching user subscription:", error);
      res.status(500).json({ message: "Failed to fetch user subscription" });
    }
  });

  app.get("/api/subscriptions/:id", requireAuth, async (req, res) => {
    try {
      const subscription = await storage.getSubscription(parseInt(req.params.id));
      if (!subscription) {
        return res.status(404).json({ message: "Subscription not found" });
      }
      res.json(subscription);
    } catch (error) {
      console.error("Error fetching subscription:", error);
      res.status(500).json({ message: "Failed to fetch subscription" });
    }
  });

  app.post("/api/subscriptions", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const subscriptionData = insertSubscriptionSchema.parse({
        ...req.body,
        userId
      });
      const subscription = await storage.createSubscription(subscriptionData);
      res.status(201).json(subscription);
    } catch (error) {
      console.error("Error creating subscription:", error);
      res.status(500).json({ message: "Failed to create subscription" });
    }
  });

  app.put("/api/subscriptions/:id", requireAuth, async (req, res) => {
    try {
      const subscriptionData = insertSubscriptionSchema.partial().parse(req.body);
      const subscription = await storage.updateSubscription(parseInt(req.params.id), subscriptionData);
      res.json(subscription);
    } catch (error) {
      console.error("Error updating subscription:", error);
      res.status(500).json({ message: "Failed to update subscription" });
    }
  });

  app.post("/api/subscriptions/:id/cancel", requireAuth, async (req, res) => {
    try {
      const { reason } = req.body;
      const subscription = await storage.cancelSubscription(parseInt(req.params.id), reason);
      res.json(subscription);
    } catch (error) {
      console.error("Error cancelling subscription:", error);
      res.status(500).json({ message: "Failed to cancel subscription" });
    }
  });

  app.post("/api/subscriptions/:id/suspend", requireAuth, async (req, res) => {
    try {
      const { reason } = req.body;
      if (!reason) {
        return res.status(400).json({ message: "Reason is required for suspension" });
      }
      const subscription = await storage.suspendSubscription(parseInt(req.params.id), reason);
      res.json(subscription);
    } catch (error) {
      console.error("Error suspending subscription:", error);
      res.status(500).json({ message: "Failed to suspend subscription" });
    }
  });

  app.post("/api/subscriptions/:id/reactivate", requireAuth, async (req, res) => {
    try {
      const subscription = await storage.reactivateSubscription(parseInt(req.params.id));
      res.json(subscription);
    } catch (error) {
      console.error("Error reactivating subscription:", error);
      res.status(500).json({ message: "Failed to reactivate subscription" });
    }
  });

  app.get("/api/subscriptions/expiring/:days", requireAuth, async (req, res) => {
    try {
      const days = parseInt(req.params.days);
      const subscriptions = await storage.getExpiringSubscriptions(days);
      res.json(subscriptions);
    } catch (error) {
      console.error("Error fetching expiring subscriptions:", error);
      res.status(500).json({ message: "Failed to fetch expiring subscriptions" });
    }
  });

  app.get("/api/subscriptions/overdue", requireAuth, async (req, res) => {
    try {
      const subscriptions = await storage.getOverdueSubscriptions();
      res.json(subscriptions);
    } catch (error) {
      console.error("Error fetching overdue subscriptions:", error);
      res.status(500).json({ message: "Failed to fetch overdue subscriptions" });
    }
  });

  // Payments
  app.get("/api/payments", requireAuth, async (req, res) => {
    try {
      const payments = await storage.getPayments();
      res.json(payments);
    } catch (error) {
      console.error("Error fetching payments:", error);
      res.status(500).json({ message: "Failed to fetch payments" });
    }
  });

  app.get("/api/payments/user", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const payments = await storage.getUserPayments(userId);
      res.json(payments);
    } catch (error) {
      console.error("Error fetching user payments:", error);
      res.status(500).json({ message: "Failed to fetch user payments" });
    }
  });

  app.get("/api/payments/subscription/:subscriptionId", requireAuth, async (req, res) => {
    try {
      const payments = await storage.getSubscriptionPayments(parseInt(req.params.subscriptionId));
      res.json(payments);
    } catch (error) {
      console.error("Error fetching subscription payments:", error);
      res.status(500).json({ message: "Failed to fetch subscription payments" });
    }
  });

  app.get("/api/payments/:id", requireAuth, async (req, res) => {
    try {
      const payment = await storage.getPayment(parseInt(req.params.id));
      if (!payment) {
        return res.status(404).json({ message: "Payment not found" });
      }
      res.json(payment);
    } catch (error) {
      console.error("Error fetching payment:", error);
      res.status(500).json({ message: "Failed to fetch payment" });
    }
  });

  app.post("/api/payments", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const paymentData = insertPaymentSchema.parse({
        ...req.body,
        userId
      });
      const payment = await storage.createPayment(paymentData);
      res.status(201).json(payment);
    } catch (error) {
      console.error("Error creating payment:", error);
      res.status(500).json({ message: "Failed to create payment" });
    }
  });

  app.put("/api/payments/:id", requireAuth, async (req, res) => {
    try {
      const paymentData = insertPaymentSchema.partial().parse(req.body);
      const payment = await storage.updatePayment(parseInt(req.params.id), paymentData);
      res.json(payment);
    } catch (error) {
      console.error("Error updating payment:", error);
      res.status(500).json({ message: "Failed to update payment" });
    }
  });

  app.post("/api/payments/:id/complete", requireAuth, async (req, res) => {
    try {
      const { paidAt, stripeData } = req.body;
      const payment = await storage.markPaymentCompleted(
        parseInt(req.params.id),
        new Date(paidAt || Date.now()),
        stripeData
      );
      res.json(payment);
    } catch (error) {
      console.error("Error completing payment:", error);
      res.status(500).json({ message: "Failed to complete payment" });
    }
  });

  app.post("/api/payments/:id/fail", requireAuth, async (req, res) => {
    try {
      const { reason } = req.body;
      if (!reason) {
        return res.status(400).json({ message: "Reason is required for payment failure" });
      }
      const payment = await storage.markPaymentFailed(parseInt(req.params.id), reason);
      res.json(payment);
    } catch (error) {
      console.error("Error marking payment as failed:", error);
      res.status(500).json({ message: "Failed to mark payment as failed" });
    }
  });

  app.post("/api/payments/:id/refund", requireAuth, async (req, res) => {
    try {
      const { amount, reason } = req.body;
      if (!amount || !reason) {
        return res.status(400).json({ message: "Amount and reason are required for refund" });
      }
      const payment = await storage.processRefund(parseInt(req.params.id), amount, reason);
      res.json(payment);
    } catch (error) {
      console.error("Error processing refund:", error);
      res.status(500).json({ message: "Failed to process refund" });
    }
  });

  // Payment Activities
  app.get("/api/payment-activities", requireAuth, async (req, res) => {
    try {
      const activities = await storage.getPaymentActivities();
      res.json(activities);
    } catch (error) {
      console.error("Error fetching payment activities:", error);
      res.status(500).json({ message: "Failed to fetch payment activities" });
    }
  });

  app.get("/api/payment-activities/subscription/:subscriptionId", requireAuth, async (req, res) => {
    try {
      const activities = await storage.getSubscriptionPaymentActivities(parseInt(req.params.subscriptionId));
      res.json(activities);
    } catch (error) {
      console.error("Error fetching subscription payment activities:", error);
      res.status(500).json({ message: "Failed to fetch subscription payment activities" });
    }
  });

  app.post("/api/payment-activities", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const activityData = insertPaymentActivitySchema.parse({
        ...req.body,
        userId
      });
      const activity = await storage.createPaymentActivity(activityData);
      res.status(201).json(activity);
    } catch (error) {
      console.error("Error creating payment activity:", error);
      res.status(500).json({ message: "Failed to create payment activity" });
    }
  });

  app.post("/api/payment-activities/schedule", requireAuth, async (req, res) => {
    try {
      const { subscriptionId, amount, scheduledDate } = req.body;
      if (!subscriptionId || !amount || !scheduledDate) {
        return res.status(400).json({ message: "Subscription ID, amount, and scheduled date are required" });
      }
      
      const activity = await storage.scheduleAutomaticPayment(
        subscriptionId,
        amount,
        new Date(scheduledDate)
      );
      res.status(201).json(activity);
    } catch (error) {
      console.error("Error scheduling automatic payment:", error);
      res.status(500).json({ message: "Failed to schedule automatic payment" });
    }
  });

  app.post("/api/payment-activities/process-scheduled", requireAuth, async (req, res) => {
    try {
      const activities = await storage.processScheduledPayments();
      res.json(activities);
    } catch (error) {
      console.error("Error processing scheduled payments:", error);
      res.status(500).json({ message: "Failed to process scheduled payments" });
    }
  });

  // Payment Reminders
  app.get("/api/payment-reminders", requireAuth, async (req, res) => {
    try {
      const reminders = await storage.getPaymentReminders();
      res.json(reminders);
    } catch (error) {
      console.error("Error fetching payment reminders:", error);
      res.status(500).json({ message: "Failed to fetch payment reminders" });
    }
  });

  app.get("/api/payment-reminders/user", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const reminders = await storage.getUserPaymentReminders(userId);
      res.json(reminders);
    } catch (error) {
      console.error("Error fetching user payment reminders:", error);
      res.status(500).json({ message: "Failed to fetch user payment reminders" });
    }
  });

  app.post("/api/payment-reminders", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const reminderData = insertPaymentReminderSchema.parse({
        ...req.body,
        userId
      });
      const reminder = await storage.createPaymentReminder(reminderData);
      res.status(201).json(reminder);
    } catch (error) {
      console.error("Error creating payment reminder:", error);
      res.status(500).json({ message: "Failed to create payment reminder" });
    }
  });

  app.post("/api/payment-reminders/:subscriptionId/schedule", requireAuth, async (req, res) => {
    try {
      const reminders = await storage.schedulePaymentReminders(parseInt(req.params.subscriptionId));
      res.status(201).json(reminders);
    } catch (error) {
      console.error("Error scheduling payment reminders:", error);
      res.status(500).json({ message: "Failed to schedule payment reminders" });
    }
  });

  app.get("/api/payment-reminders/pending", requireAuth, async (req, res) => {
    try {
      const reminders = await storage.getPendingReminders();
      res.json(reminders);
    } catch (error) {
      console.error("Error fetching pending reminders:", error);
      res.status(500).json({ message: "Failed to fetch pending reminders" });
    }
  });

  // Subscription Events
  app.get("/api/subscription-events/:subscriptionId", requireAuth, async (req, res) => {
    try {
      const events = await storage.getSubscriptionEvents(parseInt(req.params.subscriptionId));
      res.json(events);
    } catch (error) {
      console.error("Error fetching subscription events:", error);
      res.status(500).json({ message: "Failed to fetch subscription events" });
    }
  });

  app.post("/api/subscription-events", requireAuth, async (req, res) => {
    try {
      const eventData = insertSubscriptionEventSchema.parse(req.body);
      const event = await storage.createSubscriptionEvent(eventData);
      res.status(201).json(event);
    } catch (error) {
      console.error("Error creating subscription event:", error);
      res.status(500).json({ message: "Failed to create subscription event" });
    }
  });

  // Payment Notification Settings
  app.get("/api/payment-settings", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const settings = await storage.getUserPaymentSettings(userId);
      res.json(settings || {});
    } catch (error) {
      console.error("Error fetching payment settings:", error);
      res.status(500).json({ message: "Failed to fetch payment settings" });
    }
  });

  app.post("/api/payment-settings", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const settingsData = insertPaymentNotificationSettingsSchema.parse({
        ...req.body,
        userId
      });
      const settings = await storage.createPaymentSettings(settingsData);
      res.status(201).json(settings);
    } catch (error) {
      console.error("Error creating payment settings:", error);
      res.status(500).json({ message: "Failed to create payment settings" });
    }
  });

  app.put("/api/payment-settings", requireAuth, async (req, res) => {
    try {
      const userId = req.user?.id;
      if (!userId) {
        return res.status(401).json({ message: "User not authenticated" });
      }

      const settingsData = insertPaymentNotificationSettingsSchema.partial().parse(req.body);
      const settings = await storage.updatePaymentSettings(userId, settingsData);
      res.json(settings);
    } catch (error) {
      console.error("Error updating payment settings:", error);
      res.status(500).json({ message: "Failed to update payment settings" });
    }
  });

  // Subscription Analytics
  app.get("/api/subscription-stats", requireAuth, async (req, res) => {
    try {
      const stats = await storage.getSubscriptionStats();
      res.json(stats);
    } catch (error) {
      console.error("Error fetching subscription stats:", error);
      res.status(500).json({ message: "Failed to fetch subscription stats" });
    }
  });

  // Automated Tasks
  app.post("/api/subscriptions/process-overdue", requireAuth, async (req, res) => {
    try {
      await storage.processOverduePayments();
      res.json({ message: "Overdue payments processed successfully" });
    } catch (error) {
      console.error("Error processing overdue payments:", error);
      res.status(500).json({ message: "Failed to process overdue payments" });
    }
  });

  app.post("/api/subscriptions/send-reminders", requireAuth, async (req, res) => {
    try {
      await storage.sendPaymentReminders();
      res.json({ message: "Payment reminders sent successfully" });
    } catch (error) {
      console.error("Error sending payment reminders:", error);
      res.status(500).json({ message: "Failed to send payment reminders" });
    }
  });

  app.post("/api/subscriptions/suspend-overdue", requireAuth, async (req, res) => {
    try {
      await storage.suspendOverdueAccounts();
      res.json({ message: "Overdue accounts suspended successfully" });
    } catch (error) {
      console.error("Error suspending overdue accounts:", error);
      res.status(500).json({ message: "Failed to suspend overdue accounts" });
    }
  });

  app.post("/api/subscriptions/process-trial-expirations", requireAuth, async (req, res) => {
    try {
      await storage.processTrialExpirations();
      res.json({ message: "Trial expirations processed successfully" });
    } catch (error) {
      console.error("Error processing trial expirations:", error);
      res.status(500).json({ message: "Failed to process trial expirations" });
    }
  });

  // Middleware to check superadmin role
  const requireSuperAdmin = (req: any, res: any, next: any) => {
    if (!req.isAuthenticated()) {
      return res.status(401).json({ message: "Not authenticated" });
    }
    if (req.user.role !== 'superadmin') {
      return res.status(403).json({ message: "Superadmin access required" });
    }
    next();
  };

  // Superadmin organization management routes
  app.get("/api/superadmin/organizations", requireSuperAdmin, async (req, res) => {
    try {
      const result = await storage.getAllOrganizations();
      res.json(result);
    } catch (error: any) {
      console.error("Error fetching organizations:", error);
      res.status(500).json({ message: error.message });
    }
  });

  app.get("/api/superadmin/modules", requireSuperAdmin, async (req, res) => {
    try {
      const result = await storage.getAllModules();
      res.json(result);
    } catch (error: any) {
      console.error("Error fetching modules:", error);
      res.status(500).json({ message: error.message });
    }
  });

  app.get("/api/superadmin/plans", requireSuperAdmin, async (req, res) => {
    try {
      const result = await storage.getAllSubscriptionPlans();
      res.json(result);
    } catch (error: any) {
      console.error("Error fetching plans:", error);
      res.status(500).json({ message: error.message });
    }
  });

  app.get("/api/superadmin/organizations/:id/modules", requireSuperAdmin, async (req, res) => {
    try {
      const orgId = parseInt(req.params.id);
      const permissions = await storage.getOrganizationModulePermissions(orgId);
      res.json(permissions);
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  });

  app.put("/api/superadmin/organizations/:id/subscription", requireSuperAdmin, async (req, res) => {
    try {
      const orgId = parseInt(req.params.id);
      const updateData = req.body;
      const organization = await storage.updateOrganizationSubscription(orgId, updateData);
      res.json(organization);
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  });

  app.put("/api/superadmin/organizations/:orgId/modules/:moduleId", requireSuperAdmin, async (req, res) => {
    try {
      const orgId = parseInt(req.params.orgId);
      const moduleId = parseInt(req.params.moduleId);
      const { enabled } = req.body;
      const userId = req.user.id;
      
      const permission = await storage.updateOrganizationModulePermission(orgId, moduleId, enabled, userId);
      res.json(permission);
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  });

  app.post("/api/superadmin/modules", requireSuperAdmin, async (req, res) => {
    try {
      const moduleData = insertModuleSchema.parse(req.body);
      const module = await storage.createModule(moduleData);
      res.status(201).json(module);
    } catch (error: any) {
      res.status(400).json({ message: error.message });
    }
  });

  app.post("/api/superadmin/organizations", requireSuperAdmin, async (req, res) => {
    try {
      const orgData = insertOrganizationSchema.parse(req.body);
      const organization = await storage.createOrganization(orgData);
      res.status(201).json(organization);
    } catch (error: any) {
      res.status(400).json({ message: error.message });
    }
  });



  // Admin user management routes
  app.get("/api/admin/users", requireAuth, async (req, res) => {
    try {
      // Debug logging
      console.log('Admin users request - User role:', req.user?.role);
      console.log('Admin users request - User ID:', req.user?.id);
      
      // Check if user is admin
      if (req.user.role !== 'admin' && req.user.role !== 'super_admin' && req.user.role !== 'superadmin' && req.user.role !== 'org_admin') {
        console.log('Permission denied for role:', req.user.role);
        return res.status(403).json({ message: "Insufficient permissions" });
      }

      const users = await storage.getAllUsersForAdmin();
      res.json(users);
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  });

  app.post("/api/admin/users", requireAuth, async (req, res) => {
    try {
      // Check if user is admin
      if (req.user.role !== 'admin' && req.user.role !== 'super_admin' && req.user.role !== 'superadmin' && req.user.role !== 'org_admin') {
        return res.status(403).json({ message: "Insufficient permissions" });
      }

      const { firstName, lastName, email, password, role, organizationId, teamId, sendEmail = true } = req.body;

      if (!firstName || !lastName || !email) {
        return res.status(400).json({ message: "First name, last name, and email are required" });
      }

      // Check if email already exists
      const existingUser = await storage.getUserByEmail(email);
      if (existingUser) {
        return res.status(400).json({ message: "User with this email already exists" });
      }

      let generatedPassword = password;
      let userResult;

      // Use the unified createUserWithPassword method
      const result = await storage.createUserWithPassword({
        firstName,
        lastName,
        email,
        password: password, // Pass the password (can be undefined for auto-generation)
        role: role || 'player',
        organizationId,
        teamId
      });
      userResult = result.user;
      generatedPassword = result.password;

      // Send welcome email if requested
      if (sendEmail) {
        const { sendWelcomeEmail } = await import('./email');
        const emailSent = await sendWelcomeEmail({
          to: email,
          firstName,
          lastName,
          username: userResult.username!,
          password: generatedPassword,
          organizationName: organizationId ? `Organization ${organizationId}` : undefined
        });

        if (!emailSent && process.env.SENDGRID_API_KEY) {
          console.warn(`Failed to send welcome email to ${email}`);
        }
      }

      // Return user data without password
      const { password: _, ...userResponse } = userResult;
      res.status(201).json({
        user: userResponse,
        password: sendEmail ? undefined : generatedPassword, // Only return password if email wasn't sent
        emailSent: sendEmail && !!process.env.SENDGRID_API_KEY
      });
    } catch (error: any) {
      console.error("Admin user creation error:", error);
      res.status(500).json({ message: error.message });
    }
  });

  app.post("/api/admin/users/:id/reset-password", requireAuth, async (req, res) => {
    try {
      // Check if user is admin
      if (req.user.role !== 'admin' && req.user.role !== 'super_admin' && req.user.role !== 'superadmin' && req.user.role !== 'org_admin') {
        return res.status(403).json({ message: "Insufficient permissions" });
      }

      const userId = req.params.id;
      const { sendEmail = true } = req.body;

      const user = await storage.getUser(userId);
      if (!user) {
        return res.status(404).json({ message: "User not found" });
      }

      const newPassword = await storage.resetUserPassword(userId);

      // Send password reset email if requested
      if (sendEmail && user.email) {
        const { sendPasswordResetEmail } = await import('./email');
        const emailSent = await sendPasswordResetEmail(
          user.email,
          user.firstName,
          newPassword
        );

        if (!emailSent && process.env.SENDGRID_API_KEY) {
          console.warn(`Failed to send password reset email to ${user.email}`);
        }
      }

      res.json({
        message: "Password reset successfully",
        password: sendEmail ? undefined : newPassword, // Only return password if email wasn't sent
        emailSent: sendEmail && !!process.env.SENDGRID_API_KEY
      });
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  });

  app.patch("/api/admin/users/:id/status", requireAuth, async (req, res) => {
    try {
      // Check if user is admin
      if (req.user.role !== 'admin' && req.user.role !== 'super_admin' && req.user.role !== 'superadmin' && req.user.role !== 'org_admin') {
        return res.status(403).json({ message: "Insufficient permissions" });
      }

      const userId = req.params.id;
      const { status } = req.body;

      if (!['active', 'inactive', 'suspended'].includes(status)) {
        return res.status(400).json({ message: "Invalid status. Must be active, inactive, or suspended" });
      }

      const updatedUser = await storage.updateUserStatus(userId, status);
      const { password, ...userResponse } = updatedUser;
      
      res.json(userResponse);
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  });

  app.patch("/api/admin/users/:id", requireAuth, async (req, res) => {
    try {
      // Check if user is admin
      if (req.user.role !== 'admin' && req.user.role !== 'super_admin' && req.user.role !== 'superadmin' && req.user.role !== 'org_admin') {
        return res.status(403).json({ message: "Insufficient permissions" });
      }

      const userId = req.params.id;
      const { firstName, lastName, email, role, status, language, timezone } = req.body;

      // Check if email already exists for another user
      if (email) {
        const existingUser = await storage.getUserByEmail(email);
        if (existingUser && existingUser.id !== userId) {
          return res.status(400).json({ message: "Email already exists for another user" });
        }
      }

      const updatedUser = await storage.updateUser(userId, {
        firstName,
        lastName,
        email,
        role,
        status,
        language,
        timezone
      });

      const { password, ...userResponse } = updatedUser;
      res.json(userResponse);
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  });

  // Password change endpoint
  app.patch("/api/admin/users/:id/change-password", requireAuth, async (req, res) => {
    try {
      // Check if user is admin
      if (req.user?.role !== 'admin' && req.user?.role !== 'super_admin' && req.user?.role !== 'superadmin' && req.user?.role !== 'org_admin') {
        return res.status(403).json({ message: "Insufficient permissions" });
      }

      const userId = req.params.id;
      const { newPassword } = req.body;

      if (!newPassword || newPassword.length < 8) {
        return res.status(400).json({ message: "Password must be at least 8 characters long" });
      }

      // Hash the new password
      const bcrypt = await import('bcrypt');
      const hashedPassword = await bcrypt.hash(newPassword, 10);

      // Update user password
      await storage.updateUserPassword(userId, hashedPassword);
      
      res.json({ message: "Password changed successfully" });
    } catch (error: any) {
      console.error("Error changing password:", error);
      res.status(500).json({ message: "Failed to change password" });
    }
  });



  // Widget Template Routes
  app.get("/api/dashboard/widget-templates", requireAuth, async (req, res) => {
    try {
      const { category } = req.query;
      const templates = category 
        ? await storage.getWidgetTemplatesByCategory(category as string)
        : await storage.getWidgetTemplates();
      res.json(templates);
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  });

  app.post("/api/dashboard/widget-templates", requireAuth, async (req, res) => {
    try {
      const templateData = insertWidgetTemplateSchema.parse(req.body);
      const template = await storage.createWidgetTemplate(templateData);
      res.status(201).json(template);
    } catch (error: any) {
      res.status(400).json({ message: error.message });
    }
  });

  const httpServer = createServer(app);
  return httpServer;
}
