// Importar los paquetes necesarios de Express y otros módulos
import express, { Application, urlencoded, json } from "express";
import http from "http";
import { Server, Socket } from "socket.io";
import cors from "cors";
import { RegisterRoutes } from "../build/routes";
import dotenv from "dotenv";
import path from "path";

dotenv.config();

const PORT = process.env.PORT || 3000;

/*
const corsOptions = {
    origin: "*",
    optionsSuccessStatus: 200,
};
*/
const corsOptions = {
    origin: `${process.env.CORS_ALLOWED_ORIGIN}`,
    allowedHeaders: ["Content-Type", "Authorization"],
};

// Crear una nueva instancia de la aplicación de Express
const app: Application = express();

app.use(cors(corsOptions));

const server = http.createServer(app);
const io = new Server(server, {
    cors: {
        origin: "*", // ajustar según necesidad
    },
});

//app.use("/docs", swaggerUi.serve, async (_req: ExRequest, res: ExResponse) => {
//    return res.send(swaggerUi.generateHTML(await import("../build/swagger.json")));
//});

app.use(
    urlencoded({
        extended: true,
    })
);

app.use(json());

app.use((req, _res, next) => {
    if (req.path === '/companies/create') {
        require('fs').writeFileSync('request_log.json', JSON.stringify({ body: req.body, headers: req.headers }, null, 2));
    }
    next();
});

RegisterRoutes(app);

app.use(function errorHandler(
  err: unknown,
  req: express.Request,
  res: express.Response,
  next: express.NextFunction
): express.Response | void {
  if (err instanceof Error && err.name === "ValidateError") {
    console.warn(`Caught Validation Error for ${req.path}:`, (err as any).fields);
    return res.status(422).json({
      message: "Validation Failed",
      details: (err as any)?.fields,
    });
  }
  if (err instanceof Error) {
    console.error("Global Error:", err);
    return res.status(500).json({
      message: "Internal Server Error",
      details: err.message
    });
  }
  next();
});

// Escuchar conexiones
io.on("connection", (socket: Socket) => {
    const userId = socket.handshake.auth.userId as string;

    if (!userId) {
        console.log("Conexión rechazada: no se proporcionó userId");
        socket.disconnect();
        return;
    }

    console.log(`Usuario ${userId} conectado con socket ${socket.id}`);

    socket.join(`user:${userId}`);

    socket.on("disconnect", () => {
        console.log(`Usuario ${userId} desconectado`);
    });
});

//Servir la carpeta de archivos para usuarios registrados.
const filePath = path.join(__dirname, "../uploads");
//app.use("/public", authenticateMiddleware, express.static(filePath));
app.use("/public", express.static(filePath)); //without authentication

// Iniciar el servidor de Express
app.listen(PORT, () => {
    console.log(`Servidor iniciado en http://localhost:${PORT}`);
});

server.listen(3001, () => {
    console.log(`Servidor de chat en http://localhost:${3001}`);
});

export { server, io };
