import { useEffect, useState, useCallback, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import { SearchApi } from '../api/client.js';
import EmailRow from '../components/EmailRow.jsx';
import EmailDetail from '../components/EmailDetail.jsx';
import BulkToolbar from '../components/BulkToolbar.jsx';
import { Skeleton, EmptyState } from '../components/ui';
import useSelection from '../hooks/useSelection.js';
import useListKeyboardNav from '../hooks/useListKeyboardNav.js';
import useSavedSearches from '../hooks/useSavedSearches.js';

const PAGE_SIZE = 50;

function ListSkeleton({ rows = 6 }) {
  return (
    <div className="sv-skeleton-list" aria-hidden="true">
      {Array.from({ length: rows }).map((_, i) => (
        <div className="sv-skeleton-row" key={i}>
          <Skeleton className="h-3 w-3 rounded-full" />
          <Skeleton className="h-3 flex-1" />
          <Skeleton className="h-3 w-16" />
        </div>
      ))}
    </div>
  );
}


export default function SearchResults() {
  const [searchParams] = useSearchParams();
  const q = searchParams.get('q') ?? '';

  const [emails, setEmails] = useState([]);
  const [totalCount, setTotalCount] = useState(null);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [selectedEmail, setSelectedEmail] = useState(null);
  const { selected, toggle, clear, removeIds, selectedIds } = useSelection();
  const focusedId = useListKeyboardNav(emails, (id) => setEmails((prev) => prev.filter((x) => x.id !== id)));
  const { searches: savedSearches, add: addSavedSearch } = useSavedSearches();
  const isSaved = savedSearches.some((s) => s.query === q);

  const handleSave = () => {
    const label = window.prompt('Name this saved search:', q);
    if (label && label.trim()) addSavedSearch(label.trim(), q);
  };

  useEffect(() => {
    setEmails([]);
    setTotalCount(null);
    setPage(1);
    setHasMore(true);
    setError(null);
    setSelectedEmail(null);
    clear();
  }, [q, clear]);

  const fetchPage = useCallback((p) => {
    if (!q.trim()) return;
    setLoading(true);
    SearchApi.query(q, p, PAGE_SIZE)
      .then((r) => {
        setEmails((prev) => p === 1 ? r.items : [...prev, ...r.items]);
        setTotalCount(r.totalCount);
        setHasMore(p < r.totalPages);
        setPage(p);
      })
      .catch(() => setError('Search failed. Please try again.'))
      .finally(() => setLoading(false));
  }, [q]);

  useEffect(() => { fetchPage(1); }, [fetchPage]);

  const sentinelRef = useRef(null);
  useEffect(() => {
    const el = sentinelRef.current;
    if (!el) return;
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting && hasMore && !loading) fetchPage(page + 1);
      },
      { rootMargin: '200px' }
    );
    observer.observe(el);
    return () => observer.disconnect();
  }, [hasMore, loading, page, fetchPage]);

  return (
    <div className="folder-view">
      <div className="folder-view-head saved-search-row">
        <h2 className="folder-view-title">🔍 "{q}"</h2>
        {totalCount !== null && (
          <span className="folder-view-count">{totalCount.toLocaleString()} result{totalCount !== 1 ? 's' : ''}</span>
        )}
        {q.trim() && (
          <button className="saved-search-save-btn" onClick={handleSave} disabled={isSaved}>
            {isSaved ? '★ Saved' : '☆ Save search'}
          </button>
        )}
      </div>

      {!q.trim() && (
        <EmptyState
          title="Search your mail"
          description="Enter a search query above to find emails."
        />
      )}
      {error && <div className="fv-error">{error}</div>}

      <BulkToolbar
        selectedIds={selectedIds}
        onClear={clear}
        onDone={(action, ids) => {
          if (action === 'trash' || action === 'archive') {
            setEmails((prev) => prev.filter((x) => !ids.includes(x.id)));
            removeIds(ids);
          }
        }}
      />

      {q.trim() && (
        <div className={`sv-split${selectedEmail ? ' sv-split--open' : ''}`}>
          <div className="sv-list-pane">
            {loading && emails.length === 0 && !error && <ListSkeleton />}

            {!loading && !error && emails.length === 0 && !hasMore && (
              <EmptyState
                title={`No results for "${q}"`}
                description="Try a different search term or filter."
              />
            )}

            {emails.length > 0 && (
              <table className="email-list">
                <tbody>
                  {emails.map((e) => (
                    <EmailRow
                      key={e.id}
                      email={e}
                      selected={selected.has(e.id)}
                      onToggleSelect={toggle}
                      focused={focusedId === e.id}
                      onOpen={(email) => setSelectedEmail(email)}
                      onRemove={(id) => {
                        setEmails((prev) => prev.filter((x) => x.id !== id));
                        setSelectedEmail((cur) => (cur?.id === id ? null : cur));
                      }}
                    />
                  ))}
                </tbody>
              </table>
            )}

            <div ref={sentinelRef} className="fv-sentinel" />
            {loading && emails.length > 0 && <div className="fv-loading-more">Loading…</div>}
            {!hasMore && emails.length > 0 && (
              <div className="fv-end">— {emails.length.toLocaleString()} results —</div>
            )}
          </div>

          {selectedEmail && (
            <aside className="sv-reading-pane">
              <EmailDetail
                key={selectedEmail.id}
                email={selectedEmail}
                onClose={() => setSelectedEmail(null)}
              />
            </aside>
          )}
        </div>
      )}
    </div>
  );
}
