import { useState, useEffect, useRef } from 'react';
import { Input, Spin, Button, Grid, Typography } from 'antd';
import type { InputRef } from 'antd';
import { ReloadOutlined } from '@ant-design/icons';
import { useDebounce } from '@/hooks/useDebounce';
import { useDocsSearch } from '@/hooks/useDocsSearch';
import type { DocSearchResult } from '@/hooks/useDocsSearch';

const { Text } = Typography;

export default function DocsSearchOverlay() {
  const [query, setQuery] = useState('');
  const debouncedQuery = useDebounce(query, 300);
  const inputRef = useRef<InputRef>(null);
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;

  const { loading, error, indexReady, results, loadIndex, search, retry } =
    useDocsSearch();

  // Load index on first mount
  useEffect(() => {
    loadIndex().catch(() => {/* error state handled by hook */});
  }, [loadIndex]);

  // Autofocus after index loads
  useEffect(() => {
    if (indexReady) {
      setTimeout(() => inputRef.current?.focus(), 100);
    }
  }, [indexReady]);

  // Search on debounced query change OR when index becomes ready
  useEffect(() => {
    search(debouncedQuery);
  }, [debouncedQuery, search, indexReady]);

  // ---- Loading state ----
  if (loading && !indexReady) {
    return (
      <div style={{ textAlign: 'center', padding: '16px 0' }}>
        <Spin size="small" />
        <Text style={{ color: 'rgba(255,255,255,0.6)', marginLeft: 8 }}>
          Loading docs index...
        </Text>
      </div>
    );
  }

  // ---- Error state ----
  if (error) {
    return (
      <div style={{ textAlign: 'center', padding: '16px 0' }}>
        <Text style={{ color: '#ff4d4f' }}>{error}</Text>
        <br />
        <Button
          size="small"
          icon={<ReloadOutlined />}
          onClick={retry}
          style={{ marginTop: 8 }}
        >
          Retry
        </Button>
      </div>
    );
  }

  const qrSize = isMobile ? 100 : 120;

  return (
    <div>
      <Input
        ref={inputRef}
        placeholder="Search documentation..."
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        allowClear
        autoFocus
        style={{
          background: 'rgba(255,255,255,0.08)',
          border: '1px solid rgba(255,255,255,0.15)',
          color: '#fff',
          borderRadius: 6,
        }}
      />

      <div
        style={{
          marginTop: 8,
          maxHeight: '55vh',
          overflowY: 'auto',
          WebkitOverflowScrolling: 'touch',
        }}
      >
        {/* Hint states */}
        {!query && results.length === 0 && (
          <Text
            style={{
              color: 'rgba(255,255,255,0.4)',
              display: 'block',
              padding: '12px 0',
              textAlign: 'center',
              fontSize: 13,
            }}
          >
            Type at least 2 characters to search
          </Text>
        )}

        {query && debouncedQuery.length >= 2 && results.length === 0 && !loading && (
          <Text
            style={{
              color: 'rgba(255,255,255,0.4)',
              display: 'block',
              padding: '12px 0',
              textAlign: 'center',
              fontSize: 13,
            }}
          >
            No results found
          </Text>
        )}

        {/* Results */}
        {results.map((r, i) => (
          <ResultCard key={i} result={r} query={debouncedQuery} qrSize={qrSize} />
        ))}
      </div>
    </div>
  );
}

// ---- Result card ----

function ResultCard({
  result,
  query,
  qrSize,
}: {
  result: DocSearchResult;
  query: string;
  qrSize: number;
}) {
  const highlighted = highlightSnippet(result.snippet, query);

  return (
    <div
      style={{
        display: 'flex',
        gap: 10,
        padding: '10px 12px',
        marginBottom: 6,
        background: 'rgba(255,255,255,0.06)',
        borderRadius: 8,
        border: '1px solid rgba(255,255,255,0.1)',
      }}
    >
      {/* Text content */}
      <div style={{ flex: 1, minWidth: 0 }}>
        <a
          href={result.docUrl}
          target="_blank"
          rel="noopener noreferrer"
          style={{
            color: '#69b1ff',
            fontWeight: 600,
            fontSize: 14,
            textDecoration: 'none',
            display: 'block',
            overflow: 'hidden',
            textOverflow: 'ellipsis',
            whiteSpace: 'nowrap',
          }}
        >
          {result.title}
        </a>

        <div
          style={{
            color: 'rgba(255,255,255,0.7)',
            fontSize: 12,
            lineHeight: 1.5,
            marginTop: 4,
            wordBreak: 'break-word',
          }}
          dangerouslySetInnerHTML={{ __html: highlighted }}
        />

        <Text
          style={{
            color: 'rgba(255,255,255,0.3)',
            fontSize: 11,
            marginTop: 4,
            display: 'block',
          }}
        >
          {result.location}
        </Text>
      </div>

      {/* QR code */}
      <div style={{ flexShrink: 0 }}>
        <img
          src={result.qrUrl}
          alt="QR"
          width={qrSize}
          height={qrSize}
          loading="lazy"
          style={{
            borderRadius: 4,
            background: '#fff',
          }}
        />
      </div>
    </div>
  );
}

// ---- Highlight helper ----

function highlightSnippet(snippet: string, query: string): string {
  if (!query || query.length < 2) return escapeHtml(snippet);
  const escaped = escapeHtml(snippet);
  const escapedQuery = escapeRegex(query);
  const regex = new RegExp(`(${escapedQuery})`, 'gi');
  return escaped.replace(
    regex,
    '<mark style="background:#e2b714;color:#000;border-radius:2px;padding:0 1px">$1</mark>',
  );
}

function escapeHtml(str: string): string {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}

function escapeRegex(str: string): string {
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
