import React, { useState } from "react";

// =============================================
// Sample articles to search through (DO NOT MODIFY)
// =============================================
interface Article {
  id: number;
  title: string;
  body: string;
}

const ARTICLES: Article[] = [
  {
    id: 1,
    title: "Getting Started with React",
    body: "React is a JavaScript library for building user interfaces. It lets you compose complex UIs from small, isolated pieces of code called components. React has been designed from the start for gradual adoption, and you can use as little or as much React as you need.",
  },
  {
    id: 2,
    title: "Understanding JavaScript Closures",
    body: "A closure is the combination of a function bundled together with references to its surrounding state. In JavaScript, closures are created every time a function is created, at function creation time. Closures are useful because they let you associate data with a function that operates on that data.",
  },
  {
    id: 3,
    title: "CSS Grid Layout Guide",
    body: "CSS Grid Layout is a two-dimensional layout system for the web. It lets you lay content out in rows and columns. Grid layout gives us a method of creating grid structures that are described in CSS and not in HTML.",
  },
  {
    id: 4,
    title: "Introduction to TypeScript",
    body: "TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale. TypeScript adds additional syntax to JavaScript to support a tighter integration with your editor.",
  },
  {
    id: 5,
    title: "Web Performance Optimization",
    body: "Web performance refers to how quickly site content loads and renders in a web browser. Performance optimization includes reducing load times, making the site interactive sooner, and ensuring smooth scrolling and responsive interactions.",
  },
  {
    id: 6,
    title: "Node.js Event Loop Explained",
    body: "The event loop is what allows Node.js to perform non-blocking operations despite JavaScript being single-threaded. It works by offloading operations to the system kernel whenever possible.",
  },
];

// =============================================
// TODO: Implement <HighlightSearchText> Component
// =============================================
//
// This is a WRAPPER COMPONENT approach — instead of calling a function
// on each string, you wrap arbitrary JSX in <HighlightSearchText> and
// it recursively finds and highlights text nodes.
//
// Requirements:
//   1. Build a <HighlightSearchText query={...}> component
//   2. It receives \`query\` (string) and \`children\` (React.ReactNode)
//   3. Recursively traverse the children React tree
//   4. For string nodes: split around matches and wrap in <mark>
//   5. For element nodes: clone the element and recurse into its children
//   6. Case-insensitive matching, escape special regex characters
//   7. Support multi-word queries (split by spaces, match any word)
//
// Hints:
//   - Use React.Children.map and React.isValidElement to traverse
//   - For string nodes: use text.split(regex) with a capturing group
//     e.g. new RegExp(\`(\${words.join("|")})\`, "gi")
//     split keeps the matched parts in the array
//   - For element nodes: use React.cloneElement to recurse into children
//   - Build the regex from query.split(/\s+/) joined with |
//   - Escape special regex chars: replace /[.*+?^${}()|[\]\\]/g

type HighlightSearchTextProps = {
  query?: string;
  children: React.ReactNode;
};

function HighlightSearchText({ query, children }: HighlightSearchTextProps) {
  // TODO: Implement this component
  //
  // Step 1: If no query or empty query, return children as-is
  //
  // Step 2: Build a regex from the query
  //   - Split query by whitespace to get individual words
  //   - Filter out empty strings
  //   - Escape special regex characters in each word
  //   - Join with | and wrap in a capturing group: (word1|word2)
  //   - Use "gi" flags for case-insensitive global matching
  //
  // Step 3: Define a traverse(node) function that:
  //   - If node is a string → split by regex, map parts:
  //     - If part matches regex → wrap in <mark> with highlight styles
  //     - Otherwise → return as plain text
  //   - If node is a valid React element → React.cloneElement with
  //     traversed children (recurse)
  //   - If node is an array → map and traverse each item
  //   - Otherwise → return node as-is
  //
  // Step 4: Return <>{traverse(children)}</>

  return <>{children}</>;
}

export default function App() {
  const [searchText, setSearchText] = useState("");

  // Filter articles that match the search text
  const filteredList = ARTICLES.filter(
    (article) =>
      !searchText.length ||
      article.body.toLowerCase().includes(searchText.toLowerCase()) ||
      article.title.toLowerCase().includes(searchText.toLowerCase()),
  );

  return (
    <div style={{ maxWidth: 640, margin: "0 auto", padding: 24, fontFamily: "system-ui" }}>
      <h2 style={{ fontSize: 20, fontWeight: 700, marginBottom: 4 }}>
        Highlight Search Component
      </h2>
      <p style={{ fontSize: 14, color: "#666", marginBottom: 24 }}>
        Build a reusable <code>&lt;HighlightSearchText></code> wrapper component
        that recursively traverses its children and highlights matching text nodes.
        Unlike a simple function, this component works with any nested JSX structure.
      </p>

      {/* Search input */}
      <div style={{ marginBottom: 16 }}>
        <input
          type="text"
          placeholder="Search articles..."
          value={searchText}
          onChange={(e) => setSearchText(e.target.value)}
          style={{
            width: "100%",
            padding: "10px 14px",
            border: "1px solid #d1d5db",
            borderRadius: 8,
            fontSize: 14,
            outline: "none",
            boxSizing: "border-box",
          }}
        />
      </div>

      {/* Results count */}
      <div style={{ marginBottom: 16, fontSize: 13, color: "#999" }}>
        Showing {filteredList.length} of {ARTICLES.length} articles
      </div>

      {/* ============================================= */}
      {/* TODO: Wrap the article list with              */}
      {/*       <HighlightSearchText query={searchText}> */}
      {/* ============================================= */}
      {/* The component should recursively find text    */}
      {/* nodes inside the children and highlight       */}
      {/* matches with <mark> tags.                     */}
      <HighlightSearchText query={searchText}>
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {filteredList.map((article) => (
            <div
              key={article.id}
              style={{
                border: "1px solid #e5e7eb",
                borderRadius: 8,
                padding: 16,
              }}
            >
              <h3 style={{ fontSize: 15, fontWeight: 600, marginBottom: 6 }}>
                {article.title}
              </h3>
              <p style={{ fontSize: 13, color: "#666", lineHeight: 1.6, margin: 0 }}>
                {article.body}
              </p>
            </div>
          ))}
        </div>
      </HighlightSearchText>

      {/* Hint */}
      <div style={{
        marginTop: 24,
        padding: 16,
        background: "#f9fafb",
        borderLeft: "4px solid #111",
        borderRadius: "0 8px 8px 0",
        fontSize: 13,
        color: "#555",
      }}>
        <strong>Approach:</strong> This is a component-based highlighter.
        Build a <code>&lt;HighlightSearchText query=&#123;...&#125;&gt;</code> wrapper
        that recursively walks the React children tree.
        <ul style={{ margin: "8px 0 0 16px", padding: 0, lineHeight: 1.8 }}>
          <li>Use <code>React.Children.map</code> and <code>React.isValidElement</code> to traverse</li>
          <li>For string nodes: <code>text.split(regex)</code> with a capturing group keeps matches in the array</li>
          <li>For element nodes: <code>React.cloneElement(el, &#123; children: traverse(el.props.children) &#125;)</code></li>
          <li>Escape special regex chars before building the pattern</li>
          <li>Support multi-word queries by splitting on spaces and joining with <code>|</code></li>
        </ul>
      </div>
    </div>
  );
}