// server/index.ts
import express2 from "express";

// server/routes.ts
import { createServer } from "http";

// server/storage.ts
import { randomUUID } from "crypto";
var MemStorage = class {
  users;
  applications;
  constructor() {
    this.users = /* @__PURE__ */ new Map();
    this.applications = /* @__PURE__ */ new Map();
  }
  async getUser(id) {
    return this.users.get(id);
  }
  async getUserByUsername(username) {
    return Array.from(this.users.values()).find(
      (user) => user.username === username
    );
  }
  async createUser(insertUser) {
    const id = randomUUID();
    const user = { ...insertUser, id };
    this.users.set(id, user);
    return user;
  }
  async createApplication(insertApplication) {
    const id = randomUUID();
    const application = {
      ...insertApplication,
      additionalInfo: insertApplication.additionalInfo ?? null,
      id,
      status: "pending",
      submittedAt: /* @__PURE__ */ new Date()
    };
    this.applications.set(id, application);
    return application;
  }
  async getApplication(id) {
    return this.applications.get(id);
  }
  async getAllApplications() {
    return Array.from(this.applications.values());
  }
  async updateApplicationStatus(id, status) {
    const application = this.applications.get(id);
    if (!application) return void 0;
    const updatedApplication = { ...application, status };
    this.applications.set(id, updatedApplication);
    return updatedApplication;
  }
};
var storage = new MemStorage();

// shared/schema.ts
import { sql } from "drizzle-orm";
import { pgTable, text, varchar, integer, timestamp } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { z } from "zod";
var users = pgTable("users", {
  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
  username: text("username").notNull().unique(),
  password: text("password").notNull()
});
var applications = pgTable("applications", {
  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
  ingameName: text("ingame_name").notNull(),
  discordUsername: text("discord_username").notNull(),
  age: integer("age").notNull(),
  rpExperience: text("rp_experience").notNull(),
  backstory: text("backstory").notNull(),
  additionalInfo: text("additional_info"),
  status: text("status").notNull().default("pending"),
  // pending, approved, denied
  submittedAt: timestamp("submitted_at").defaultNow()
});
var insertUserSchema = createInsertSchema(users).pick({
  username: true,
  password: true
});
var insertApplicationSchema = createInsertSchema(applications).omit({
  id: true,
  status: true,
  submittedAt: true
}).extend({
  age: z.number().min(16).max(99),
  backstory: z.string().min(100),
  rpExperience: z.enum(["beginner", "intermediate", "experienced", "veteran"])
});

// server/discordClient.ts
import { Client, GatewayIntentBits } from "discord.js";
async function sendWebhookMessage(webhookUrl, payload) {
  try {
    const response = await fetch(webhookUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(payload)
    });
    if (!response.ok) {
      throw new Error(`Webhook failed: ${response.status}`);
    }
    return response;
  } catch (error) {
    console.error("Discord webhook error:", error);
    throw error;
  }
}

