import { createSignal, For, Show, onMount } from 'solid-js';
import { useSearchParams } from '@solidjs/router';
import { 
  IconSearch, 
  IconFilter, 
  IconBookmark, 
  IconChecklist, 
  IconNotebook, 
  IconFolder,
  IconX,
  IconStar,
  IconEye,
  IconEyeOff,
  IconFileText
} from '@tabler/icons-solidjs';
import { Input } from '@/components/ui/Input';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { SavedSearches } from './SavedSearches';

interface SearchFilters {
  query: string;
  content_type: 'all' | 'bookmarks' | 'tasks' | 'notes' | 'files';
  tags: string[];
  date_range: {
    start: string;
    end: string;
  };
  author: string;
  language: string;
  file_types: string[];
  is_favorite?: boolean;
  is_read?: boolean;
  is_public?: boolean;
  limit: number;
  offset: number;
  search_mode: 'fulltext' | 'semantic' | 'hybrid'; // New field
  threshold: number; // Similarity threshold for semantic search
}

interface SearchResult {
  id: number;
  type: string;
  title: string;
  description: string;
  content: string;
  tags: Array<{ id: number; name: string; color: string }>;
  created_at: string;
  updated_at: string;
  url?: string;
  status?: string;
  priority?: string;
  due_date?: string;
  is_favorite?: boolean;
  is_read?: boolean;
  is_public?: boolean;
  author?: string;
  file_size?: number;
  mime_type?: string;
  file_type?: string;
  progress?: number;
  highlights?: Record<string, string[]>;
  score: number;
  similarity?: number; // Semantic similarity score
}

interface SearchResponse {
  results: SearchResult[];
  total: number;
  query: string;
  filters: SearchFilters;
  took: number;
  suggestions: string[];
  aggregations: Record<string, number>;
}

