import { ReactNode } from "react";

export const patterns = [
  {
    regex: /<PERSON>/g,
    className: "bg-blue-200 text-blue-800",
    label: "Personne",
  },
  {
    regex: /<EMAIL_ADDRESS>/g,
    className: "bg-green-200 text-green-800",
    label: "Adresse Email",
  },
  {
    regex: /<PHONE_NUMBER>/g,
    className: "bg-purple-200 text-purple-800",
    label: "N° de Téléphone",
  },
  {
    regex: /<LOCATION>/g,
    className: "bg-red-200 text-red-800",
    label: "Lieu",
  },
  {
    regex: /<IBAN>/g,
    className: "bg-yellow-200 text-yellow-800",
    label: "IBAN",
  },
  {
    regex: /<ORGANIZATION>/g,
    className: "bg-indigo-200 text-indigo-800",
    label: "Organisation",
  },
  {
    regex: /<FLEXIBLE_DATE>/g,
    className: "bg-pink-200 text-pink-800",
    label: "Date",
  },
  {
    regex: /<BE_ADDRESS>/g,
    className: "bg-cyan-200 text-cyan-800",
    label: "Adresse (BE)",
  },
  {
    regex: /<BE_PHONE_NUMBER>/g,
    className: "bg-violet-200 text-violet-800",
    label: "N° de Tél. (BE)",
  },
  {
    regex: /<CREDIT_CARD>/g,
    className: "bg-orange-200 text-orange-800",
    label: "Carte de Crédit",
  },
  {
    regex: /<URL>/g,
    className: "bg-teal-200 text-teal-800",
    label: "URL",
  },
  {
    regex: /<IP_ADDRESS>/g,
    className: "bg-gray-300 text-gray-900",
    label: "Adresse IP",
  },
  {
    regex: /<DATE_TIME>/g,
    className: "bg-pink-300 text-pink-900",
    label: "Date & Heure",
  },
  {
    regex: /<NRP>/g,
    className: "bg-red-300 text-red-900",
    label: "N° Registre National",
  },
  {
    regex: /<BE_VAT>/g,
    className: "bg-yellow-300 text-yellow-900",
    label: "TVA (BE)",
  },
  {
    regex: /<BE_ENTERPRISE_NUMBER>/g,
    className: "bg-lime-200 text-lime-800",
    label: "N° d'entreprise (BE)",
  },
  {
    regex: /<BE_PRO_ID>/g,
    className: "bg-emerald-200 text-emerald-800",
    label: "ID Pro (BE)",
  },
];

interface EntityMapping {
  originalValue: string;
  anonymizedValue: string;
  entityType: string;
  startIndex: number;
  endIndex: number;
}

export const highlightEntities = (
  text: string,
  entityMappings?: EntityMapping[]
): ReactNode => {
  if (!text) return text;

  const replacements: Array<{
    start: number;
    end: number;
    element: ReactNode;
  }> = [];

  // Si on a des mappings, on les utilise pour créer un mapping des valeurs anonymisées
  const anonymizedValueMap = new Map<
    string,
    { label: string; className: string }
  >();

  if (entityMappings) {
    entityMappings.forEach((mapping) => {
      // Trouver le pattern correspondant au type d'entité
      const pattern = patterns.find((p) => p.label === mapping.entityType);
      if (pattern) {
        anonymizedValueMap.set(mapping.anonymizedValue, {
          label: mapping.anonymizedValue,
          className: pattern.className,
        });
      }
    });
  }

  // Trouver toutes les correspondances
  patterns.forEach((pattern, patternIndex) => {
    const regex = new RegExp(pattern.regex.source, pattern.regex.flags);
    let match;

    while ((match = regex.exec(text)) !== null) {
      const start = match.index;
      const end = match.index + match[0].length;

      // Vérifier qu'il n'y a pas de chevauchement avec des remplacements existants
      const hasOverlap = replacements.some(
        (r) =>
          (start >= r.start && start < r.end) || (end > r.start && end <= r.end)
      );

      if (!hasOverlap) {
        // Chercher si on a un mapping pour cette entité
        let displayLabel = pattern.label;
        const displayClass = pattern.className; // Changé de 'let' à 'const'

        if (entityMappings) {
          // Compter les occurrences précédentes du même type pour déterminer le numéro
          const entityType = pattern.label;
          const previousMatches = replacements.filter((r) => {
            // Correction du type 'any' en utilisant une interface plus spécifique
            const element = r.element as React.ReactElement<{
              className?: string;
            }>;
            const prevPattern = patterns.find(
              (p) =>
                p.className ===
                element?.props?.className?.split(" ")[0] +
                  " " +
                  element?.props?.className?.split(" ")[1]
            );
            return prevPattern?.label === entityType;
          }).length;

          const matchingMapping = entityMappings.find(
            (mapping) => mapping.entityType === entityType
          );

          if (matchingMapping) {
            // Utiliser le compteur pour déterminer le bon numéro avec des crochets
            const entityCount = previousMatches + 1;
            displayLabel = `${entityType} [${entityCount}]`;
          }
        }

        const element = (
          <span
            key={`${patternIndex}-${start}`}
            className={`${displayClass} px-2 py-1 rounded-md font-medium text-xs inline-block mx-0.5 shadow-sm border`}
            title={`${displayLabel} anonymisé`}
          >
            {displayLabel}
          </span>
        );

        replacements.push({ start, end, element });
      }
    }
  });

  // Trier les remplacements par position
  replacements.sort((a, b) => a.start - b.start);

  // Construire le résultat final
  if (replacements.length === 0) {
    return text;
  }

  const parts: ReactNode[] = [];
  let lastIndex = 0;

  replacements.forEach((replacement) => {
    // Ajouter le texte avant le remplacement
    if (replacement.start > lastIndex) {
      parts.push(text.slice(lastIndex, replacement.start));
    }

    // Ajouter l'élément de remplacement
    parts.push(replacement.element);

    lastIndex = replacement.end;
  });

  // Ajouter le texte restant
  if (lastIndex < text.length) {
    parts.push(text.slice(lastIndex));
  }

  return parts;
};
