import type { Connect, Plugin } from "vite";
import { cpSync, createReadStream, existsSync, statSync } from "node:fs";
import { extname, resolve } from "node:path";

const MIME_TYPES: Record<string, string> = {
  ".css": "text/css",
  ".js": "application/javascript",
  ".png": "image/png",
  ".jpg": "image/jpeg",
  ".jpeg": "image/jpeg",
  ".gif": "image/gif",
  ".mp4": "video/mp4",
  ".ttf": "font/ttf",
  ".woff": "font/woff",
  ".woff2": "font/woff2",
  ".html": "text/html"
};

const APP_ROUTE_PREFIXES = [
  "/login",
  "/register",
  "/profile",
  "/admin",
  "/verify",
  "/reset-password",
  "/forgot-password",
  "/pages"
];

function isAppRoute(url: string): boolean {
  const path = url.split("?")[0];
  return APP_ROUTE_PREFIXES.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
}

function createMainStaticMiddleware(mainDir: string): Connect.NextHandleFunction {
  const root = resolve(mainDir);

  return (req, res, next) => {
    const urlPath = decodeURIComponent((req.url ?? "").split("?")[0]);
    if (!urlPath || urlPath === "/") {
      next();
      return;
    }

    const relativePath = urlPath.replace(/^\/+/, "");
    const filePath = resolve(root, relativePath);

    if (!filePath.startsWith(root) || !existsSync(filePath) || !statSync(filePath).isFile()) {
      next();
      return;
    }

    const ext = extname(filePath).toLowerCase();
    res.setHeader("Content-Type", MIME_TYPES[ext] ?? "application/octet-stream");
    createReadStream(filePath).pipe(res);
  };
}

function createAppFallbackMiddleware(): Connect.NextHandleFunction {
  return (req, _res, next) => {
    const url = req.url ?? "";
    if (isAppRoute(url)) {
      req.url = "/app.html";
    }
    next();
  };
}

export function mainStaticPlugin(mainDir: string): Plugin {
  const resolvedMainDir = resolve(mainDir);

  return {
    name: "kompton-main-static",
    configureServer(server) {
      server.middlewares.use("/main", createMainStaticMiddleware(resolvedMainDir));
      server.middlewares.use(createAppFallbackMiddleware());
    },
    configurePreviewServer(server) {
      server.middlewares.use("/main", createMainStaticMiddleware(resolvedMainDir));
      server.middlewares.use(createAppFallbackMiddleware());
    },
    closeBundle() {
      cpSync(resolvedMainDir, resolve(__dirname, "dist/main"), { recursive: true });
    }
  };
}
