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

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

/** WESP hub page routes → static HTML (same as wesp/app/routes/pages.py). */
const WESP_PAGE_ROUTES: Record<string, string> = {
  "/login": "login.html",
  "/recipes": "recipes.html",
  "/recipes_content": "recipes.html",
  "/components": "components.html",
  "/feed_dispensers": "feed_dispensers.html",
  "/reports": "reports.html",
  "/feed_consumption": "consumption.html",
  "/consumption": "consumption.html",
  "/lab": "lab.html",
  "/lab-profiles": "lab-profiles.html",
  "/admin": "admin.html",
};

function injectOrchestratorScripts(html: string, urlPath: string): string {
  const scripts =
    urlPath === "/login"
      ? [
          '<script src="/static/js/wesp-orchestrator-auth-bridge.js"></script>',
          '<script src="/static/js/wesp-orchestrator-login.js"></script>',
        ]
      : [
          '<script src="/static/js/wesp-orchestrator-auth-bridge.js"></script>',
          '<script src="/static/js/wesp-orchestrator-boot.js"></script>',
        ];
  const block = scripts.join("\n");
  if (html.includes("wesp-orchestrator-auth-bridge.js")) {
    return html;
  }
  if (html.includes("</head>")) {
    return html.replace("</head>", `${block}\n</head>`);
  }
  return `${block}\n${html}`;
}

function sendFile(res: Connect.ServerResponse, filePath: string, transform?: (body: string) => string): void {
  const ext = extname(filePath).toLowerCase();
  if (transform && ext === ".html") {
    const body = transform(readFileSync(filePath, "utf-8"));
    res.setHeader("Content-Type", "text/html; charset=utf-8");
    res.end(body);
    return;
  }
  res.setHeader("Content-Type", MIME_TYPES[ext] ?? "application/octet-stream");
  createReadStream(filePath).pipe(res);
}

export function wespStaticPlugin(staticRoot: string): Plugin {
  const root = resolve(staticRoot);

  return {
    name: "kompton-wesp-static",
    configureServer(server) {
      server.middlewares.use(createWespMiddleware(root));
    },
    configurePreviewServer(server) {
      server.middlewares.use(createWespMiddleware(root));
    },
  };
}

function createWespMiddleware(root: string): Connect.NextHandleFunction {
  return (req, res, next) => {
    const urlPath = decodeURIComponent((req.url ?? "").split("?")[0]);
    if (!urlPath || urlPath === "/") {
      next();
      return;
    }

    const pageFile = WESP_PAGE_ROUTES[urlPath];
    if (pageFile) {
      const htmlPath = resolve(root, pageFile);
      if (existsSync(htmlPath) && statSync(htmlPath).isFile()) {
        sendFile(res, htmlPath, (body) => injectOrchestratorScripts(body, urlPath));
        return;
      }
    }

    if (urlPath.startsWith("/static/")) {
      const relative = urlPath.replace(/^\/static\//, "");
      const filePath = resolve(root, relative);
      if (filePath.startsWith(root) && existsSync(filePath) && statSync(filePath).isFile()) {
        sendFile(res, filePath);
        return;
      }
    }

    next();
  };
}

export { WESP_PAGE_ROUTES };
