import { FastifyRequest, FastifyReply } from 'fastify';
import { config } from '../config';
import { applyRewrites } from '../proxy/rewrite';

/** Sinsay Cookiebot domain group — declaration is fetched with referer www.sinsay.com. */
const COOKIEBOT_ID = '35c8a6cc-d203-484c-abb5-a74e2605a491';

const COOKIEBOT_LOADER_RE =
  /\(function\s*\(\s*d\s*\)\s*\{[\s\S]*?cookiebotId[\s\S]*?\}\)\(document\);/;

async function fetchCookieDeclarationScript(culture: string): Promise<string | null> {
  const upstreamUrl =
    `https://consent.cookiebot.com/${COOKIEBOT_ID}/cdreport.js` +
    `?referer=www.sinsay.com&culture=${encodeURIComponent(culture)}`;

  const res = await fetch(upstreamUrl, {
    headers: { Accept: '*/*', 'User-Agent': 'Mozilla/5.0 (compatible; SinsayProxy/1.0)' },
  });
  if (!res.ok) return null;

  let body = await res.text();
  if (/not authorized/i.test(body)) return null;

  body = applyRewrites(body);
  body = body.replaceAll('www.sinsay.com', config.domain);
  return body;
}

/** Parse HTML payload from Cookiebot cdreport.js (InjectCookieDeclaration('...')). */
export function extractDeclarationHtml(cdreportJs: string): string | null {
  const marker = 'CookieDeclaration.InjectCookieDeclaration(';
  const start = cdreportJs.indexOf(marker);
  if (start < 0) return null;

  let i = start + marker.length;
  while (i < cdreportJs.length && /\s/.test(cdreportJs[i])) i++;
  const quote = cdreportJs[i];
  if (quote !== "'" && quote !== '"') return null;
  i++;

  let out = '';
  while (i < cdreportJs.length) {
    const ch = cdreportJs[i];
    if (ch === '\\' && i + 1 < cdreportJs.length) {
      const next = cdreportJs[i + 1];
      if (next === 'n') {
        out += '\n';
        i += 2;
        continue;
      }
      if (next === 'r') {
        out += '\r';
        i += 2;
        continue;
      }
      if (next === 't') {
        out += '\t';
        i += 2;
        continue;
      }
      out += next;
      i += 2;
      continue;
    }
    if (ch === quote) {
      break;
    }
    out += ch;
    i++;
  }
  return out || null;
}

/**
 * Proxy Cookiebot cookie declaration (cdreport.js) for optional client-side load.
 */
export async function handleCookieDeclaration(
  request: FastifyRequest<{ Querystring: { culture?: string } }>,
  reply: FastifyReply,
): Promise<void> {
  const raw = request.query.culture ?? 'pl';
  const culture = /^[a-z]{2}(-[a-z]{2})?$/i.test(raw) ? raw.toLowerCase() : 'pl';

  const body = await fetchCookieDeclarationScript(culture);
  if (!body) {
    reply.status(502).type('text/plain').send('Cookie declaration unavailable');
    return;
  }

  reply
    .header('content-type', 'application/javascript; charset=utf-8')
    .header('cache-control', 'public, max-age=3600, stale-while-revalidate=600')
    .send(body);
}

/**
 * Inject cookie table HTML server-side and remove the broken Cookiebot loader.
 */
export async function patchCookiesListPage(html: string): Promise<string> {
  const cultureMatch = html.match(/global\.languageCode\s*=\s*['"]([^'"]+)['"]/i);
  const culture = (cultureMatch?.[1] ?? 'pl_PL').split('_')[0] || 'pl';

  const cdreport = await fetchCookieDeclarationScript(culture);
  if (!cdreport) return html;

  const declarationHtml = extractDeclarationHtml(cdreport);
  if (!declarationHtml) return html;

  let patched = html.replace(COOKIEBOT_LOADER_RE, '');
  patched = patched.replace(
    /<div\s+id=["']cookieList["'][^>]*>[\s\S]*?<\/div>/i,
    `<div id="cookieList" style="padding-top: 0px;">${declarationHtml}</div>`,
  );
  return patched;
}
