import express, { type Request, Response, NextFunction } from "express";
import { registerRoutes } from "./routes";
import { videoSyncService } from "./videoSync";
import { setupVite, serveStatic, log } from "./vite";
import { storage } from "./storage";
import fs from "fs";
import path from "path";

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.use((req, res, next) => {
  const start = Date.now();
  const path = req.path;
  let capturedJsonResponse: Record<string, any> | undefined = undefined;

  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 (path.startsWith("/api")) {
      let logLine = `${req.method} ${path} ${res.statusCode} in ${duration}ms`;
      if (capturedJsonResponse) {
        logLine += ` :: ${JSON.stringify(capturedJsonResponse)}`;
      }

      if (logLine.length > 80) {
        logLine = logLine.slice(0, 79) + "…";
      }

      log(logLine);
    }
  });

  next();
});

(async () => {
  // Initialize video sync service for automatic Bunny.net updates
  await videoSyncService.initialize();
  
  // Social media prerendering middleware - mora biti PRED setupVite
  app.get('/video/:videoId', async (req, res, next) => {
    const { videoId } = req.params;
    const userAgent = req.get('User-Agent') || '';
    
    // Če je to Facebook, Twitter, WhatsApp ali podoben scraper
    const isSocialBot = /facebookexternalhit|twitterbot|whatsapp|telegrambot|discordbot|slackbot|linkedinbot/i.test(userAgent);
    
    if (isSocialBot) {
      try {
        const video = await storage.getVideo(videoId);
        
        if (!video) {
          return next(); // Če video ne obstaja, preusmerimo na običajno SPA
        }

        // Preberemo osnovni HTML template
        const clientTemplate = path.resolve(import.meta.dirname, "..", "client", "index.html");
        let template = await fs.promises.readFile(clientTemplate, "utf-8");
        
        // Escape special characters v naslovih in opisih
        const escapeHtml = (text: string) => text.replace(/"/g, '&quot;').replace(/'/g, '&#39;');
        
        // Zamenimo meta oznake z video specifičnimi
        const baseUrl = req.protocol + '://' + req.get('host');
        const videoUrl = `${baseUrl}/video/${video.id}`;
        const thumbnailUrl = `${baseUrl}/api/video-thumbnail/${video.id}`;
        
        // Zamenjamo osnovne meta oznake
        template = template.replace(
          /<title>.*<\/title>/,
          `<title>${escapeHtml(video.title)} | go4.video</title>`
        );
        
        template = template.replace(
          /<meta name="description" content="[^"]*"/,
          `<meta name="description" content="${escapeHtml(video.description || `Watch ${video.title} on go4.video`)}"`
        );
        
        // Zamenjamo Open Graph meta oznake
        template = template.replace(
          /<meta property="og:title" content="[^"]*"/,
          `<meta property="og:title" content="${escapeHtml(video.title)}"`
        );
        
        template = template.replace(
          /<meta property="og:description" content="[^"]*"/,
          `<meta property="og:description" content="${escapeHtml(video.description || `Watch ${video.title} on go4.video`)}"`
        );
        
        template = template.replace(
          /<meta property="og:image" content="[^"]*"/,
          `<meta property="og:image" content="${thumbnailUrl}"`
        );
        
        // Zamenjamo tudi Twitter image
        template = template.replace(
          /<meta name="twitter:image" content="[^"]*"/,
          `<meta name="twitter:image" content="${thumbnailUrl}"`
        );
        
        template = template.replace(
          /<meta name="twitter:title" content="[^"]*"/,
          `<meta name="twitter:title" content="${escapeHtml(video.title)}"`
        );
        
        template = template.replace(
          /<meta name="twitter:description" content="[^"]*"/,
          `<meta name="twitter:description" content="${escapeHtml(video.description || `Watch ${video.title} on go4.video`)}"`
        );
        
        // Dodamo dodatne OG oznake za video z detajlnimi informacijami
        const duration = Math.floor(video.duration / 60) + ':' + (video.duration % 60).toString().padStart(2, '0');
        const additionalMeta = `
    <meta property="og:url" content="${videoUrl}">
    <meta property="og:type" content="video.other">
    <meta property="og:video:duration" content="${video.duration}">
    <meta property="og:site_name" content="go4.video">
    <meta property="video:duration" content="${video.duration}">
    <meta property="video:release_date" content="${video.createdAt?.toISOString()}">
    
    <!-- Dodatni Twitter Card meta podatki -->
    <meta name="twitter:player:width" content="1200">
    <meta name="twitter:player:height" content="630">
    <meta name="twitter:creator" content="@go4video">
    
    <!-- Strukturirani podatki za Google -->
    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "VideoObject",
      "name": "${escapeHtml(video.title)}",
      "description": "${escapeHtml(video.description || `Watch ${video.title} on go4.video`)}",
      "thumbnailUrl": "${thumbnailUrl}",
      "uploadDate": "${video.createdAt?.toISOString()}",
      "duration": "PT${Math.floor(video.duration / 60)}M${video.duration % 60}S",
      "contentUrl": "${videoUrl}",
      "embedUrl": "${videoUrl}",
      "publisher": {
        "@type": "Organization",
        "name": "go4.video",
        "url": "${baseUrl}"
      }
    }
    </script>`;
        
        template = template.replace('</head>', `${additionalMeta}\n</head>`);
        
        res.setHeader('Content-Type', 'text/html');
        res.send(template);
        return;
        
      } catch (error) {
        console.error('Error rendering video page for social bot:', error);
        // Če se zgodi napaka, nadaljujemo z običajno SPA
        return next();
      }
    }
    
    // Za običajne uporabnike nadaljujemo z SPA
    next();
  });
  
  const server = await registerRoutes(app);

  app.use((err: any, _req: Request, res: Response, _next: NextFunction) => {
    const status = err.status || err.statusCode || 500;
    const message = err.message || "Internal Server Error";

    res.status(status).json({ message });
    throw err;
  });

  // importantly only setup vite in development and after
  // setting up all the other routes so the catch-all route
  // doesn't interfere with the other routes
  if (app.get("env") === "development") {
    await setupVite(app, server);
  } else {
    serveStatic(app);
  }

  // ALWAYS serve the app on the port specified in the environment variable PORT
  // Other ports are firewalled. Default to 5000 if not specified.
  // this serves both the API and the client.
  // It is the only port that is not firewalled.
  const port = parseInt(process.env.PORT || '5000', 10);
  server.listen({
    port,
    host: "0.0.0.0",
    reusePort: true,
  }, () => {
    log(`serving on port ${port}`);
  });
})();
