/* eslint-disable security/detect-unsafe-regex */
"use client";

import React from "react";
import DOMPurify from "dompurify";

interface WikiLinkRendererProps {
  /** HTML content with wiki-links to parse */
  html: string;
  /** Additional CSS classes */
  className?: string;
}

/**
 * WikiLinkRenderer - Parses and renders wiki-links in HTML content
 *
 * Converts:
 * - [[slug]] → clickable link to /knowledge/slug
 * - [[slug|display text]] → clickable link with custom text
 *
 * Features:
 * - Distinct styling for wiki-links (blue color, underline)
 * - Graceful handling of broken links (gray out)
 * - Preserves all other HTML formatting
 */
export function WikiLinkRenderer({
  html,
  className = "",
}: WikiLinkRendererProps): React.ReactElement {
  const processedHtml = React.useMemo(() => {
    // SEC-WEB-2 FIX: Sanitize ENTIRE HTML input BEFORE processing wiki-links
    // This prevents stored XSS via knowledge entry content
    const sanitizedHtml = DOMPurify.sanitize(html, {
      // Allow common formatting tags that are safe
      ALLOWED_TAGS: [
        "p",
        "br",
        "strong",
        "b",
        "em",
        "i",
        "u",
        "s",
        "strike",
        "del",
        "ins",
        "mark",
        "small",
        "sub",
        "sup",
        "code",
        "pre",
        "blockquote",
        "h1",
        "h2",
        "h3",
        "h4",
        "h5",
        "h6",
        "ul",
        "ol",
        "li",
        "dl",
        "dt",
        "dd",
        "table",
        "thead",
        "tbody",
        "tfoot",
        "tr",
        "th",
        "td",
        "hr",
        "span",
        "div",
      ],
      // Allow safe attributes only
      ALLOWED_ATTR: ["class", "id", "title", "lang", "dir"],
      // Remove any data: or javascript: URIs
      ALLOW_DATA_ATTR: false,
    });
    return parseWikiLinks(sanitizedHtml);
  }, [html]);

  return (
    <div
      className={`wiki-link-content ${className}`}
      dangerouslySetInnerHTML={{ __html: processedHtml }}
      onClick={handleWikiLinkClick}
    />
  );
}

/**
 * Parse wiki-links in HTML and convert to anchor tags
 *
 * Supports:
 * - [[slug]] - basic link
 * - [[slug|display text]] - link with custom display text
 */
function parseWikiLinks(html: string): string {
  // Match [[...]] patterns
  // Group 1: target slug
  // Group 2: optional display text after |
  const wikiLinkRegex = /\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g;

  return html.replace(wikiLinkRegex, (match, slug: string, displayText?: string) => {
    const trimmedSlug = slug.trim();
    const text = displayText?.trim() ?? trimmedSlug;

    // Enhanced slug validation - reject dangerous protocols and special characters
    if (!isValidWikiLinkSlug(trimmedSlug)) {
      // Invalid slug - return original text escaped
      return escapeHtml(match);
    }

    // Sanitize display text with DOMPurify (text-only, no HTML)
    const sanitizedText = DOMPurify.sanitize(text, {
      ALLOWED_TAGS: [], // No HTML tags allowed in display text
      KEEP_CONTENT: true, // Keep the text content
    });

    // Create a styled link
    // Using data-wiki-link attribute for styling and click handling
    return `<a
      href="/knowledge/${encodeURIComponent(trimmedSlug)}"
      data-wiki-link="true"
      data-slug="${encodeURIComponent(trimmedSlug)}"
      class="wiki-link text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 underline decoration-dotted hover:decoration-solid transition-colors"
      title="Go to ${escapeHtml(trimmedSlug)}"
    >${escapeHtml(sanitizedText)}</a>`;
  });
}

/**
 * Validate wiki-link slug
 * Rejects dangerous protocols and invalid characters
 */
function isValidWikiLinkSlug(slug: string): boolean {
  // Reject empty slugs
  if (!slug || slug.length === 0) {
    return false;
  }

  // Reject dangerous protocols
  const dangerousProtocols = ["javascript:", "data:", "vbscript:", "file:", "about:", "blob:"];

  const lowerSlug = slug.toLowerCase();
  for (const protocol of dangerousProtocols) {
    if (lowerSlug.includes(protocol)) {
      return false;
    }
  }

  // Reject URL-encoded dangerous protocols
  if (lowerSlug.includes("%")) {
    try {
      const decoded = decodeURIComponent(lowerSlug);
      for (const protocol of dangerousProtocols) {
        if (decoded.includes(protocol)) {
          return false;
        }
      }
    } catch {
      // If decoding fails, reject it
      return false;
    }
  }

  // Reject HTML tags in slug
  if (/<[^>]*>/.test(slug)) {
    return false;
  }

  // Reject HTML entities in slug
  if (/&[a-z]+;/i.test(slug)) {
    return false;
  }

  // Only allow safe characters: alphanumeric, hyphens, underscores, dots, slashes
  return /^[a-zA-Z0-9\-_./]+$/.test(slug);
}

/**
 * Handle wiki-link clicks
 * Intercepts clicks on wiki-links to use Next.js navigation
 */
function handleWikiLinkClick(e: React.MouseEvent<HTMLDivElement>): void {
  const target = e.target as HTMLElement;

  // Check if the clicked element is a wiki-link
  if (target.tagName === "A" && target.dataset.wikiLink === "true") {
    const href = target.getAttribute("href");
    if (href?.startsWith("/knowledge/")) {
      // Let Next.js Link handle navigation naturally
      // No need to preventDefault - the href will work
    }
  }
}

/**
 * Escape HTML to prevent XSS
 */
function escapeHtml(text: string): string {
  const div = document.createElement("div");
  div.textContent = text;
  return div.innerHTML;
}

/**
 * Custom hook to check if a wiki-link target exists
 * (For future enhancement - mark broken links differently)
 */
export function useWikiLinkValidation(_slug: string): {
  isValid: boolean;
  isLoading: boolean;
} {
  // Placeholder for future implementation
  // Could fetch from /api/knowledge/entries/:slug to check existence
  return {
    isValid: true,
    isLoading: false,
  };
}
