'use client';

import { useState, useEffect, useRef } from 'react';
import { seriesApi, storyApi } from '../../lib/api';
import { Series } from '../../types/api';

interface SeriesSelectorProps {
  value: string;
  onChange: (seriesName: string, seriesId?: string) => void;
  placeholder?: string;
  error?: string;
  disabled?: boolean;
  required?: boolean;
  label?: string;
  authorId?: string; // Optional author ID to prioritize that author's series
}

export default function SeriesSelector({
  value,
  onChange,
  placeholder = 'Enter or select a series',
  error,
  disabled = false,
  required = false,
  label = 'Series',
  authorId
}: SeriesSelectorProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [series, setSeries] = useState<Series[]>([]);
  const [filteredSeries, setFilteredSeries] = useState<Series[]>([]);
  const [loading, setLoading] = useState(false);
  const [inputValue, setInputValue] = useState(value || '');
  const [authorSeriesMap, setAuthorSeriesMap] = useState<Record<string, string[]>>({});
  
  const inputRef = useRef<HTMLInputElement>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);

  // Load series and author-series mappings when component mounts or when dropdown opens
  useEffect(() => {
    const loadSeriesData = async () => {
      try {
        setLoading(true);
        
        // Load all series
        const seriesResult = await seriesApi.getSeries({ page: 0, size: 100 }); // Get first 100 series
        setSeries(seriesResult.content);
        
        // Load some recent stories to build author-series mapping
        // This gives us a sample of which authors have written in which series
        try {
          const storiesResult = await storyApi.getStories({ page: 0, size: 200 }); // Get recent stories
          const newAuthorSeriesMap: Record<string, string[]> = {};
          
          storiesResult.content.forEach(story => {
            if (story.authorId && story.seriesName) {
              if (!newAuthorSeriesMap[story.authorId]) {
                newAuthorSeriesMap[story.authorId] = [];
              }
              if (!newAuthorSeriesMap[story.authorId].includes(story.seriesName)) {
                newAuthorSeriesMap[story.authorId].push(story.seriesName);
              }
            }
          });
          
          setAuthorSeriesMap(newAuthorSeriesMap);
        } catch (error) {
          console.error('Failed to load author-series mapping:', error);
          // Continue without author prioritization if this fails
        }
      } catch (error) {
        console.error('Failed to load series:', error);
      } finally {
        setLoading(false);
      }
    };

    if (isOpen && series.length === 0) {
      loadSeriesData();
    }
  }, [isOpen, series.length]);

  // Update internal value when prop changes
  useEffect(() => {
    setInputValue(value || '');
  }, [value]);

  // Filter and sort series based on input and author priority
  useEffect(() => {
    let filtered: Series[];
    
    if (!inputValue.trim()) {
      filtered = [...series];
    } else {
      filtered = series.filter(s =>
        s.name.toLowerCase().includes(inputValue.toLowerCase())
      );
    }
    
    // Sort series: prioritize those from the current author if authorId is provided
    if (authorId && authorSeriesMap[authorId]) {
      const authorSeriesNames = authorSeriesMap[authorId];
      
      filtered.sort((a, b) => {
        const aIsAuthorSeries = authorSeriesNames.includes(a.name);
        const bIsAuthorSeries = authorSeriesNames.includes(b.name);
        
        if (aIsAuthorSeries && !bIsAuthorSeries) return -1; // a first
        if (!aIsAuthorSeries && bIsAuthorSeries) return 1;  // b first
        
        // If both or neither are author series, sort alphabetically
        return a.name.localeCompare(b.name);
      });
    } else {
      // No author prioritization, just sort alphabetically
      filtered.sort((a, b) => a.name.localeCompare(b.name));
    }
    
    setFilteredSeries(filtered);
  }, [inputValue, series, authorId, authorSeriesMap]);

  // Handle clicks outside to close dropdown
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(event.target as Node) &&
        !inputRef.current?.contains(event.target as Node)
      ) {
        setIsOpen(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = e.target.value;
    setInputValue(newValue);
    setIsOpen(true);
    
    // If user is typing and it doesn't match any existing series exactly, clear the seriesId
    onChange(newValue, undefined);
  };

  const handleInputFocus = () => {
    setIsOpen(true);
  };

  const handleSeriesSelect = (selectedSeries: Series) => {
    setInputValue(selectedSeries.name);
    setIsOpen(false);
    onChange(selectedSeries.name, selectedSeries.id);
    inputRef.current?.blur();
  };

  const handleInputBlur = () => {
    // Small delay to allow clicks on dropdown items
    setTimeout(() => {
      if (!dropdownRef.current?.contains(document.activeElement)) {
        setIsOpen(false);
      }
    }, 200);
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Escape') {
      setIsOpen(false);
      inputRef.current?.blur();
    }
  };

  return (
    <div className="relative">
      {label && (
        <label className="block text-sm font-medium theme-header mb-2">
          {label}
          {required && <span className="text-red-500 ml-1">*</span>}
        </label>
      )}
      
      <div className="relative">
        <input
          ref={inputRef}
          type="text"
          value={inputValue}
          onChange={handleInputChange}
          onFocus={handleInputFocus}
          onBlur={handleInputBlur}
          onKeyDown={handleKeyDown}
          placeholder={placeholder}
          disabled={disabled}
          className={`w-full px-3 py-2 border rounded-lg theme-card theme-text theme-border focus:outline-none focus:ring-2 focus:ring-theme-accent focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed ${
            error ? 'border-red-500 focus:ring-red-500' : ''
          }`}
        />
        
        {/* Dropdown Arrow */}
        <div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
          <svg
            className={`h-4 w-4 theme-text transition-transform ${isOpen ? 'rotate-180' : ''}`}
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
          </svg>
        </div>
      </div>

      {/* Dropdown */}
      {isOpen && (
        <div
          ref={dropdownRef}
          className="absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border theme-border rounded-lg shadow-lg max-h-60 overflow-y-auto"
        >
          {loading ? (
            <div className="px-3 py-2 text-sm theme-text">Loading series...</div>
          ) : (
            <>
              {filteredSeries.length > 0 ? (
                filteredSeries.map((s) => {
                  const isAuthorSeries = authorId && authorSeriesMap[authorId]?.includes(s.name);
                  
                  return (
                    <button
                      key={s.id}
                      type="button"
                      className={`w-full text-left px-3 py-2 text-sm theme-text hover:theme-accent-light hover:theme-accent-text transition-colors flex items-center justify-between ${
                        isAuthorSeries ? 'bg-blue-50 dark:bg-blue-900/20 border-l-2 border-blue-400' : ''
                      }`}
                      onClick={() => handleSeriesSelect(s)}
                    >
                      <div className="flex items-center gap-2">
                        <span>{s.name}</span>
                        {isAuthorSeries && (
                          <span className="text-xs px-1.5 py-0.5 rounded-full bg-blue-100 dark:bg-blue-800 text-blue-800 dark:text-blue-100">
                            Author
                          </span>
                        )}
                      </div>
                      <span className="text-xs text-gray-500">
                        {s.storyCount} {s.storyCount === 1 ? 'story' : 'stories'}
                      </span>
                    </button>
                  );
                })
              ) : (
                <>
                  {inputValue.trim() && (
                    <button
                      type="button"
                      className="w-full text-left px-3 py-2 text-sm theme-text hover:theme-accent-light hover:theme-accent-text transition-colors"
                      onClick={() => {
                        setIsOpen(false);
                        onChange(inputValue.trim());
                      }}
                    >
                      Create new series: &quot;{inputValue.trim()}&quot;
                    </button>
                  )}
                  {!inputValue.trim() && (
                    <div className="px-3 py-2 text-sm text-gray-500">No series found</div>
                  )}
                </>
              )}
              
              {inputValue.trim() && !filteredSeries.some(s => s.name.toLowerCase() === inputValue.toLowerCase()) && (
                <button
                  type="button"
                  className="w-full text-left px-3 py-2 text-sm theme-text hover:theme-accent-light hover:theme-accent-text transition-colors"
                  onClick={() => {
                    setIsOpen(false);
                    onChange(inputValue.trim());
                  }}
                >
                  Use &quot;{inputValue.trim()}&quot;
                </button>
              )}
            </>
          )}
        </div>
      )}

      {error && (
        <p className="mt-1 text-sm text-red-600 dark:text-red-400">{error}</p>
      )}
    </div>
  );
}