import express from "express";
import path from "path";
import { fileURLToPath } from "url";
import { createServer as createViteServer, ViteDevServer } from "vite";
import fs from "fs";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const isProd = process.env.NODE_ENV === "production" || process.env.NODE_ENV === "prod";

async function startServer() {
  console.log(`NODE_ENV is: "${process.env.NODE_ENV}"`);
  console.log(`Starting server in ${isProd ? "PRODUCTION" : "DEVELOPMENT"} mode...`);
  const app = express();
  let vite: ViteDevServer | null = null;

  if (!isProd) {
    // DEV MODE
    vite = await createViteServer({
      server: { middlewareMode: true },
      appType: "custom",
    });
    app.use(vite.middlewares);
  } else {
    // PROD MODE
    app.use((await import("compression")).default());
    app.use(
      (await import("serve-static")).default(path.resolve(__dirname, "dist/client"), {
        index: false,
      })
    );
  }

  app.get("*all", async (req, res) => {
    try {
      const url = req.originalUrl;

      // Handle WWW and HTTPS redirects in production
      if (isProd) {
        const host = req.headers.host || "";
        const protocol = req.headers["x-forwarded-proto"] || req.protocol;

        if (host.startsWith("www.") || protocol === "http") {
          const newHost = host.replace(/^www\./, "");
          return res.redirect(301, `https://${newHost}${url}`);
        }
      }

      let template: string;
      let render: any;

      if (!isProd && vite) {
        // Dev: read from root index.html and use vite to transform
        template = fs.readFileSync(path.resolve(__dirname, "index.html"), "utf-8");
        template = await vite.transformIndexHtml(url, template);
        render = (await vite.ssrLoadModule("/src/entry-server.tsx")).render;
      } else {
        // Prod: read from dist/client/index.html
        template = fs.readFileSync(path.resolve(__dirname, "dist/client/index.html"), "utf-8");
        // In prod, entry-server is built to dist/server/entry-server.js
        // Note: Using dynamic import for the built server bundle
        render = (await import("./dist/server/entry-server.js")).render;
      }

      const { html, meta, initialData, statusCode } = await render(url);

      const canonicalTag = meta.canonical 
        ? `<link rel="canonical" href="${meta.canonical}" />` 
        : `<link rel="canonical" href="https://nytsolvers.com${url.split('?')[0]}" />`;

      const safeInitialData = JSON.stringify(initialData).replace(/</g, '\\u003c').replace(/>/g, '\\u003e');

      const fullHtml = template
        .replace(`<!--ssr-outlet-->`, () => html)
        .replace(`<!--meta-title-->`, () => meta.title)
        .replace(`<!--meta-description-->`, () => meta.description)
        .replace(`<!--meta-canonical-->`, () => canonicalTag)
        .replace(`<!--initial-data-->`, () => `<script>window.__INITIAL_DATA__ = ${safeInitialData};</script>`);

      res.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://*.googletagmanager.com https://www.google-analytics.com https://*.google-analytics.com https://www.clarity.ms https://*.clarity.ms https://c.bing.com https://*.bing.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://*.googleapis.com; img-src 'self' data: https://www.googletagmanager.com https://*.googletagmanager.com https://www.google-analytics.com https://*.google-analytics.com https://www.google.com https://*.google.com https://nytsolvers.com https://*.nytsolvers.com https://c.bing.com https://*.bing.com; connect-src 'self' ws: wss: http: https: https://api.nytsolvers.com https://*.nytsolvers.com https://api.dictionaryapi.dev https://api.datamuse.com https://*.google-analytics.com https://analytics.google.com https://*.analytics.google.com https://stats.g.doubleclick.net https://www.googletagmanager.com https://*.googletagmanager.com https://*.clarity.ms https://c.bing.com https://*.bing.com; font-src 'self' https://fonts.gstatic.com https://*.gstatic.com; frame-src 'self' https://www.googletagmanager.com https://*.googletagmanager.com;");

      res.status(statusCode || 200).set({ "Content-Type": "text/html" }).end(fullHtml);
    } catch (err: any) {
      if (vite) vite.ssrFixStacktrace(err);
      console.error(err);
      res.status(500).end(err.message);
    }
  });

  const port = process.env.PORT || 3000;
  app.listen(port, () => {
    console.log(`SSR server running on http://localhost:${port} (${isProd ? 'production' : 'development'})`);
  });
}

startServer();