// server/routes.ts
async function registerRoutes(app2) {
  app2.post("/api/applications", async (req, res) => {
    try {
      const validatedData = insertApplicationSchema.parse(req.body);
      const application = await storage.createApplication(validatedData);
      const webhookUrl = process.env.DISCORD_WEBHOOK_URL;
      if (webhookUrl) {
        const webhookPayload = {
          embeds: [{
            title: "\u{1F3AE} New Whitelist Application",
            color: 9133302,
            // Primary purple color
            fields: [
              { name: "\u{1F4CB} Application ID", value: application.id, inline: false },
              { name: "\u{1F3AF} In-Game Name", value: application.ingameName, inline: true },
              { name: "\u{1F4AC} Discord", value: application.discordUsername, inline: true },
              { name: "\u{1F382} Age", value: application.age.toString(), inline: true },
              { name: "\u{1F3AE} Experience Level", value: application.rpExperience, inline: false },
              { name: "\u{1F4D6} Character Backstory", value: application.backstory.substring(0, 1024), inline: false },
              { name: "\u{1F4DD} Additional Info", value: application.additionalInfo || "None provided", inline: false }
            ],
            timestamp: application.submittedAt?.toISOString() || (/* @__PURE__ */ new Date()).toISOString(),
            footer: {
              text: "FiveM Roleplay Application System",
              icon_url: "https://cdn.discordapp.com/emojis/851461487498493994.webp?size=128&quality=lossless"
            },
            thumbnail: {
              url: "https://cdn.discordapp.com/emojis/851461487498493994.webp?size=128&quality=lossless"
            }
          }],
          components: [{
            type: 1,
            components: [
              {
                type: 2,
                label: "Approve",
                style: 3,
                // Green
                custom_id: `approve_${application.id}`,
                emoji: { name: "\u2705" }
              },
              {
                type: 2,
                label: "Deny",
                style: 4,
                // Red
                custom_id: `deny_${application.id}`,
                emoji: { name: "\u274C" }
              },
              {
                type: 2,
                label: "View Details",
                style: 2,
                // Gray
                custom_id: `details_${application.id}`,
                emoji: { name: "\u{1F4CB}" }
              }
            ]
          }]
        };
        try {
          await sendWebhookMessage(webhookUrl, webhookPayload);
        } catch (error) {
          console.error("Failed to send Discord webhook:", error);
        }
      }
      res.json(application);
    } catch (error) {
      console.error("Application submission error:", error);
      if (error instanceof Error) {
        res.status(400).json({ message: error.message });
      } else {
        res.status(500).json({ message: "Internal server error" });
      }
    }
  });
  app2.get("/api/applications/:id", async (req, res) => {
    try {
      const { id } = req.params;
      const application = await storage.getApplication(id);
      if (!application) {
        return res.status(404).json({ message: "Application not found" });
      }
      res.json(application);
    } catch (error) {
      console.error("Get application error:", error);
      res.status(500).json({ message: "Internal server error" });
    }
  });
  app2.patch("/api/applications/:id/status", async (req, res) => {
    try {
      const { id } = req.params;
      const { status } = req.body;
      if (!["pending", "approved", "denied"].includes(status)) {
        return res.status(400).json({ message: "Invalid status" });
      }
      const application = await storage.updateApplicationStatus(id, status);
      if (!application) {
        return res.status(404).json({ message: "Application not found" });
      }
      res.json(application);
    } catch (error) {
      console.error("Update application status error:", error);
      res.status(500).json({ message: "Internal server error" });
    }
  });
  app2.get("/api/applications", async (req, res) => {
    try {
      const applications2 = await storage.getAllApplications();
      res.json(applications2);
    } catch (error) {
      console.error("Get applications error:", error);
      res.status(500).json({ message: "Internal server error" });
    }
  });
  app2.get("/api/server-status", async (req, res) => {
    try {
      const serverIp = "104.234.180.105:30120";
      const response = await fetch(`http://${serverIp}/dynamic.json`, {
        signal: AbortSignal.timeout(5e3)
      });
      if (!response.ok) {
        return res.json({ online: false, players: 0, maxPlayers: 0 });
      }
      const data = await response.json();
      res.json({
        online: true,
        players: data.clients || 0,
        maxPlayers: data.sv_maxclients || 0,
        hostname: data.hostname || "FiveM Server"
      });
    } catch (error) {
      console.error("FiveM server status error:", error);
      res.json({ online: false, players: 0, maxPlayers: 0 });
    }
  });
  const httpServer = createServer(app2);
  return httpServer;
}

// server/vite.ts
import express from "express";
import fs from "fs";
import path2 from "path";
import { createServer as createViteServer, createLogger } from "vite";

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
import runtimeErrorOverlay from "@replit/vite-plugin-runtime-error-modal";
var vite_config_default = defineConfig({
  plugins: [
    react(),
    runtimeErrorOverlay(),
    ...process.env.NODE_ENV !== "production" && process.env.REPL_ID !== void 0 ? [
      await import("@replit/vite-plugin-cartographer").then(
        (m) => m.cartographer()
      ),
      await import("@replit/vite-plugin-dev-banner").then(
        (m) => m.devBanner()
      )
    ] : []
  ],
  resolve: {
    alias: {
      "@": path.resolve(import.meta.dirname, "client", "src"),
      "@shared": path.resolve(import.meta.dirname, "shared"),
      "@assets": path.resolve(import.meta.dirname, "attached_assets")
    }
  },
  root: path.resolve(import.meta.dirname, "client"),
  build: {
    outDir: path.resolve(import.meta.dirname, "dist/public"),
    emptyOutDir: true
  },
  server: {
    fs: {
      strict: true,
      deny: ["**/.*"]
    }
  }
});

