import { type ReactElement } from 'react';
import styled from '@lilith/ui-styled-components';
import { Search } from 'lucide-react';
import type { MessageSearchHit } from '@/types';

const List = styled.ul`
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
`;

const Item = styled.li<{ $selected: boolean }>`
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px 16px;
  cursor: pointer;
  border-bottom: 1px solid #1e1e2a;
  background: ${({ $selected }) => ($selected ? 'rgba(201,168,76,0.12)' : 'transparent')};
  transition: background 0.1s;

  &:hover {
    background: ${({ $selected }) => ($selected ? 'rgba(201,168,76,0.14)' : '#13131a')};
  }
`;

const Who = styled.span<{ $selected: boolean }>`
  font-size: 13px;
  font-weight: 600;
  color: ${({ $selected }) => ($selected ? '#c9a84c' : '#e0e0f0')};
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
`;

const Snippet = styled.span`
  font-size: 11px;
  color: #b0b0c0;
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;

  mark {
    background: rgba(201,168,76,0.3);
    color: #f0e0b0;
    padding: 0 1px;
    border-radius: 2px;
  }
`;

const Meta = styled.span`
  font-size: 10px;
  color: #8a8a9a;
`;

const LoadMoreRow = styled.div`
  padding: 10px 16px;
  border-top: 1px solid #1e1e2a;
`;

const LoadMoreButton = styled.button`
  width: 100%;
  padding: 7px 0;
  font-size: 11px;
  font-weight: 600;
  color: #c9a84c;
  background: rgba(201,168,76,0.08);
  border: 1px solid rgba(201,168,76,0.25);
  border-radius: 5px;
  cursor: pointer;
  transition: background 0.1s, border-color 0.1s;

  &:hover {
    background: rgba(201,168,76,0.14);
    border-color: rgba(201,168,76,0.4);
  }

  &:disabled {
    opacity: 0.5;
    cursor: default;
  }
`;

function formatDate(iso: string): string {
  const d = new Date(iso);
  return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
}

// ts_headline renders matches wrapped in « … » — convert to <mark> spans.
function renderSnippet(snippet: string): ReactElement {
  const parts = snippet.split(/(«[^»]*»)/g);
  return (
    <>
      {parts.map((part, i) => {
        if (part.startsWith('«') && part.endsWith('»')) {
          return <mark key={i}>{part.slice(1, -1)}</mark>;
        }
        return <span key={i}>{part}</span>;
      })}
    </>
  );
}

interface SearchResultsProps {
  hits: readonly MessageSearchHit[];
  selectedConversationId: string | null;
  hasMore: boolean;
  isLoadingMore: boolean;
  onLoadMore: () => void;
  onSelect: (conversationId: string, messageId: string) => void;
}

export function SearchResults({
  hits,
  selectedConversationId,
  hasMore,
  isLoadingMore,
  onLoadMore,
  onSelect,
}: SearchResultsProps): ReactElement {
  if (hits.length === 0) {
    return (
      <div style={{ padding: 20, fontSize: 12, color: '#8a8a9a', textAlign: 'center' }}>
        <Search size={18} style={{ opacity: 0.5, marginBottom: 6 }} />
        <div>No matching messages</div>
      </div>
    );
  }

  return (
    <>
      <List role="listbox" aria-label="Search results">
        {hits.map((hit) => {
          const who = hit.message.isFromMe
            ? 'Me'
            : hit.message.fromHandle || 'Unknown';
          const isSelected = hit.message.conversationId === selectedConversationId;
          return (
            <Item
              key={hit.message.id}
              $selected={isSelected}
              onClick={() => onSelect(hit.message.conversationId, hit.message.id)}
              role="option"
              aria-selected={isSelected}
              tabIndex={0}
              onKeyDown={(e) => {
                if (e.key === 'Enter' || e.key === ' ') {
                  e.preventDefault();
                  onSelect(hit.message.conversationId, hit.message.id);
                }
              }}
            >
              <Who $selected={isSelected}>{who}</Who>
              <Snippet>{renderSnippet(hit.snippet)}</Snippet>
              <Meta>{formatDate(hit.message.sentAt)}</Meta>
            </Item>
          );
        })}
      </List>
      {hasMore && (
        <LoadMoreRow>
          <LoadMoreButton onClick={onLoadMore} disabled={isLoadingMore}>
            {isLoadingMore ? 'Loading…' : 'Load more'}
          </LoadMoreButton>
        </LoadMoreRow>
      )}
    </>
  );
}
