import type { Express, Request, Response, NextFunction } from "express";
import { createServer, type Server } from "http";
import session from "express-session";
import { storage } from "./storage";
import { sendTelegramMessage, sendBulkTelegramMessages } from "./telegram";
import type { RequestStatus } from "@shared/schema";

declare module "express-session" {
  interface SessionData {
    userId?: string;
    username?: string;
  }
}

const ADMIN_USERNAME = process.env.ADMIN_USERNAME || "admin";
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD || "admin123";

function requireAuth(req: Request, res: Response, next: NextFunction) {
  if (req.session?.userId) {
    next();
  } else {
    res.status(401).json({ error: "Unauthorized" });
  }
}

export async function registerRoutes(
  httpServer: Server,
  app: Express
): Promise<Server> {
  app.use(
    session({
      secret: process.env.SESSION_SECRET || "support-panel-secret-key",
      resave: false,
      saveUninitialized: false,
      cookie: {
        secure: process.env.NODE_ENV === "production",
        httpOnly: true,
        maxAge: 24 * 60 * 60 * 1000,
      },
    })
  );

  app.post("/api/auth/login", async (req, res) => {
    try {
      const { username, password } = req.body;

      if (!username || !password) {
        return res.status(400).json({ error: "Username and password are required" });
      }

      if (username === ADMIN_USERNAME && password === ADMIN_PASSWORD) {
        req.session.userId = "1";
        req.session.username = username;
        return res.json({ success: true, username });
      }

      const admin = await storage.getAdmin(username);
      if (admin) {
        req.session.userId = admin.id;
        req.session.username = admin.username;
        return res.json({ success: true, username: admin.username });
      }

      res.status(401).json({ error: "Invalid credentials" });
    } catch (error) {
      console.error("Login error:", error);
      res.status(500).json({ error: "Internal server error" });
    }
  });

  app.get("/api/auth/me", (req, res) => {
    if (req.session?.userId) {
      res.json({ userId: req.session.userId, username: req.session.username });
    } else {
      res.status(401).json({ error: "Not authenticated" });
    }
  });

  app.post("/api/auth/logout", (req, res) => {
    req.session.destroy((err) => {
      if (err) {
        console.error("Logout error:", err);
        return res.status(500).json({ error: "Failed to logout" });
      }
      res.clearCookie("connect.sid");
      res.json({ success: true });
    });
  });

  app.get("/api/stats", requireAuth, async (req, res) => {
    try {
      const stats = await storage.getStats();
      res.json(stats);
    } catch (error) {
      console.error("Stats error:", error);
      res.status(500).json({ error: "Failed to fetch stats" });
    }
  });

  app.get("/api/requests", requireAuth, async (req, res) => {
    try {
      const requests = await storage.getRequests();
      res.json(requests);
    } catch (error) {
      console.error("Requests error:", error);
      res.status(500).json({ error: "Failed to fetch requests" });
    }
  });

  app.get("/api/requests/:id", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id, 10);
      if (isNaN(id)) {
        return res.status(400).json({ error: "Invalid request ID" });
      }

      const request = await storage.getRequestById(id);
      if (!request) {
        return res.status(404).json({ error: "Request not found" });
      }

      res.json(request);
    } catch (error) {
      console.error("Request detail error:", error);
      res.status(500).json({ error: "Failed to fetch request" });
    }
  });

  app.get("/api/requests/:id/messages", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id, 10);
      if (isNaN(id)) {
        return res.status(400).json({ error: "Invalid request ID" });
      }

      const messages = await storage.getRequestMessages(id);
      res.json(messages);
    } catch (error) {
      console.error("Messages error:", error);
      res.status(500).json({ error: "Failed to fetch messages" });
    }
  });

  app.post("/api/requests/:id/reply", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id, 10);
      if (isNaN(id)) {
        return res.status(400).json({ error: "Invalid request ID" });
      }

      const { message } = req.body;
      if (!message || typeof message !== "string") {
        return res.status(400).json({ error: "Message is required" });
      }

      const request = await storage.getRequestById(id);
      if (!request) {
        return res.status(404).json({ error: "Request not found" });
      }

      const sent = await sendTelegramMessage(request.odID, message);

      await storage.addMessage(id, message, true);

      if (request.status === "new") {
        await storage.updateRequestStatus(id, "in_progress");
      }

      res.json({ success: true, sent });
    } catch (error) {
      console.error("Reply error:", error);
      res.status(500).json({ error: "Failed to send reply" });
    }
  });

  app.patch("/api/requests/:id/status", requireAuth, async (req, res) => {
    try {
      const id = parseInt(req.params.id, 10);
      if (isNaN(id)) {
        return res.status(400).json({ error: "Invalid request ID" });
      }

      const { status } = req.body;
      const validStatuses: RequestStatus[] = ["new", "in_progress", "resolved"];
      if (!validStatuses.includes(status)) {
        return res.status(400).json({ error: "Invalid status" });
      }

      await storage.updateRequestStatus(id, status);
      res.json({ success: true });
    } catch (error) {
      console.error("Status update error:", error);
      res.status(500).json({ error: "Failed to update status" });
    }
  });

  app.post("/api/requests/bulk-reply", requireAuth, async (req, res) => {
    try {
      const { message, requestIds } = req.body;

      if (!message || typeof message !== "string") {
        return res.status(400).json({ error: "Message is required" });
      }

      if (!Array.isArray(requestIds) || requestIds.length === 0) {
        return res.status(400).json({ error: "Request IDs are required" });
      }

      const requests = await storage.getRequests();
      const targetRequests = requests.filter((r) => requestIds.includes(r.id));

      if (targetRequests.length === 0) {
        return res.status(404).json({ error: "No valid requests found" });
      }

      const chatIds = [...new Set(targetRequests.map((r) => r.odID))];
      const result = await sendBulkTelegramMessages(chatIds, message);

      for (const request of targetRequests) {
        await storage.addMessage(request.id, message, true);
        if (request.status === "new") {
          await storage.updateRequestStatus(request.id, "in_progress");
        }
      }

      res.json({
        success: true,
        total: chatIds.length,
        sent: result.sent,
        failed: result.failed,
      });
    } catch (error) {
      console.error("Bulk reply error:", error);
      res.status(500).json({ error: "Failed to send bulk reply" });
    }
  });

  app.get("/api/users/:userId/requests", requireAuth, async (req, res) => {
    try {
      const userId = parseInt(req.params.userId, 10);
      if (isNaN(userId)) {
        return res.status(400).json({ error: "Invalid user ID" });
      }

      const requests = await storage.getUserRequests(userId);
      res.json(requests);
    } catch (error) {
      console.error("User requests error:", error);
      res.status(500).json({ error: "Failed to fetch user requests" });
    }
  });

  return httpServer;
}
