import React, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
import { createPortal } from 'react-dom';
import { useSelector } from 'react-redux';
import { PlusOutlined, TagOutlined } from '@ant-design/icons';
import { RootState } from '@/app/store';
import { IProjectTask } from '@/types/project/projectTasksViewModel.types';
import { ITaskLabel } from '@/types/tasks/taskLabel.types';
import { useSocket } from '@/socket/socketContext';
import { SocketEvents } from '@/shared/socket-events';
import { useAuthService } from '@/hooks/useAuth';
import { Button, Checkbox, Tag } from '@/components';

interface LabelsSelectorProps {
  task: IProjectTask;
  isDarkMode?: boolean;
}

const LabelsSelector: React.FC<LabelsSelectorProps> = ({ 
  task, 
  isDarkMode = false 
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 });
  const dropdownRef = useRef<HTMLDivElement>(null);
  const buttonRef = useRef<HTMLButtonElement>(null);
  const searchInputRef = useRef<HTMLInputElement>(null);

  const { labels } = useSelector((state: RootState) => state.taskLabelsReducer);
  const currentSession = useAuthService().getCurrentSession();
  const { socket } = useSocket();

  const filteredLabels = useMemo(() => {
    return (labels as ITaskLabel[])?.filter(label =>
      label.name?.toLowerCase().includes(searchQuery.toLowerCase())
    ) || [];
  }, [labels, searchQuery]);

  // Update dropdown position
  const updateDropdownPosition = useCallback(() => {
    if (buttonRef.current) {
      const rect = buttonRef.current.getBoundingClientRect();
      setDropdownPosition({
        top: rect.bottom + window.scrollY + 2,
        left: rect.left + window.scrollX,
      });
    }
  }, []);

  // Close dropdown when clicking outside and handle scroll
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node) &&
          buttonRef.current && !buttonRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    const handleScroll = () => {
      if (isOpen) {
        // Check if the button is still visible in the viewport
        if (buttonRef.current) {
          const rect = buttonRef.current.getBoundingClientRect();
          const isVisible = rect.top >= 0 && rect.left >= 0 && 
                           rect.bottom <= window.innerHeight && 
                           rect.right <= window.innerWidth;
          
          if (isVisible) {
            updateDropdownPosition();
          } else {
            // Hide dropdown if button is not visible
            setIsOpen(false);
          }
        }
      }
    };

    const handleResize = () => {
      if (isOpen) {
        updateDropdownPosition();
      }
    };

    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
      window.addEventListener('scroll', handleScroll, true);
      window.addEventListener('resize', handleResize);
      
      return () => {
        document.removeEventListener('mousedown', handleClickOutside);
        window.removeEventListener('scroll', handleScroll, true);
        window.removeEventListener('resize', handleResize);
      };
    } else {
      document.addEventListener('mousedown', handleClickOutside);
      return () => document.removeEventListener('mousedown', handleClickOutside);
    }
  }, [isOpen, updateDropdownPosition]);

  const handleDropdownToggle = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    console.log('Labels dropdown toggle clicked, current state:', isOpen);
    
    if (!isOpen) {
      updateDropdownPosition();
      setIsOpen(true);
      // Focus search input after opening
      setTimeout(() => {
        searchInputRef.current?.focus();
      }, 0);
    } else {
      setIsOpen(false);
    }
  };



  const handleLabelToggle = (label: ITaskLabel) => {
    const labelData = {
      task_id: task.id,
      label_id: label.id,
      parent_task: task.parent_task_id,
      team_id: currentSession?.team_id,
    };

    socket?.emit(SocketEvents.TASK_LABELS_CHANGE.toString(), JSON.stringify(labelData));
  };

  const handleCreateLabel = () => {
    if (!searchQuery.trim()) return;
    
    const labelData = {
      task_id: task.id,
      label: searchQuery.trim(),
      parent_task: task.parent_task_id,
      team_id: currentSession?.team_id,
    };
    
    socket?.emit(SocketEvents.CREATE_LABEL.toString(), JSON.stringify(labelData));
    setSearchQuery('');
  };

  const checkLabelSelected = (labelId: string) => {
    return task?.all_labels?.some(existingLabel => existingLabel.id === labelId) || false;
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    const existingLabel = filteredLabels.find(
      label => label.name?.toLowerCase() === searchQuery.toLowerCase()
    );
    
    if (!existingLabel && e.key === 'Enter') {
      handleCreateLabel();
    }
  };

  return (
    <>
      <button
        ref={buttonRef}
        onClick={handleDropdownToggle}
        className={`
          w-5 h-5 rounded border border-dashed flex items-center justify-center
          transition-colors duration-200
          ${isOpen 
            ? isDarkMode 
              ? 'border-blue-500 bg-blue-900/20 text-blue-400' 
              : 'border-blue-500 bg-blue-50 text-blue-600'
            : isDarkMode 
              ? 'border-gray-600 hover:border-gray-500 hover:bg-gray-800 text-gray-400' 
              : 'border-gray-300 hover:border-gray-400 hover:bg-gray-100 text-gray-600'
          }
        `}
      >
        <PlusOutlined className="text-xs" />
      </button>

      {isOpen && createPortal(
        <div
          ref={dropdownRef}
          className={`
            fixed z-9999 w-72 rounded-md shadow-lg border
            ${isDarkMode 
              ? 'bg-gray-800 border-gray-600' 
              : 'bg-white border-gray-200'
            }
          `}
          style={{
            top: dropdownPosition.top,
            left: dropdownPosition.left,
          }}
        >
          {/* Header */}
          <div className={`p-2 border-b ${isDarkMode ? 'border-gray-600' : 'border-gray-300'}`}>
            <input
              ref={searchInputRef}
              type="text"
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              onKeyDown={handleKeyDown}
              placeholder="Search labels..."
              className={`
                w-full px-2 py-1 text-xs rounded border
                ${isDarkMode
                  ? 'bg-gray-700 border-gray-600 text-gray-100 placeholder-gray-400 focus:border-blue-500'
                  : 'bg-white border-gray-300 text-gray-900 placeholder-gray-500 focus:border-blue-500'
                }
                focus:outline-none focus:ring-1 focus:ring-blue-500
              `}
            />
          </div>

          {/* Labels List */}
          <div className="max-h-48 overflow-y-auto">
            {filteredLabels && filteredLabels.length > 0 ? (
              filteredLabels.map((label) => (
                <div
                  key={label.id}
                  className={`
                    flex items-center gap-2 p-2 cursor-pointer transition-colors
                    ${isDarkMode ? 'hover:bg-gray-700' : 'hover:bg-gray-50'}
                  `}
                  onClick={() => handleLabelToggle(label)}
                >
                  <Checkbox
                    checked={checkLabelSelected(label.id || '')}
                    onChange={() => handleLabelToggle(label)}
                    isDarkMode={isDarkMode}
                  />
                  
                  <div
                    className="w-3 h-3 rounded-full shrink-0"
                    style={{ backgroundColor: label.color_code }}
                  />
                  
                  <div className="flex-1 min-w-0">
                    <div className={`text-xs font-medium truncate ${isDarkMode ? 'text-gray-100' : 'text-gray-900'}`}>
                      {label.name}
                    </div>
                  </div>
                </div>
              ))
            ) : (
              <div className={`p-4 text-center ${isDarkMode ? 'text-gray-400' : 'text-gray-500'}`}>
                <div className="text-xs">No labels found</div>
                {searchQuery.trim() && (
                  <button
                    onClick={handleCreateLabel}
                    className={`
                      mt-2 px-3 py-1 text-xs rounded border transition-colors
                      ${isDarkMode
                        ? 'border-gray-600 text-gray-300 hover:bg-gray-700'
                        : 'border-gray-300 text-gray-600 hover:bg-gray-50'
                      }
                    `}
                  >
                    Create "{searchQuery}"
                  </button>
                )}
              </div>
            )}
          </div>

          {/* Footer */}
          <div className={`p-2 border-t ${isDarkMode ? 'border-gray-600' : 'border-gray-200'}`}>
            <button
              className={`
                w-full flex items-center justify-center gap-1 px-2 py-1 text-xs rounded
                transition-colors
                ${isDarkMode
                  ? 'text-blue-400 hover:bg-gray-700'
                  : 'text-blue-600 hover:bg-blue-50'
                }
              `}
              onClick={() => {
                // TODO: Implement manage labels functionality
                console.log('Manage labels clicked');
              }}
            >
              <TagOutlined />
              Manage labels
            </button>
          </div>
        </div>,
        document.body
      )}
    </>
  );
};

export default LabelsSelector; 