export const EnhancedSearch = () => {
  const [activeTab, setActiveTab] = createSignal<'search' | 'saved'>('search');
  const [searchQuery, setSearchQuery] = createSignal('');
  const [filters, setFilters] = createSignal<SearchFilters>({
    query: '',
    content_type: 'all',
    tags: [],
    date_range: { start: '', end: '' },
    author: '',
    language: '',
    file_types: [],
    limit: 20,
    offset: 0,
    search_mode: 'fulltext',
    threshold: 0.7
  });
  const [searchResults, setSearchResults] = createSignal<SearchResult[]>([]);
  const [total, setTotal] = createSignal(0);
  const [loading, setLoading] = createSignal(false);
  const [showFilters, setShowFilters] = createSignal(false);
  const [aggregations, setAggregations] = createSignal<Record<string, number>>({});
  const [took, setTook] = createSignal(0);
  const [searchParams] = useSearchParams();

  // API call to search
  const performSearch = async (resetOffset = true) => {
    setLoading(true);
    
    const currentFilters = { ...filters() };
    currentFilters.query = searchQuery();
    
    if (resetOffset) {
      currentFilters.offset = 0;
    }

    try {
      // Try multiple token sources for better compatibility
      const token = localStorage.getItem('token') || 
                    localStorage.getItem('auth_token') || 
                    localStorage.getItem('trackeep_token');
      let response;
      
      if (currentFilters.search_mode === 'semantic') {
        // Use semantic search API
        response = await fetch(`${import.meta.env.VITE_API_URL || 'http://localhost:8080'}/api/v1/search/semantic`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': token ? `Bearer ${token}` : ''
          },
          body: JSON.stringify({
            query: currentFilters.query,
            content_type: currentFilters.content_type,
            limit: currentFilters.limit,
            threshold: currentFilters.threshold
          })
        });

        if (response.ok) {
          const data = await response.json();
          const results = Array.isArray(data?.results) ? data.results : [];
          if (resetOffset) {
            setSearchResults(results);
          } else {
            setSearchResults(prev => [...prev, ...results]);
          }
          setTotal(results.length); // Semantic search doesn't return total count
          setTook(Number(data?.took) || 0);
        }
      } else {
        // Use enhanced full-text search API
        response = await fetch(`${import.meta.env.VITE_API_URL || 'http://localhost:8080'}/api/v1/search/enhanced`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': token ? `Bearer ${token}` : ''
          },
          body: JSON.stringify(currentFilters)
        });

        if (response.ok) {
          const data: SearchResponse = await response.json();
          const results = Array.isArray((data as any)?.results) ? (data as any).results : [];
          if (resetOffset) {
            setSearchResults(results);
          } else {
            setSearchResults(prev => [...prev, ...results]);
          }
          setTotal(Number((data as any)?.total) || results.length);
          setAggregations((data as any)?.aggregations && typeof (data as any).aggregations === 'object' ? (data as any).aggregations : {});
          setTook(Number((data as any)?.took) || 0);
        }
      }

      if (!response.ok) {
        // If unauthorized, fallback to mock data
        if (response.status === 401) {
          console.warn('Search authorization failed, using mock data');
          const mockResults: SearchResult[] = [
            {
              id: 1,
              type: 'bookmark',
              title: `Mock result for "${currentFilters.query}"`,
              description: 'This is a mock search result due to authorization issues',
              content: 'Mock content for demonstration purposes',
              tags: [{ id: 1, name: 'demo', color: '#6b7280' }],
              created_at: new Date().toISOString(),
              updated_at: new Date().toISOString(),
              url: 'https://example.com',
              score: 0.9
            },
            {
              id: 2,
              type: 'note',
              title: `Another mock result for "${currentFilters.query}"`,
              description: 'Another mock search result in demo mode',
              content: 'Additional mock content for search demonstration',
              tags: [{ id: 2, name: 'mock', color: '#3b82f6' }],
              created_at: new Date().toISOString(),
              updated_at: new Date().toISOString(),
              score: 0.8
            }
          ];
          
          if (resetOffset) {
            setSearchResults(mockResults);
          } else {
            setSearchResults(prev => [...prev, ...mockResults]);
          }
          setTotal(mockResults.length);
          setTook(50);
          return;
        }
        throw new Error('Search failed');
      }
    } catch (error) {
      console.error('Search failed:', error);
      // Fallback to mock data on any error
      const mockResults: SearchResult[] = [
        {
          id: 1,
          type: 'bookmark',
          title: `Fallback result for "${currentFilters.query}"`,
          description: 'This is a fallback search result due to API errors',
          content: 'Fallback content for demonstration purposes',
          tags: [{ id: 1, name: 'fallback', color: '#ef4444' }],
          created_at: new Date().toISOString(),
          updated_at: new Date().toISOString(),
          url: 'https://example.com',
          score: 0.7
        }
      ];
      
      if (resetOffset) {
        setSearchResults(mockResults);
      } else {
        setSearchResults(prev => [...prev, ...mockResults]);
      }
      setTotal(mockResults.length);
      setTook(100);
    } finally {
      setLoading(false);
    }
  };

  // Debounced search
  let searchTimeout: number;
  const debouncedSearch = () => {
    clearTimeout(searchTimeout);
    searchTimeout = setTimeout(() => performSearch(), 300);
  };

  // Handle search input
  const handleSearchInput = (value: string) => {
    setSearchQuery(value);
    debouncedSearch();
  };

  // Handle filter changes
  const updateFilter = (key: keyof SearchFilters, value: any) => {
    setFilters(prev => ({ ...prev, [key]: value }));
    setTimeout(() => performSearch(), 100);
  };

  // Add/remove tag filter
  const toggleTag = (tag: string) => {
    const currentTags = filters().tags;
    const newTags = currentTags.includes(tag)
      ? currentTags.filter(t => t !== tag)
      : [...currentTags, tag];
    updateFilter('tags', newTags);
  };

  // Clear all filters
  const clearFilters = () => {
    setFilters({
      query: searchQuery(),
      content_type: 'all',
      tags: [],
      date_range: { start: '', end: '' },
      author: '',
      language: '',
      file_types: [],
      limit: 20,
      offset: 0,
      search_mode: 'fulltext',
      threshold: 0.7
    });
    setTimeout(() => performSearch(), 100);
  };

  // Load more results
  const loadMore = () => {
    setFilters(prev => ({ ...prev, offset: prev.offset + prev.limit }));
    setTimeout(() => performSearch(false), 100);
  };

  // Get icon for content type
  const getIcon = (type: string) => {
    switch (type) {
      case 'bookmark':
        return IconBookmark;
      case 'task':
        return IconChecklist;
      case 'note':
        return IconNotebook;
      case 'file':
        return IconFolder;
      default:
        return IconFileText;
    }
  };

  // Get color for content type
  const getTypeColor = (type: string) => {
    switch (type) {
      case 'bookmark':
        return 'text-green-400';
      case 'task':
        return 'text-yellow-400';
      case 'note':
        return 'text-purple-400';
      case 'file':
        return 'text-orange-400';
      default:
        return 'text-gray-400';
    }
  };

  // Format file size
  const formatFileSize = (bytes?: number) => {
    if (!bytes) return '';
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(1024));
    return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
  };

  // Format date
  const formatDate = (dateString: string) => {
    return new Date(dateString).toLocaleDateString();
  };

  // Get priority color
  const getPriorityColor = (priority?: string) => {
    switch (priority) {
      case 'urgent':
        return 'bg-red-500';
      case 'high':
        return 'bg-orange-500';
      case 'medium':
        return 'bg-yellow-500';
      case 'low':
        return 'bg-green-500';
      default:
        return 'bg-gray-500';
    }
  };

  // Get status color
  const getStatusColor = (status?: string) => {
    switch (status) {
      case 'completed':
        return 'bg-green-500';
      case 'in_progress':
        return 'bg-blue-500';
      case 'pending':
        return 'bg-yellow-500';
      case 'cancelled':
        return 'bg-red-500';
      default:
        return 'bg-gray-500';
    }
  };

  // Initial search on mount (respect URL query/tag params)
  onMount(() => {
    const urlQuery = (searchParams as any).query || '';
    const urlTag = (searchParams as any).tag || '';

    const initialQuery = urlQuery || urlTag || '';

    if (initialQuery) {
      setSearchQuery(initialQuery);
      setFilters(prev => ({
        ...prev,
        query: initialQuery,
        tags: urlTag ? [urlTag] : prev.tags,
      }));
    }

    performSearch();
  });

  return (
    <div class="space-y-6">
      {/* Header with Tabs */}
      <div class="space-y-4">
        <div class="flex items-center justify-between">
          <div>
            <h1 class="text-3xl font-bold">Enhanced Search</h1>
            <p class="text-muted-foreground mt-2">
              Search across all your content with powerful filters and AI-powered discovery
            </p>
          </div>
        </div>

        {/* Tabs */}
        <div class="border-b">
          <nav class="flex space-x-8">
            <button
              class={`py-2 px-1 border-b-2 font-medium text-sm transition-colors ${
                activeTab() === 'search'
                  ? 'border-primary text-primary'
                  : 'border-transparent text-muted-foreground hover:text-foreground'
              }`}
              onClick={() => setActiveTab('search')}
            >
              <div class="flex items-center gap-2">
                <IconSearch class="size-4" />
                Search
              </div>
            </button>
            <button
              class={`py-2 px-1 border-b-2 font-medium text-sm transition-colors ${
                activeTab() === 'saved'
                  ? 'border-primary text-primary'
                  : 'border-transparent text-muted-foreground hover:text-foreground'
              }`}
              onClick={() => setActiveTab('saved')}
            >
              <div class="flex items-center gap-2">
                <IconBookmark class="size-4" />
                Saved Searches
              </div>
            </button>
          </nav>
        </div>
      </div>

      {/* Tab Content */}
      <Show when={activeTab() === 'search'}>
        <div class="space-y-6">
          {/* Search Input */}
          <div class="space-y-4">
            <div class="relative">
              <IconSearch class="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground size-5" />
              <Input
                type="text"
                placeholder="Search across all your content..."
                value={searchQuery()}
                onInput={(e: any) => handleSearchInput(e.target?.value || '')}
                class="pl-10 pr-12 h-12 text-lg"
              />
              <Button
                variant="ghost"
                size="sm"
                onClick={() => setShowFilters(!showFilters())}
                class="absolute right-2 top-1/2 transform -translate-y-1/2"
              >
                <IconFilter class="size-4" />
              </Button>
            </div>

            {/* Search Stats */}
            <Show when={total() > 0}>
              <div class="flex items-center justify-between text-sm text-muted-foreground">
                <span>Found {total()} results in {took()}ms</span>
                <div class="flex items-center gap-4">
                  <For each={Object.entries(aggregations())}>
                    {([type, count]) => (
                      <span>{type}: {count}</span>
                    )}
                  </For>
                </div>
              </div>
            </Show>
          </div>

          {/* Filters Panel */}
          <Show when={showFilters()}>
            <Card class="p-6 space-y-4">
              <div class="flex items-center justify-between">
                <h3 class="text-lg font-semibold">Filters</h3>
                <div class="flex gap-2">
                  <Button variant="outline" size="sm" onClick={clearFilters}>
                    Clear All
                  </Button>
                  <Button variant="ghost" size="sm" onClick={() => setShowFilters(false)}>
                    <IconX class="size-4" />
                  </Button>
                </div>
              </div>

              <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {/* Search Mode */}
                <div class="space-y-2">
                  <label class="text-sm font-medium">Search Mode</label>
                  <select
                    value={filters().search_mode}
                    onChange={(e: any) => updateFilter('search_mode', e.target.value)}
                    class="w-full p-2 border rounded-md bg-background"
                  >
                    <option value="fulltext">Full-Text Search</option>
                    <option value="semantic">Semantic Search</option>
                    <option value="hybrid">Hybrid (Coming Soon)</option>
                  </select>
                </div>

                {/* Similarity Threshold (for semantic search) */}
                <Show when={filters().search_mode === 'semantic'}>
                  <div class="space-y-2">
                    <label class="text-sm font-medium">Similarity Threshold: {filters().threshold.toFixed(2)}</label>
                    <input
                      type="range"
                      min="0.1"
                      max="1.0"
                      step="0.1"
                      value={filters().threshold}
                      onChange={(e: any) => updateFilter('threshold', parseFloat(e.target.value))}
                      class="w-full"
                    />
                    <div class="flex justify-between text-xs text-muted-foreground">
                      <span>More results</span>
                      <span>More precise</span>
                    </div>
                  </div>
                </Show>

                {/* Content Type Filter */}
                <div class="space-y-2">
                  <label class="text-sm font-medium">Content Type</label>
                  <select
                    value={filters().content_type}
                    onChange={(e: any) => updateFilter('content_type', e.target.value)}
                    class="w-full p-2 border rounded-md bg-background"
                  >
                    <option value="all">All Types</option>
                    <option value="bookmarks">Bookmarks</option>
                    <option value="tasks">Tasks</option>
                    <option value="notes">Notes</option>
                    <option value="files">Files</option>
                  </select>
                </div>

                {/* Date Range */}
                <div class="space-y-2">
                  <label class="text-sm font-medium">Date Range</label>
                  <div class="flex gap-2">
                    <Input
                      type="date"
                      value={filters().date_range.start}
                      onChange={(e: any) => updateFilter('date_range', { 
                        ...filters().date_range, 
                        start: e.target?.value || '' 
                      })}
                      placeholder="Start date"
                    />
                    <Input
                      type="date"
                      value={filters().date_range.end}
                      onChange={(e: any) => updateFilter('date_range', { 
                        ...filters().date_range, 
                        end: e.target?.value || '' 
                      })}
                      placeholder="End date"
                    />
                  </div>
                </div>

                {/* Author Filter */}
                <div class="space-y-2">
                  <label class="text-sm font-medium">Author</label>
                  <Input
                    type="text"
                    value={filters().author}
                    onChange={(e: any) => updateFilter('author', e.target?.value || '')}
                    placeholder="Filter by author"
                  />
                </div>

                {/* Boolean Filters */}
                <div class="space-y-2">
                  <label class="text-sm font-medium">Quick Filters</label>
                  <div class="flex flex-wrap gap-2">
                    <Button
                      variant={filters().is_favorite ? "default" : "outline"}
                      size="sm"
                      onClick={() => updateFilter('is_favorite', !filters().is_favorite)}
                    >
                      <IconStar class="size-3 mr-1" />
                      Favorites
                    </Button>
                    <Button
                      variant={filters().is_read ? "default" : "outline"}
                      size="sm"
                      onClick={() => updateFilter('is_read', !filters().is_read)}
                    >
                      <IconEye class="size-3 mr-1" />
                      Read
                    </Button>
                    <Button
                      variant={filters().is_public ? "default" : "outline"}
                      size="sm"
                      onClick={() => updateFilter('is_public', !filters().is_public)}
                    >
                      <IconEyeOff class="size-3 mr-1" />
                      Public
                    </Button>
                  </div>
                </div>
              </div>

              {/* Active Tags */}
              <Show when={filters().tags.length > 0}>
                <div class="space-y-2">
                  <label class="text-sm font-medium">Active Tags</label>
                  <div class="flex flex-wrap gap-2">
                    <For each={filters().tags}>
                      {(tag) => (
                        <span class="inline-block bg-secondary text-secondary-foreground text-xs px-2 py-1 rounded cursor-pointer hover:bg-secondary/80" onClick={() => toggleTag(tag)}>
                          {tag}
                          <IconX class="inline size-3 ml-1" />
                        </span>
                      )}
                    </For>
                  </div>
                </div>
              </Show>
            </Card>
          </Show>

          {/* Search Results */}
          <div class="space-y-4">
            <Show when={loading()}>
              <div class="text-center py-8">
                <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto"></div>
                <p class="mt-2 text-muted-foreground">Searching...</p>
              </div>
            </Show>

            <Show when={!loading() && searchResults().length === 0 && searchQuery()}>
              <div class="text-center py-8 text-muted-foreground">
                <IconSearch class="size-12 mx-auto mb-4 opacity-50" />
                <h3 class="text-lg font-medium mb-2">No results found</h3>
                <p>Try adjusting your search terms or filters</p>
              </div>
            </Show>

            <Show when={!loading() && searchResults().length > 0}>
              <div class="space-y-4">
                <For each={searchResults()}>
                  {(result) => {
                    const Icon = getIcon(result.type);
                    return (
                      <Card class="p-6 hover:shadow-md transition-shadow">
                        <div class="flex items-start gap-4">
                          {/* Type Icon */}
                          <div class={`p-2 rounded-lg bg-muted ${getTypeColor(result.type)}`}>
                            <Icon class="size-5" />
                          </div>

                          {/* Content */}
                          <div class="flex-1 min-w-0">
                            <div class="flex items-start justify-between gap-4">
                              <div class="flex-1">
                                <h3 class="text-lg font-semibold mb-1">{result.title}</h3>
                                <p class="text-muted-foreground mb-2">{result.description}</p>
                                
                                {/* Content preview */}
                                <Show when={result.content}>
                                  <p class="text-sm text-muted-foreground line-clamp-2 mb-3">
                                    {result.content.substring(0, 200)}...
                                  </p>
                                </Show>

                                {/* Tags */}
                                <Show when={result.tags.length > 0}>
                                  <div class="flex flex-wrap gap-1 mb-3">
                                    <For each={result.tags}>
                                      {(tag) => (
                                        <span 
                                          class="inline-block bg-secondary text-secondary-foreground text-xs px-2 py-1 rounded cursor-pointer hover:bg-secondary/80"
                                          onClick={() => toggleTag(tag.name)}
                                        >
                                          {tag.name}
                                        </span>
                                      )}
                                    </For>
                                  </div>
                                </Show>

                                {/* Metadata */}
                                <div class="flex items-center gap-4 text-xs text-muted-foreground">
                                  <span class="capitalize">{result.type}</span>
                                  <span>Created {formatDate(result.created_at)}</span>
                                  <Show when={result.updated_at !== result.created_at}>
                                    <span>Updated {formatDate(result.updated_at)}</span>
                                  </Show>
                                  <Show when={result.author}>
                                    <span>By {result.author}</span>
                                  </Show>
                                  <Show when={result.file_size}>
                                    <span>{formatFileSize(result.file_size)}</span>
                                  </Show>
                                  <Show when={result.score}>
                                    <span>Score: {result.score.toFixed(1)}</span>
                                  </Show>
                                  <Show when={result.similarity !== undefined}>
                                    <span>Similarity: {(result.similarity! * 100).toFixed(1)}%</span>
                                  </Show>
                                </div>
                              </div>

                              {/* Status/Priority Indicators */}
                              <div class="flex flex-col items-end gap-2">
                                <Show when={result.status}>
                                  <span class={`inline-block ${getStatusColor(result.status)} text-white text-xs px-2 py-1 rounded`}>
                                    {result.status}
                                  </span>
                                </Show>
                                <Show when={result.priority}>
                                  <span class={`inline-block ${getPriorityColor(result.priority)} text-white text-xs px-2 py-1 rounded`}>
                                    {result.priority}
                                  </span>
                                </Show>
                                <Show when={result.is_favorite}>
                                  <IconStar class="size-4 text-yellow-500 fill-current" />
                                </Show>
                                <Show when={result.is_read !== undefined}>
                                  {result.is_read ? (
                                    <IconEye class="size-4 text-green-500" />
                                  ) : (
                                    <IconEyeOff class="size-4 text-gray-400" />
                                  )}
                                </Show>
                                <Show when={result.progress !== undefined}>
                                  <div class="text-xs text-muted-foreground">
                                    {result.progress}%
                                  </div>
                                </Show>
                              </div>
                            </div>

                            {/* URL for bookmarks */}
                            <Show when={result.url}>
                              <div class="mt-3">
                                <a 
                                  href={result.url} 
                                  target="_blank" 
                                  rel="noopener noreferrer"
                                  class="text-sm text-blue-500 hover:underline"
                                >
                                  {result.url}
                                </a>
                              </div>
                            </Show>
                          </div>
                        </div>
                      </Card>
                    );
                  }}
                </For>

                {/* Load More */}
                <Show when={searchResults().length < total()}>
                  <div class="text-center">
                    <Button 
                      variant="outline" 
                      onClick={loadMore}
                      disabled={loading()}
                    >
                      Load More Results
                    </Button>
                  </div>
                </Show>
              </div>
            </Show>
          </div>
        </div>
      </Show>

      <Show when={activeTab() === 'saved'}>
        <SavedSearches />
      </Show>
    </div>
  );
};
