import { Router } from "express";
import type { Request } from "express";
import { prisma } from "../../db/prisma.js";
import { env } from "../../config/env.js";

export const rssRouter = Router();

function escapeXml(value: string) {
  return value
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&apos;");
}

function toRfc822(value: Date) {
  return value.toUTCString();
}

function buildFrontendUrl(path: string) {
  return new URL(path, env.APP_PUBLIC_URL).toString();
}

function buildRequestUrl(req: Request) {
  const protoHeader = req.get("x-forwarded-proto");
  const hostHeader = req.get("x-forwarded-host") || req.get("host");
  const protocol = protoHeader?.split(",")[0]?.trim() || req.protocol || "http";
  const host = hostHeader?.split(",")[0]?.trim();

  if (!host) {
    return "";
  }

  return `${protocol}://${host}${req.originalUrl}`;
}

function formatSignalDescription(signal: {
  leagueName: string;
  marketType: string;
  selection: string;
  lineValue: number | null;
  odds: number;
  status: string;
  comment: string | null;
  eventStartTime: Date;
  signalTime: Date;
}) {
  const parts = [
    `League: ${signal.leagueName}`,
    `Market: ${signal.marketType}`,
    `Selection: ${signal.selection}${signal.lineValue !== null ? ` ${signal.lineValue}` : ""}`,
    `Odds: ${signal.odds}`,
    `Status: ${signal.status}`,
    `Event start: ${signal.eventStartTime.toISOString()}`,
    `Signal time: ${signal.signalTime.toISOString()}`
  ];

  if (signal.comment) {
    parts.push(`Comment: ${signal.comment}`);
  }

  return parts.join(" | ");
}

rssRouter.get("/rss.xml", async (req, res, next) => {
  try {
    const signals = await prisma.signal.findMany({
      where: { published: true },
      orderBy: [{ signalTime: "desc" }, { createdAt: "desc" }],
      take: 50
    });

    const siteUrl = env.APP_PUBLIC_URL;
    const selfUrl = buildRequestUrl(req);
    const latestDate = signals[0]?.updatedAt ?? new Date();

    const itemsXml = signals
      .map((signal) => {
        const title = `${signal.homeTeam} vs ${signal.awayTeam}: ${signal.selection} @ ${signal.odds}`;
        const link = buildFrontendUrl(`/signals/${signal.id}`);
        const description = formatSignalDescription(signal);

        return [
          "<item>",
          `<title>${escapeXml(title)}</title>`,
          `<link>${escapeXml(link)}</link>`,
          `<guid isPermaLink="false">${escapeXml(signal.id)}</guid>`,
          `<pubDate>${toRfc822(signal.signalTime)}</pubDate>`,
          `<description>${escapeXml(description)}</description>`,
          "</item>"
        ].join("");
      })
      .join("");

    const channelParts = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">',
      "<channel>",
      "<title>Betting Signals</title>",
      "<description>Latest published betting signals</description>",
      `<link>${escapeXml(siteUrl)}</link>`,
      `<lastBuildDate>${toRfc822(latestDate)}</lastBuildDate>`,
      "<language>ru</language>"
    ];

    if (selfUrl) {
      channelParts.push(`<atom:link href="${escapeXml(selfUrl)}" rel="self" type="application/rss+xml" />`);
    }

    channelParts.push(itemsXml, "</channel>", "</rss>");

    res.setHeader("Content-Type", "application/rss+xml; charset=utf-8");
    res.send(channelParts.join(""));
  } catch (error) {
    next(error);
  }
});
