import { Router, Request, Response, NextFunction } from 'express';
import { prisma } from '../../config/database';
import { redis } from '../../config/redis';
import { env } from '../../config/env';
import { siteSettingsService } from '../settings/settings.service';
import { escapeHtml } from '../../utils/escapeHtml';

const router = Router();

const CACHE_TTL = 600; // 10 minutes

/** Generate minimal HTML with OG tags + JS redirect for non-bots */
function ogHtml(opts: {
  title: string;
  description: string;
  image?: string | null;
  url: string;
  siteName: string;
  type?: string;
}): string {
  const safeTitle = escapeHtml(opts.title);
  const safeDesc = escapeHtml(opts.description);
  const safeSite = escapeHtml(opts.siteName);
  const safeUrl = escapeHtml(opts.url);
  const safeImage = opts.image ? escapeHtml(opts.image) : '';

  return `<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>${safeTitle}</title>
  <meta property="og:title" content="${safeTitle}">
  <meta property="og:description" content="${safeDesc}">
  <meta property="og:site_name" content="${safeSite}">
  <meta property="og:url" content="${safeUrl}">
  <meta property="og:type" content="${opts.type || 'website'}">
  ${safeImage ? `<meta property="og:image" content="${safeImage}">` : ''}
  <meta name="twitter:card" content="${safeImage ? 'summary_large_image' : 'summary'}">
  <meta name="twitter:title" content="${safeTitle}">
  <meta name="twitter:description" content="${safeDesc}">
  ${safeImage ? `<meta name="twitter:image" content="${safeImage}">` : ''}
  <meta http-equiv="refresh" content="0;url=${safeUrl}">
</head>
<body>
  <p>Redirecting to <a href="${safeUrl}">${safeTitle}</a>...</p>
</body>
</html>`;
}

// GET /api/og/campaign/:slug
router.get('/campaign/:slug', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const slug = req.params.slug as string;
    const cacheKey = `og:campaign:${slug}`;

    try {
      const cached = await redis.get(cacheKey);
      if (cached) { res.type('html').send(cached); return; }
    } catch { /* cache miss */ }

    const campaign = await prisma.campaign.findFirst({
      where: { slug, status: 'ACTIVE' },
      select: { title: true, description: true, coverPhoto: true },
    });

    if (!campaign) { res.status(404).send('Not found'); return; }

    const settings = await siteSettingsService.getPublic();
    const appDomain = env.DOMAIN ? `app.${env.DOMAIN}` : 'app.cmlite.org';
    const protocol = env.DOMAIN ? 'https' : req.protocol;
    const url = `${protocol}://${appDomain}/campaign/${slug}`;

    const html = ogHtml({
      title: campaign.title,
      description: campaign.description?.slice(0, 200) || `${campaign.title} — Take action now`,
      image: campaign.coverPhoto || null,
      url,
      siteName: settings.organizationName || 'Changemaker Lite',
    });

    try { await redis.setex(cacheKey, CACHE_TTL, html); } catch { /* non-critical */ }

    res.type('html').send(html);
  } catch (err) {
    next(err);
  }
});

// GET /api/og/page/:slug
router.get('/page/:slug', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const slug = req.params.slug as string;
    const cacheKey = `og:page:${slug}`;

    try {
      const cached = await redis.get(cacheKey);
      if (cached) { res.type('html').send(cached); return; }
    } catch { /* cache miss */ }

    const page = await prisma.landingPage.findFirst({
      where: { slug, published: true },
      select: { title: true, description: true, seoTitle: true, seoDescription: true, seoImage: true },
    });

    if (!page) { res.status(404).send('Not found'); return; }

    const settings = await siteSettingsService.getPublic();
    const appDomain = env.DOMAIN ? `app.${env.DOMAIN}` : 'app.cmlite.org';
    const protocol = env.DOMAIN ? 'https' : req.protocol;
    const url = `${protocol}://${appDomain}/p/${slug}`;

    const html = ogHtml({
      title: page.seoTitle || page.title,
      description: page.seoDescription || page.description?.slice(0, 200) || page.title,
      image: page.seoImage || null,
      url,
      siteName: settings.organizationName || 'Changemaker Lite',
    });

    try { await redis.setex(cacheKey, CACHE_TTL, html); } catch { /* non-critical */ }

    res.type('html').send(html);
  } catch (err) {
    next(err);
  }
});

// GET /api/og/gallery/:id
router.get('/gallery/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = req.params.id as string;
    const cacheKey = `og:gallery:${id}`;

    try {
      const cached = await redis.get(cacheKey);
      if (cached) { res.type('html').send(cached); return; }
    } catch { /* cache miss */ }

    const videoId = parseInt(id, 10);
    if (isNaN(videoId)) { res.status(404).send('Not found'); return; }

    const video = await prisma.video.findFirst({
      where: { id: videoId, isPublished: true },
      select: { title: true, thumbnailPath: true },
    });

    if (!video) { res.status(404).send('Not found'); return; }

    const settings = await siteSettingsService.getPublic();
    const appDomain = env.DOMAIN ? `app.${env.DOMAIN}` : 'app.cmlite.org';
    const protocol = env.DOMAIN ? 'https' : req.protocol;
    const url = `${protocol}://${appDomain}/gallery/watch/${id}`;

    const html = ogHtml({
      title: video.title || 'Video',
      description: video.title || 'Watch this video',
      image: video.thumbnailPath ? `${protocol}://${appDomain}/media/public/${videoId}/thumbnail` : null,
      url,
      siteName: settings.organizationName || 'Changemaker Lite',
      type: 'video.other',
    });

    try { await redis.setex(cacheKey, CACHE_TTL, html); } catch { /* non-critical */ }

    res.type('html').send(html);
  } catch (err) {
    next(err);
  }
});

export { router as ogRouter };