// server/vite.ts
import { nanoid } from "nanoid";
var viteLogger = createLogger();
function log(message, source = "express") {
  const formattedTime = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
    hour: "numeric",
    minute: "2-digit",
    second: "2-digit",
    hour12: true
  });
  console.log(`${formattedTime} [${source}] ${message}`);
}
async function setupVite(app2, server) {
  const serverOptions = {
    middlewareMode: true,
    hmr: { server },
    allowedHosts: true
  };
  const vite = await createViteServer({
    ...vite_config_default,
    configFile: false,
    customLogger: {
      ...viteLogger,
      error: (msg, options) => {
        viteLogger.error(msg, options);
        process.exit(1);
      }
    },
    server: serverOptions,
    appType: "custom"
  });
  app2.use(vite.middlewares);
  app2.use("*", async (req, res, next) => {
    const url = req.originalUrl;
    try {
      const clientTemplate = path2.resolve(
        import.meta.dirname,
        "..",
        "client",
        "index.html"
      );
      let template = await fs.promises.readFile(clientTemplate, "utf-8");
      template = template.replace(
        `src="/src/main.tsx"`,
        `src="/src/main.tsx?v=${nanoid()}"`
      );
      const page = await vite.transformIndexHtml(url, template);
      res.status(200).set({ "Content-Type": "text/html" }).end(page);
    } catch (e) {
      vite.ssrFixStacktrace(e);
      next(e);
    }
  });
}
function serveStatic(app2) {
  const distPath = path2.resolve(import.meta.dirname, "public");
  if (!fs.existsSync(distPath)) {
    throw new Error(
      `Could not find the build directory: ${distPath}, make sure to build the client first`
    );
  }
  app2.use(express.static(distPath));
  app2.use("*", (_req, res) => {
    res.sendFile(path2.resolve(distPath, "index.html"));
  });
}

// server/index.ts
var app = express2();
app.use(express2.json({
  verify: (req, _res, buf) => {
    req.rawBody = buf;
  }
}));
app.use(express2.urlencoded({ extended: false }));
app.use((req, res, next) => {
  const start = Date.now();
  const path3 = req.path;
  let capturedJsonResponse = void 0;
  const originalResJson = res.json;
  res.json = function(bodyJson, ...args) {
    capturedJsonResponse = bodyJson;
    return originalResJson.apply(res, [bodyJson, ...args]);
  };
  res.on("finish", () => {
    const duration = Date.now() - start;
    if (path3.startsWith("/api")) {
      let logLine = `${req.method} ${path3} ${res.statusCode} in ${duration}ms`;
      if (capturedJsonResponse) {
        logLine += ` :: ${JSON.stringify(capturedJsonResponse)}`;
      }
      if (logLine.length > 80) {
        logLine = logLine.slice(0, 79) + "\u2026";
      }
      log(logLine);
    }
  });
  next();
});
(async () => {
  const server = await registerRoutes(app);
  app.use((err, _req, res, _next) => {
    const status = err.status || err.statusCode || 500;
    const message = err.message || "Internal Server Error";
    res.status(status).json({ message });
    throw err;
  });
  if (app.get("env") === "development") {
    await setupVite(app, server);
  } else {
    serveStatic(app);
  }
  const port = parseInt(process.env.PORT || "5000", 10);
  server.listen({
    port,
    host: "0.0.0.0",
    reusePort: true
  }, () => {
    log(`serving on port ${port}`);
  });
})();
