/**
 * Full search results page.
 *
 * Reads `q` from URL search params, calls searchApi, groups results by type
 * (technique_pages first, then key_moments). Shows fallback banner when
 * keyword search was used.
 */

import { useCallback, useEffect, useState } from "react";
import { Link, useSearchParams, useNavigate } from "react-router-dom";
import { searchApi, type SearchResultItem } from "../api";
import { catSlug } from "../utils/catSlug";
import SearchAutocomplete from "../components/SearchAutocomplete";
import SortDropdown from "../components/SortDropdown";
import TagList from "../components/TagList";
import { useDocumentTitle } from "../hooks/useDocumentTitle";
import { useSortPreference } from "../hooks/useSortPreference";

const SEARCH_SORT_OPTIONS = [
  { value: "relevance", label: "Relevance" },
  { value: "newest", label: "Newest" },
  { value: "oldest", label: "Oldest" },
  { value: "alpha", label: "A–Z" },
  { value: "creator", label: "Creator" },
];

export default function SearchResults() {
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const q = searchParams.get("q") ?? "";
  const [sort, setSort] = useSortPreference("relevance");

  useDocumentTitle(q ? `Search: ${q} — Chrysopedia` : "Search — Chrysopedia");

  const [results, setResults] = useState<SearchResultItem[]>([]);
  const [partialMatches, setPartialMatches] = useState<SearchResultItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const doSearch = useCallback(async (query: string, sortBy: string) => {
    if (!query.trim()) {
      setResults([]);
      setPartialMatches([]);
      return;
    }

    setLoading(true);
    setError(null);
    try {
      const res = await searchApi(query.trim(), undefined, undefined, sortBy);
      setResults(res.items);
      setPartialMatches(res.partial_matches ?? []);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Search failed");
      setResults([]);
      setPartialMatches([]);
    } finally {
      setLoading(false);
    }
  }, []);

  // Search when URL param or sort changes
  useEffect(() => {
    if (q) void doSearch(q, sort);
  }, [q, sort, doSearch]);

  // Group results by type
  const techniqueResults = results.filter((r) => r.type === "technique_page");
  const sectionResults = results.filter((r) => r.type === "technique_section");
  const momentResults = results.filter((r) => r.type === "key_moment");

  return (
    <div className="search-results-page">
      <h1 className="sr-only">Search Results</h1>
      {/* Inline search bar */}
      <SearchAutocomplete
        variant="inline"
        initialQuery={q}
        onSearch={(newQ) =>
          navigate(`/search?q=${encodeURIComponent(newQ)}`, { replace: true })
        }
      />

      {/* Sort control */}
      {q && (
        <SortDropdown
          options={SEARCH_SORT_OPTIONS}
          value={sort}
          onChange={setSort}
        />
      )}

      {/* Status */}
      {loading && <div className="loading">Searching…</div>}
      {error && <div className="loading error-text">Error: {error}</div>}

      {/* No exact results — partial match fallback */}
      {!loading && !error && q && results.length === 0 && partialMatches.length > 0 && (
        <>
          <div className="partial-match-banner">
            <p>No exact matches for all terms in "{q}"</p>
          </div>
          <PartialMatchResults items={partialMatches} />
        </>
      )}

      {/* No results at all */}
      {!loading && !error && q && results.length === 0 && partialMatches.length === 0 && (
        <div className="empty-state">
          <p>No results found for "{q}"</p>
        </div>
      )}

      {/* Technique pages */}
      {techniqueResults.length > 0 && (
        <section className="search-group">
          <h3 className="search-group__title">
            Techniques ({techniqueResults.length})
          </h3>
          <div className="search-group__list">
            {techniqueResults.map((item, i) => (
              <SearchResultCard key={`tp-${item.slug}`} item={item} staggerIndex={i} />
            ))}
          </div>
        </section>
      )}

      {/* Technique sections */}
      {sectionResults.length > 0 && (
        <section className="search-group">
          <h3 className="search-group__title">
            Sections ({sectionResults.length})
          </h3>
          <div className="search-group__list">
            {sectionResults.map((item, i) => (
              <SearchResultCard key={`ts-${item.slug}-${item.section_anchor}-${i}`} item={item} staggerIndex={i} />
            ))}
          </div>
        </section>
      )}

      {/* Key moments */}
      {momentResults.length > 0 && (
        <section className="search-group">
          <h3 className="search-group__title">
            Key Moments ({momentResults.length})
          </h3>
          <div className="search-group__list">
            {momentResults.map((item, i) => (
              <SearchResultCard key={`km-${item.slug}-${i}`} item={item} staggerIndex={i} />
            ))}
          </div>
        </section>
      )}
    </div>
  );
}

