import { getPublishedPostBySlug } from '@/lib/content';
import sanitizeHtml from 'sanitize-html';

function decodeHtmlEntities(text: string): string {
  return text
    .replace(/&nbsp;/g, ' ')
    .replace(/&amp;/g, '&')
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'")
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&mdash;/g, '--')
    .replace(/&ndash;/g, '-')
    .replace(/&hellip;/g, '...')
    .replace(/&#x27;/g, "'")
    .replace(/&#x2F;/g, '/')
    .replace(/&#(\d+);/g, (_, code) => {
      const value = Number.parseInt(code, 10);
      return Number.isNaN(value) ? '' : String.fromCharCode(value);
    });
}

function cleanHtmlToText(html: string): string {
  const normalized = html
    .replace(/<div\b[^>]*class=(['"])[^'"]*post-metadata[^'"]*\1[^>]*>[\s\S]*?<\/div>/gi, '')
    .replace(/<div\b[^>]*class=(['"])[^'"]*blog-content[^'"]*\1[^>]*>/gi, '')
    .replace(/<\/div>\s*$/i, '');

  const withLinks = normalized.replace(
    /<a\b[^>]*href=(['"])(.*?)\1[^>]*>([\s\S]*?)<\/a>/gi,
    (_, __, href: string, text: string) => `[${cleanHtmlToText(text)}](${href})`,
  );

  const structured = withLinks
    .replace(/<br\s*\/?>/gi, '\n')
    .replace(/<li\b[^>]*>/gi, '- ')
    .replace(/<\/li>/gi, '\n')
    .replace(/<h([1-6])\b[^>]*>/gi, (_, level: string) => `${'#'.repeat(Number.parseInt(level, 10))} `)
    .replace(/<\/h[1-6]>/gi, '\n\n')
    .replace(/<\/p>/gi, '\n\n')
    .replace(/<\/div>/gi, '\n\n')
    .replace(/<\/section>/gi, '\n\n')
    .replace(/<\/ul>/gi, '\n')
    .replace(/<\/ol>/gi, '\n');

  const stripped = sanitizeHtml(structured, {
    allowedTags: [],
    allowedAttributes: {},
  });

  return decodeHtmlEntities(stripped)
    .replace(/\r\n/g, '\n')
    .replace(/\n{3,}/g, '\n\n')
    .replace(/[ \t]+\n/g, '\n')
    .replace(/\n[ \t]+/g, '\n')
    .trim();
}

function renderRawPost(slug: string): string | null {
  const post = getPublishedPostBySlug(slug);
  if (!post) {
    return null;
  }

  const sections: string[] = [
    `# ${post.title}`,
    '',
    post.description,
    '',
    `Canonical URL: https://www.qrmaster.net/blog/${post.slug}`,
    `Published: ${post.datePublished}`,
    `Updated: ${post.dateModified || post.updatedAt || post.datePublished}`,
  ];

  if (post.quickAnswer) {
    sections.push('', '## Quick Answer', '', cleanHtmlToText(post.quickAnswer));
  }

  if (post.keySteps?.length) {
    sections.push('', '## Steps', '', ...post.keySteps.map((step, index) => `${index + 1}. ${step}`));
  }

  const mainText = cleanHtmlToText(post.content);
  if (mainText) {
    sections.push('', '## Article', '', mainText);
  }

  if (post.faq?.length) {
    sections.push('', '## FAQ', '');
    for (const item of post.faq) {
      sections.push(`Q: ${cleanHtmlToText(item.question)}`);
      sections.push(`A: ${cleanHtmlToText(item.answer)}`, '');
    }
    if (sections[sections.length - 1] === '') {
      sections.pop();
    }
  }

  if (post.sources?.length) {
    sections.push('', '## Sources', '');
    for (const source of post.sources) {
      const accessDate = source.accessDate ? ` (accessed ${source.accessDate})` : '';
      sections.push(`- ${source.name}: ${source.url}${accessDate}`);
    }
  }

  return `${sections.join('\n').trim()}\n`;
}

export async function GET(
  _request: Request,
  { params }: { params: { slug: string } },
) {
  const content = renderRawPost(params.slug);

  if (!content) {
    return new Response('Not Found', {
      status: 404,
      headers: {
        'Content-Type': 'text/plain; charset=utf-8',
        'X-Robots-Tag': 'noindex, nofollow',
      },
    });
  }

  return new Response(content, {
    headers: {
      'Content-Type': 'text/markdown; charset=utf-8',
      'X-Robots-Tag': 'noindex, nofollow',
      'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
    },
  });
}
