'use client';

import { useState, useEffect, useRef, useCallback } from 'react';
import { authorApi } from '../../lib/api';
import { Author } from '../../types/api';

interface AuthorSelectorProps {
  value: string;
  onChange: (authorName: string, authorId?: string) => void;
  placeholder?: string;
  error?: string;
  disabled?: boolean;
  required?: boolean;
  label?: string;
}

export default function AuthorSelector({
  value,
  onChange,
  placeholder = 'Enter or select an author',
  error,
  disabled = false,
  required = false,
  label = 'Author'
}: AuthorSelectorProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [authors, setAuthors] = useState<Author[]>([]);
  const [loading, setLoading] = useState(false);
  const [inputValue, setInputValue] = useState(value || '');

  const inputRef = useRef<HTMLInputElement>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);
  const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);

  // Search authors dynamically based on input
  const searchAuthors = useCallback(async (query: string) => {
    try {
      setLoading(true);

      if (!query.trim()) {
        // If empty query, load recent/popular authors
        const result = await authorApi.getAuthors({ page: 0, size: 20, sortBy: 'name', sortDir: 'asc' });
        setAuthors(result.content);
      } else {
        // Search by name
        const result = await authorApi.searchAuthorsByName(query, { page: 0, size: 20 });
        setAuthors(result.content);
      }
    } catch (error) {
      console.error('Failed to search authors:', error);
      setAuthors([]);
    } finally {
      setLoading(false);
    }
  }, []);

  // Debounced search effect
  useEffect(() => {
    // Clear existing timer
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current);
    }

    // Only search when dropdown is open
    if (isOpen) {
      // Set new timer for debounced search
      debounceTimerRef.current = setTimeout(() => {
        searchAuthors(inputValue);
      }, 300); // 300ms debounce delay
    }

    // Cleanup timer on unmount
    return () => {
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }
    };
  }, [inputValue, isOpen, searchAuthors]);

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

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

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

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = e.target.value;
    setInputValue(newValue);
    setIsOpen(true);

    // Call onChange for free-form text entry (new author)
    onChange(newValue);
  };

  const handleAuthorSelect = (author: Author) => {
    setInputValue(author.name);
    setIsOpen(false);
    onChange(author.name, author.id);
  };

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

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Escape') {
      setIsOpen(false);
    } else if (e.key === 'ArrowDown' && !isOpen) {
      setIsOpen(true);
    }
  };

  return (
    <div className="relative" ref={dropdownRef}>
      {label && (
        <label className="block text-sm font-medium theme-header mb-2">
          {label}{required && ' *'}
        </label>
      )}
      
      <div className="relative">
        <input
          ref={inputRef}
          type="text"
          value={inputValue}
          onChange={handleInputChange}
          onFocus={handleInputFocus}
          onKeyDown={handleKeyDown}
          placeholder={placeholder}
          disabled={disabled}
          required={required}
          className={`w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:border-transparent transition-colors ${
            error
              ? 'border-red-300 focus:ring-red-500 theme-error'
              : 'theme-border focus:ring-theme-accent focus:theme-accent-border'
          } ${disabled ? 'theme-disabled' : 'theme-input'}`}
          aria-expanded={isOpen}
          aria-haspopup="listbox"
          role="combobox"
        />
        
        {/* Dropdown arrow */}
        <div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
          <svg
            className={`w-4 h-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 className="absolute z-50 w-full mt-1 theme-card theme-shadow border theme-border rounded-md max-h-60 overflow-auto">
          {loading ? (
            <div className="px-3 py-2 text-sm theme-text text-center">
              Searching authors...
            </div>
          ) : authors.length > 0 ? (
            <>
              {/* Search results */}
              <div className="py-1">
                {authors.map((author) => (
                  <button
                    key={author.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"
                    onClick={() => handleAuthorSelect(author)}
                  >
                    <span>{author.name}</span>
                    <span className="text-xs theme-text-muted">
                      {author.storyCount} {author.storyCount === 1 ? 'story' : 'stories'}
                    </span>
                  </button>
                ))}
              </div>

              {/* New author option if input doesn't match exactly */}
              {inputValue.trim() && !authors.find(a => a.name.toLowerCase() === inputValue.toLowerCase()) && (
                <>
                  <div className="border-t theme-border"></div>
                  <div className="py-1">
                    <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());
                      }}
                    >
                      <span className="font-medium">Create new author:</span> "{inputValue.trim()}"
                    </button>
                  </div>
                </>
              )}
            </>
          ) : inputValue.trim() ? (
            /* No matches, show create new option */
            <div className="py-1">
              <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());
                }}
              >
                <span className="font-medium">Create new author:</span> "{inputValue.trim()}"
              </button>
            </div>
          ) : (
            /* Empty state - show prompt */
            <div className="px-3 py-2 text-sm theme-text-muted text-center">
              Type to search for authors or create a new one
            </div>
          )}
        </div>
      )}

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