function getSearchResultLink(item: SearchResultItem): string {
  if (item.type === "technique_section") {
    if (item.technique_page_slug && item.section_anchor) {
      return `/techniques/${item.technique_page_slug}#${item.section_anchor}`;
    }
    if (item.technique_page_slug) {
      return `/techniques/${item.technique_page_slug}`;
    }
    return `/search?q=${encodeURIComponent(item.title)}`;
  }
  if (item.type === "key_moment") {
    if (item.technique_page_slug) {
      return `/techniques/${item.technique_page_slug}#km-${item.slug || item.title}`;
    }
    // Graceful fallback — re-search instead of 404
    return `/search?q=${encodeURIComponent(item.title)}`;
  }
  return `/techniques/${item.slug}`;
}

function SearchResultCard({ item, staggerIndex }: { item: SearchResultItem; staggerIndex: number }) {
  const typeLabels: Record<string, string> = {
    technique_page: "Technique",
    key_moment: "Key Moment",
    technique_section: "Section",
  };

  return (
    <Link
      to={getSearchResultLink(item)}
      className="search-result-card card-stagger"
      style={{ '--stagger-index': staggerIndex } as React.CSSProperties}
    >
      <div className="search-result-card__header">
        <span className="search-result-card__title">{item.title}</span>
        <span className={`badge badge--type badge--type-${item.type}`}>
          {typeLabels[item.type] ?? item.type}
        </span>
      </div>
      {item.type === "technique_section" && item.section_heading && (
        <div className="search-result-card__section-context">
          § {item.section_heading}
        </div>
      )}
      {item.match_context && (
        <div className="search-result-card__match-context">
          <span className="match-context__icon">⚡</span>
          <span className="match-context__text">{item.match_context}</span>
        </div>
      )}
      {item.summary && (
        <p className="search-result-card__summary">
          {item.summary.length > 200
            ? `${item.summary.slice(0, 200)}…`
            : item.summary}
        </p>
      )}
      <div className="search-result-card__meta">
        {item.creator_name && <span className="search-result-card__creator">{item.creator_name}</span>}
        {item.topic_category && (
          <>
            <span className="queue-card__separator">·</span>
            <span className={`badge badge--cat-${catSlug(item.topic_category)}`}>{item.topic_category}</span>
          </>
        )}
        {item.topic_tags.length > 0 && (
          <span className="search-result-card__tags">
            <TagList tags={item.topic_tags} />
          </span>
        )}
      </div>
    </Link>
  );
}

function PartialMatchResults({ items }: { items: SearchResultItem[] }) {
  const techniqueResults = items.filter((r) => r.type === "technique_page");
  const sectionResults = items.filter((r) => r.type === "technique_section");
  const momentResults = items.filter((r) => r.type === "key_moment");

  return (
    <div className="partial-match-results">
      <h3 className="partial-match-results__header">
        Results matching some of your terms
      </h3>

      {techniqueResults.length > 0 && (
        <section className="search-group">
          <h4 className="search-group__title">
            Techniques ({techniqueResults.length})
          </h4>
          <div className="search-group__list">
            {techniqueResults.map((item, i) => (
              <SearchResultCard key={`partial-tp-${item.slug}`} item={item} staggerIndex={i} />
            ))}
          </div>
        </section>
      )}

      {sectionResults.length > 0 && (
        <section className="search-group">
          <h4 className="search-group__title">
            Sections ({sectionResults.length})
          </h4>
          <div className="search-group__list">
            {sectionResults.map((item, i) => (
              <SearchResultCard key={`partial-ts-${item.slug}-${item.section_anchor}-${i}`} item={item} staggerIndex={i} />
            ))}
          </div>
        </section>
      )}

      {momentResults.length > 0 && (
        <section className="search-group">
          <h4 className="search-group__title">
            Key Moments ({momentResults.length})
          </h4>
          <div className="search-group__list">
            {momentResults.map((item, i) => (
              <SearchResultCard key={`partial-km-${item.slug}-${i}`} item={item} staggerIndex={i} />
            ))}
          </div>
        </section>
      )}
    </div>
  );
}
