import React, { useCallback, useEffect } from "react";
import {
  GrammarContent,
  GrammarHeader,
  GrammarHeaderContent,
  ModelComtainer,
  ModelContent,
} from "../style";
import HandIcon from "../icons/hand";
import classNames from "classnames";
import ChatIcon from "../icons/chatIcon";
import AIcon from "../icons/aIcon";
import { MarsIcon } from "lucide-react";
import { useState } from "react";
import GoodCheck from "../../../../assets/svg/goodCheck";
import RedX from "../../../../assets/svg/redX";
import DOMPurify from "dompurify";
// import useReportUtils from "../../hooks/useRreportUtils";
import useTranslation from "../../../../hooks/useTranslation.jsx";
import wordStore from "../../../../mc/wordStore.json";
const findBestMatchPosition = (text, targetWord, suggestedPosition) => {
  const cleanTarget = targetWord.trim();

  // For single characters, be more precise with position matching
  if (cleanTarget.length === 1 && suggestedPosition !== undefined) {
    const pos = suggestedPosition - 1; // Convert to 0-based index

    // Check exact position first
    if (pos >= 0 && pos < text.length && text[pos] === cleanTarget) {
      return pos;
    }

    // Check nearby positions with small tolerance for single characters
    const tolerance = 3;
    for (
      let i = Math.max(0, pos - tolerance);
      i <= Math.min(text.length - 1, pos + tolerance);
      i++
    ) {
      if (text[i] === cleanTarget) {
        // Prefer positions that are standalone (surrounded by spaces or at boundaries)
        const prevChar = i > 0 ? text[i - 1] : " ";
        const nextChar = i < text.length - 1 ? text[i + 1] : " ";
        if (
          /\s/.test(prevChar) &&
          (/\s/.test(nextChar) || i === text.length - 1)
        ) {
          return i;
        }
      }
    }

    // Fallback: find the rightmost occurrence of the character (likely the intended one)
    const lastIndex = text.lastIndexOf(cleanTarget);
    if (lastIndex !== -1) {
      return lastIndex;
    }
  }

  // For multi-character words, use the original logic with improvements
  if (suggestedPosition !== undefined) {
    const tolerance = Math.max(5, cleanTarget.length); // Dynamic tolerance based on word length
    const startSearch = Math.max(0, suggestedPosition - 1 - tolerance);
    const endSearch = Math.min(
      text.length,
      suggestedPosition - 1 + cleanTarget.length + tolerance
    );
    const searchArea = text.slice(startSearch, endSearch);

    // Look for exact match in the search area
    const exactMatch = searchArea.indexOf(cleanTarget);
    if (exactMatch !== -1) {
      return startSearch + exactMatch;
    }

    // Look for case-insensitive match
    const caseInsensitiveMatch = searchArea
      .toLowerCase()
      .indexOf(cleanTarget.toLowerCase());
    if (caseInsensitiveMatch !== -1) {
      return startSearch + caseInsensitiveMatch;
    }
  }

  // Find all occurrences using different strategies, prioritizing word boundaries for multi-char words
  const strategies =
    cleanTarget.length === 1
      ? [
          // For single characters, don't use word boundaries as they don't work well
          new RegExp(cleanTarget.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"),
          new RegExp(cleanTarget.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi"),
        ]
      : [
          // For multi-character words, prefer word boundaries
          new RegExp(
            `\\b${cleanTarget.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`,
            "g"
          ),
          new RegExp(
            `\\b${cleanTarget.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`,
            "gi"
          ),
          new RegExp(cleanTarget.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"),
          new RegExp(cleanTarget.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi"),
        ];
  for (const regex of strategies) {
    const matches = [];
    let match;
    while ((match = regex.exec(text)) !== null) {
      matches.push({
        index: match.index,
        text: match[0],
        distance: suggestedPosition
          ? Math.abs(match.index - (suggestedPosition - 1))
          : 0,
      });
    }
    if (matches.length > 0) {
      // If multiple matches, prefer the one closest to suggested position
      if (suggestedPosition !== undefined) {
        matches.sort((a, b) => a.distance - b.distance);
      }
      return matches[0].index;
    }
  }
  return -1;
};
const validateCorrectionPositions = (corrections, originalText) => {
  const issues = [];
  const wordOccurrences = new Map();

  // Build a map of all word occurrences for better analysis
  corrections?.forEach((correction) => {
    const word = correction.original_word;
    if (!wordOccurrences.has(word)) {
      const occurrences = [];
      let index = originalText.indexOf(word);
      while (index !== -1) {
        occurrences.push(index);
        index = originalText.indexOf(word, index + 1);
      }
      wordOccurrences.set(word, occurrences);
    }
  });
  corrections.forEach((correction, index) => {
    const { position, length, original_word, replacement_word } = correction;
    if (position !== undefined && length !== undefined) {
      const startPos = Math.max(0, position - 1);
      const endPos = Math.min(originalText.length, startPos + length);
      const textAtPosition = originalText.slice(startPos, endPos);
      if (
        textAtPosition !== original_word &&
        textAtPosition.trim() !== original_word.trim()
      ) {
        const occurrences = wordOccurrences.get(original_word) || [];
        issues.push({
          correctionIndex: index,
          expected: original_word,
          found: textAtPosition,
          position: position,
          length: length,
          replacement: replacement_word,
          allOccurrences: occurrences,
          multipleOccurrences: occurrences.length > 1,
          suggestion:
            occurrences.length > 1
              ? `Multiple "${original_word}" found at positions: ${occurrences
                  .map((pos) => pos + 1)
                  .join(", ")}`
              : "Position data may be inaccurate",
        });
      }
    }
  });
  if (issues.length > 0) {
    console.group("🔍 Grammar Correction Position Analysis");
    console.log(`Original text: "${originalText}"`);
    issues.forEach((issue) => {
      console.warn(
        `Correction ${issue.correctionIndex + 1}: "${issue.expected}" → "${
          issue.replacement
        }"`
      );
      console.warn(`  Expected at pos ${issue.position}: "${issue.expected}"`);
      console.warn(`  Actually found: "${issue.found}"`);
      console.warn(`  ${issue.suggestion}`);
    });
    console.groupEnd();
  }
  return issues;
};
const Grammar = ({ Aidata }) => {
  const { findText } = useTranslation(wordStore);
  const [selectedSection, setSelectedSection] = useState(1);
  const [formattedCopy, setFormattedCopy] = useState("");
  const [operationIndex, setOperationIndex] = useState(null);
  const data = Aidata?.data;
  const originalText = data?.["Original Speech"] || "";
  const correctText = data?.["Grammatical Correct Version"] || "";
  const feedbackCorrection = data?.["Correction Operations (Optional)"] || [];
  const findOperation = useCallback(() => {
    const substitutedCorrections = feedbackCorrection.filter((correction) =>
      ["substituted", "formatting"].includes(correction.operation)
    );
    return substitutedCorrections[operationIndex ?? -1] || null;
  }, [feedbackCorrection, operationIndex]);
  const processSubstitutedCorrections = useCallback(
    (corrections, originalSpeech) => {
      if (!corrections.length) return originalSpeech;
      console.log(corrections, originalSpeech, "fffff");
      let workingText = originalSpeech;
      const appliedCorrections = new Set();
      const correctionMappings = corrections
        ?.map((correction, originalIndex) => {
          const { position, original_word } = correction;

          // Find best position in the original text
          const bestPosition = findBestMatchPosition(
            originalSpeech,
            original_word,
            position
          );
          return {
            originalPosition: bestPosition,
            correction,
            originalIndex,
            length: original_word.length,
          };
        })
        .filter((mapping) => mapping?.originalPosition !== -1);
      correctionMappings?.sort(
        (a, b) => a.originalPosition - b.originalPosition
      );
      correctionMappings?.forEach((mapping) => {
        const { correction, originalIndex, originalPosition, length } = mapping;
        const { original_word } = correction;
        if (appliedCorrections.has(originalIndex)) {
          return;
        }
        let currentPosition = -1;
        if (original_word.length === 1) {
          const unprocessedOccurrences = [];
          let searchIndex = 0;
          while (searchIndex < workingText.length) {
            const foundIndex = workingText.indexOf(original_word, searchIndex);
            if (foundIndex === -1) break;

            // Check if this occurrence is not already wrapped in HTML
            const beforeContext = workingText.slice(
              Math.max(0, foundIndex - 50),
              foundIndex
            );
            const afterContext = workingText.slice(
              foundIndex,
              Math.min(workingText.length, foundIndex + 50)
            );

            // Skip if it's inside HTML tags
            if (
              !beforeContext.includes('<span class="issue"') &&
              !afterContext.startsWith('<span class="issue"') &&
              !beforeContext.includes('<span class="number"')
            ) {
              const prevChar =
                foundIndex > 0 ? workingText[foundIndex - 1] : " ";
              const nextChar =
                foundIndex < workingText.length - 1
                  ? workingText[foundIndex + 1]
                  : " ";
              const isStandalone =
                /\s/.test(prevChar) &&
                (/\s/.test(nextChar) || foundIndex === workingText.length - 1);
              unprocessedOccurrences.push({
                index: foundIndex,
                isStandalone,
                distanceFromOriginal: Math.abs(foundIndex - originalPosition),
              });
            }
            searchIndex = foundIndex + 1;
          }
          if (unprocessedOccurrences.length > 0) {
            // Sort by preference: standalone first, then closest to original position
            unprocessedOccurrences.sort((a, b) => {
              if (a.isStandalone && !b.isStandalone) return -1;
              if (!a.isStandalone && b.isStandalone) return 1;
              return a.distanceFromOriginal - b.distanceFromOriginal;
            });
            currentPosition = unprocessedOccurrences[0].index;
          }
        } else {
          // For multi-character words, find all unprocessed occurrences and pick the best one
          const unprocessedOccurrences = [];
          let searchIndex = 0;
          while (searchIndex < workingText.length) {
            const foundIndex = workingText.indexOf(original_word, searchIndex);
            if (foundIndex === -1) break;

            // Check if this occurrence is not already wrapped in HTML
            const beforeContext = workingText.slice(
              Math.max(0, foundIndex - 50),
              foundIndex
            );
            const afterContext = workingText.slice(
              foundIndex,
              Math.min(workingText.length, foundIndex + 50)
            );

            // Skip if it's inside HTML tags
            if (
              !beforeContext.includes('<span class="issue"') &&
              !afterContext.startsWith('<span class="issue"') &&
              !beforeContext.includes('<span class="number"')
            ) {
              // Check if this occurrence is standalone (word boundaries)
              const prevChar =
                foundIndex > 0 ? workingText[foundIndex - 1] : " ";
              const nextChar =
                foundIndex < workingText.length - 1
                  ? workingText[foundIndex + original_word.length]
                  : " ";
              const isStandalone =
                /\s/.test(prevChar) &&
                (/\s/.test(nextChar) ||
                  foundIndex + original_word.length === workingText.length);
              unprocessedOccurrences.push({
                index: foundIndex,
                isStandalone,
                distanceFromOriginal: Math.abs(foundIndex - originalPosition),
              });
            }
            searchIndex = foundIndex + 1;
          }
          if (unprocessedOccurrences.length > 0) {
            // Sort by preference: standalone first, then closest to original position
            unprocessedOccurrences.sort((a, b) => {
              if (a.isStandalone && !b.isStandalone) return -1;
              if (!a.isStandalone && b.isStandalone) return 1;
              return a.distanceFromOriginal - b.distanceFromOriginal;
            });
            currentPosition = unprocessedOccurrences[0].index;
            console.log(
              `🎯 Multi-char word "${original_word}" - found ${unprocessedOccurrences.length} occurrences:`,
              unprocessedOccurrences.map((occ) => ({
                position: occ.index,
                standalone: occ.isStandalone,
                distance: occ.distanceFromOriginal,
                context: workingText.slice(
                  Math.max(0, occ.index - 3),
                  occ.index + original_word.length + 3
                ),
              }))
            );
            console.log(
              `🎯 Selected position ${currentPosition} (standalone: ${unprocessedOccurrences[0].isStandalone})`
            );
          }
        }
        if (original_word.length === 1 && currentPosition !== -1) {
          const allOccurrences = [];
          let searchIndex = 0;
          while (searchIndex < workingText.length) {
            const foundIndex = workingText.indexOf(original_word, searchIndex);
            if (foundIndex === -1) break;

            // Check if this position is not already wrapped in HTML
            const beforeContext = workingText.slice(
              Math.max(0, foundIndex - 30),
              foundIndex
            );
            const afterContext = workingText.slice(
              foundIndex,
              Math.min(workingText.length, foundIndex + 30)
            );

            // Skip if it's inside HTML tags or already processed
            if (
              !beforeContext.includes('<span class="issue"') &&
              !afterContext.startsWith('<span class="issue"')
            ) {
              // For single characters, prefer standalone occurrences
              const prevChar =
                foundIndex > 0 ? workingText[foundIndex - 1] : " ";
              const nextChar =
                foundIndex < workingText.length - 1
                  ? workingText[foundIndex + 1]
                  : " ";
              const isStandalone =
                /\s/.test(prevChar) &&
                (/\s/.test(nextChar) || foundIndex === workingText.length - 1);
              allOccurrences.push({
                index: foundIndex,
                isStandalone,
                distanceFromOriginal: Math.abs(foundIndex - originalPosition),
              });
            }
            searchIndex = foundIndex + 1;
          }
          if (allOccurrences.length > 0) {
            // Prefer standalone occurrences, then closest to original position
            allOccurrences.sort((a, b) => {
              if (a.isStandalone && !b.isStandalone) return -1;
              if (!a.isStandalone && b.isStandalone) return 1;
              return a.distanceFromOriginal - b.distanceFromOriginal;
            });
            currentPosition = allOccurrences[0].index;
          }
        }
        if (currentPosition !== -1) {
          const endPosition = currentPosition + original_word.length;
          const textAtPosition = workingText.slice(
            currentPosition,
            endPosition
          );

          // Verify this is the text we expect and it's not already wrapped
          if (textAtPosition === original_word) {
            const highlightHtml = `<span class="issue" data-index="${originalIndex}"><span class="number" data-index="${originalIndex}">${
              originalIndex + 1
            }</span> ${textAtPosition}</span>`;

            // Apply the highlighting
            workingText =
              workingText.slice(0, currentPosition) +
              highlightHtml +
              workingText.slice(endPosition);

            // Mark this correction as applied
            appliedCorrections.add(originalIndex);
            appliedCorrections.add(originalIndex);
            console.log(
              `✓ Applied correction ${
                originalIndex + 1
              } for "${original_word}" at position ${currentPosition}`
            );
          } else {
            console.warn(
              `✗ Skipped correction ${
                originalIndex + 1
              } for "${original_word}" - text mismatch or already processed. Found: "${textAtPosition}"`
            );
          }
        } else {
          console.warn(
            `✗ Could not locate "${original_word}" for correction ${
              originalIndex + 1
            }`
          );
        }
      });
      return DOMPurify.sanitize(workingText);
    },
    []
  );
  useEffect(() => {
    const substitutedCorrections = feedbackCorrection?.filter((correction) =>
      ["substituted", "formatting"].includes(correction.operation)
    );

    // Enhanced debugging for the specific issue
    if (substitutedCorrections.length > 0) {
      // Show character-by-character analysis for debugging
      substitutedCorrections.forEach((correction, index) => {
        if (correction.original_word.length === 1) {
          // Show all occurrences of single characters
          const char = correction.original_word;
          const occurrences = [];
          for (let i = 0; i < originalText.length; i++) {
            if (originalText[i] === char) {
              occurrences.push({
                index: i + 1,
                // 1-based for readability
                context: originalText.slice(Math.max(0, i - 3), i + 4),
                isStandalone:
                  (i === 0 || /\s/.test(originalText[i - 1])) &&
                  (i === originalText.length - 1 ||
                    /\s/.test(originalText[i + 1])),
              });
            }
          }
          console.log(`  All "${char}" occurrences:`, occurrences);
        }
      });
      console.groupEnd();
      validateCorrectionPositions(substitutedCorrections, originalText);
    }
    console.log(substitutedCorrections, "fff");
    const processedSpeech = processSubstitutedCorrections(
      substitutedCorrections,
      originalText
    );
    setFormattedCopy(processedSpeech);
  }, [feedbackCorrection, data, processSubstitutedCorrections]);
  useEffect(() => {
    const handleClick = (event) => {
      const target = event.target;
      const index = target.getAttribute("data-index");
      if (index) setOperationIndex(Number(index));
    };
    document.addEventListener("click", handleClick);
    return () => document.removeEventListener("click", handleClick);
  }, []);
  const tabs = [
    {
      label: "Feedback",
      value: 1,
      icon: ChatIcon,
    },
    {
      label: "View script",
      value: 2,
      icon: AIcon,
    },
    {
      label: "Corrected version",
      value: 3,
      icon: MarsIcon,
    },
  ].filter((item) => !(item?.value === 3 && Aidata?.score >= 100));
  const operation = findOperation();
  return (
    <ModelComtainer>
      <ModelContent>
        <GrammarHeader>
          <div className="instruction">
            <HandIcon />
            <p>{findText("Click on the words to see detailed feedback")}</p>
          </div>
          <GrammarHeaderContent>
            <div
              className="grammar_analysis_container"
              dangerouslySetInnerHTML={{
                __html: formattedCopy,
              }}
            ></div>
          </GrammarHeaderContent>
          <ul className="no-border ul_tabs">
            {tabs.map((tab) => (
              <li
                key={tab.value}
                style={{
                  height: "40px",
                }}
                className={classNames({
                  active: selectedSection === tab.value,
                })}
                onClick={() => {
                  setSelectedSection(tab.value);
                }}
              >
                <tab.icon
                  color={selectedSection === tab.value ? "#f5f7f7" : "#949999"}
                />
                <p>{tab.label}</p>
              </li>
            ))}
          </ul>
        </GrammarHeader>
        <GrammarContent>
          {selectedSection === 1 && operation && (
            <div className="feedback_section">
              <div className="failed">
                <RedX />
                <span>
                  <span>{operationIndex + 1}</span> {operation?.original_word}
                </span>
              </div>
              <div className="correct">
                <GoodCheck />
                <span>{operation?.replacement_word}</span>
              </div>
            </div>
          )}
          {selectedSection === 2 && originalText && <p>{originalText}</p>}
          {selectedSection === 3 && (
            <div className="correct_section">
              {/* <div className="warning">
                <WarningGrey />
                <p>Introduced words are highlighted in green</p>
               </div> */}
              <p>{correctText}</p>
            </div>
          )}
        </GrammarContent>
      </ModelContent>
    </ModelComtainer>
  );
};
export default Grammar;
