import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { createPortal } from 'react-dom';
import { useTranslation } from 'react-i18next';
import { FaPlus } from 'react-icons/fa';
import apiService from '../services/apiService';
import { supportsQuickCreate } from '../components/QuickCreateConfig';
import { hasCreatePermission } from '../services/permissionService';
import QuickCreateModal from '../components/QuickCreateModal';

interface LinkFieldProps {
  label: string;
  doctype: string;
  value: string;
  onChange: (value: string) => void;
  /** When true, only the input is rendered (use an outer <label> / FL). */
  hideLabel?: boolean;
  placeholder?: string;
  disabled?: boolean;
  /** Frappe filter rows `[['DocType', 'field', 'op', value]]` or legacy dict form */
  filters?: any;
  compact?: boolean;
  usePortal?: boolean;
  // New props for QuickCreate functionality
  allowQuickCreate?: boolean; // Enable/disable quick create (default: false)
  onQuickCreateSuccess?: (newRecord: any) => void; // Callback after quick create
  quickCreateInitialValues?: Record<string, any>; // Initial values for quick create form
  query?: string;
}

// Stable empty object to avoid re-renders
const EMPTY_FILTERS: Record<string, any> = {};

const LinkField: React.FC<LinkFieldProps> = ({
  label,
  doctype,
  value,
  onChange,
  hideLabel = false,
  placeholder,
  disabled = false,
  filters,
  compact = false,
  usePortal = true,
  // QuickCreate props with defaults
  allowQuickCreate = false, // Default to false - must explicitly enable per field
  onQuickCreateSuccess,
  quickCreateInitialValues = {},
  query,
}) => {
  const { t } = useTranslation();
  const [searchResults, setSearchResults] = useState<{ value: string; description?: string }[]>([]);
  const [searchText, setSearchText] = useState('');
  const [isDropdownOpen, setDropdownOpen] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [dropdownPosition, setDropdownPosition] = useState<{ top: number; left: number; width: number }>({ top: 0, left: 0, width: 0 });
  
  // QuickCreate modal state
  const [showQuickCreate, setShowQuickCreate] = useState(false);
  
  // Permission state for QuickCreate
  // null = not checked yet, true = allowed, false = denied
  const [hasPermission, setHasPermission] = useState<boolean | null>(null);
  
  const containerRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const lastSearchRef = useRef<string>('');
  const hasLoadedRef = useRef<boolean>(false);
  
  // Use stable empty object if filters not provided
  const stableFilters = filters || EMPTY_FILTERS;
  
  // Stringify filters for comparison (avoid object reference issues)
  const filtersKey = useMemo(() => JSON.stringify(stableFilters), [stableFilters]);

  // Check if doctype has QuickCreate config
  const hasQuickCreateConfig = useMemo(() => {
    const supported = supportsQuickCreate(doctype);
    console.log(`[LinkField] ${doctype} hasQuickCreateConfig: ${supported}`);
    return supported;
  }, [doctype]);

  // Check permission ONLY when allowQuickCreate is enabled AND doctype has config
  useEffect(() => {
    // Reset state when doctype or allowQuickCreate changes
    setHasPermission(null);
    
    // Only check permission if allowQuickCreate is true AND doctype has config
    if (allowQuickCreate && hasQuickCreateConfig) {
      console.log(`[LinkField] Checking permission for ${doctype}...`);
      
      hasCreatePermission(doctype)
        .then((result) => {
          console.log(`[LinkField] Permission for ${doctype}: ${result}`);
          setHasPermission(result);
        })
        .catch((err) => {
          console.error(`[LinkField] Permission check failed for ${doctype}:`, err);
          setHasPermission(false);
        });
    } else {
      // If allowQuickCreate is false or no config, don't show button
      setHasPermission(false);
      
      if (allowQuickCreate && !hasQuickCreateConfig) {
        console.warn(`[LinkField] ${doctype}: allowQuickCreate=true but no config in QuickCreateConfig.ts`);
      }
    }
  }, [allowQuickCreate, doctype, hasQuickCreateConfig]);

  // Final check: show button only if ALL conditions are met:
  // 1. allowQuickCreate={true} is set on the field
  // 2. Doctype has config in QuickCreateConfig.ts
  // 3. Permission check passed (hasPermission === true)
  const canQuickCreate = useMemo(() => {
    const result = allowQuickCreate && hasQuickCreateConfig && hasPermission === true;
    console.log(`[LinkField] canQuickCreate for ${doctype}: ${result}`, {
      allowQuickCreate,
      hasQuickCreateConfig,
      hasPermission
    });
    return result;
  }, [allowQuickCreate, hasQuickCreateConfig, hasPermission, doctype]);

  /// Fetch link options from ERPNext with filters
const searchLink = useCallback(async (text: string = '', force: boolean = false) => {
  // Prevent duplicate calls for the same search text
  const searchKey = `${text}-${filtersKey}-${query || ''}`;
  if (!force && lastSearchRef.current === searchKey) {
    return;
  }
  lastSearchRef.current = searchKey;
  
  setIsLoading(true);
  try {
    let response: { value: string; description?: string }[] | null = null;

    if (query) {
      // Use custom query method
      const params = new URLSearchParams({
        txt: text,
        doctype: doctype,
        searchfield: 'name',
        start: '0',
        page_len: '50',
      });

      // Add filters if provided
      if (stableFilters && Object.keys(stableFilters).length > 0) {
        params.append('filters', JSON.stringify(stableFilters));
      }

      const customResponse = await apiService.apiCall<any>(
        `/api/method/${query}?${params.toString()}`
      );

      // Custom query returns array of arrays: [[value, description], ...]
      // Convert to expected format
      if (Array.isArray(customResponse)) {
        response = customResponse.map((item: any) => {
          if (Array.isArray(item)) {
            return { value: item[0], description: item[1] || undefined };
          }
          return { value: item.value || item.name || item, description: item.description };
        });
      } else {
        response = [];
      }
    } else {
      // Use standard Frappe search_link
      const params = new URLSearchParams({ 
        doctype, 
        txt: text,
        page_length: '50',
      });

      // Add filters if provided
      if (stableFilters && Object.keys(stableFilters).length > 0) {
        params.append('filters', JSON.stringify(stableFilters));
      }

      response = await apiService.apiCall<{ value: string; description?: string }[]>(
        `/api/method/frappe.desk.search.search_link?${params.toString()}`
      );
    }

    setSearchResults(response || []);
  } catch (error) {
    console.error(`Error fetching ${doctype} links:`, error);
    setSearchResults([]);
  } finally {
    setIsLoading(false);
  }
}, [doctype, filtersKey, stableFilters, query]);

  // Debounced search for typing
  const debouncedSearch = useCallback((text: string) => {
    if (debounceRef.current) {
      clearTimeout(debounceRef.current);
    }
    debounceRef.current = setTimeout(() => {
      searchLink(text);
    }, 300);
  }, [searchLink]);

  // Fetch default options ONLY when dropdown first opens
  useEffect(() => {
    if (isDropdownOpen && !hasLoadedRef.current) {
      hasLoadedRef.current = true;
      searchLink(searchText || '', true);
    }
    
    // Reset the loaded flag when dropdown closes
    if (!isDropdownOpen) {
      hasLoadedRef.current = false;
      lastSearchRef.current = '';
    }
  }, [isDropdownOpen]); // Only depend on isDropdownOpen

  // Cleanup debounce on unmount
  useEffect(() => {
    return () => {
      if (debounceRef.current) {
        clearTimeout(debounceRef.current);
      }
    };
  }, []);

  // Calculate dropdown position for portal rendering
  const updateDropdownPosition = useCallback(() => {
    if (usePortal && inputRef.current) {
      const rect = inputRef.current.getBoundingClientRect();
      setDropdownPosition({
        top: rect.bottom + window.scrollY,
        left: rect.left + window.scrollX,
        width: rect.width
      });
    }
  }, [usePortal]);

  // Update position when dropdown opens or on scroll/resize
  useEffect(() => {
    if (isDropdownOpen && usePortal) {
      updateDropdownPosition();
      
      const handleUpdate = () => updateDropdownPosition();
      window.addEventListener('scroll', handleUpdate, true);
      window.addEventListener('resize', handleUpdate);
      
      return () => {
        window.removeEventListener('scroll', handleUpdate, true);
        window.removeEventListener('resize', handleUpdate);
      };
    }
  }, [isDropdownOpen, usePortal, updateDropdownPosition]);

  // Close dropdown when clicking outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      const target = event.target as Node;
      const clickedOutsideContainer = containerRef.current && !containerRef.current.contains(target);
      const clickedOutsideDropdown = usePortal && dropdownRef.current && !dropdownRef.current.contains(target);
      
      // Close if clicked outside both container and dropdown (when using portal)
      if (usePortal) {
        if (clickedOutsideContainer && clickedOutsideDropdown) {
          setDropdownOpen(false);
          setSearchText('');
        }
      } else {
        if (clickedOutsideContainer) {
          setDropdownOpen(false);
          setSearchText('');
        }
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [usePortal]);

  // Handle selecting an item from dropdown
  const handleSelect = (selectedValue: string) => {
    onChange(selectedValue);
    setSearchText('');
    setDropdownOpen(false);
  };

  // Handle clearing the field
  const handleClear = () => {
    onChange('');
    setSearchText('');
    setDropdownOpen(false);
  };

  // Handle opening QuickCreate modal
  const handleOpenQuickCreate = () => {
    setDropdownOpen(false);
    setSearchText('');
    setShowQuickCreate(true);
  };

  // Handle QuickCreate success
  const handleQuickCreateSuccess = (newRecord: any) => {
    // Get the name/value from the new record
    const newValue = newRecord.name || newRecord[Object.keys(newRecord)[0]];
    handleSelect(newValue);
    
    // Call external callback if provided
    if (onQuickCreateSuccess) {
      onQuickCreateSuccess(newRecord);
    }
  };

  // Render dropdown content
  const renderDropdown = () => {
    const dropdownClasses = `bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 
      rounded-md w-full shadow-lg ${compact ? 'mt-0.5' : 'mt-1'}`;
    
    const positionStyle = usePortal ? {
      position: 'fixed' as const,
      top: `${dropdownPosition.top}px`,
      left: `${dropdownPosition.left}px`,
      width: `${dropdownPosition.width}px`,
      zIndex: 1050,
      marginTop: compact ? '2px' : '4px'
    } : {};

    if (!isDropdownOpen || disabled) return null;

    const dropdownContent = (
      <div ref={dropdownRef}>
        {/* Loading indicator */}
        {isLoading && (
          <div className={`${usePortal ? '' : 'absolute z-[1050]'} ${dropdownClasses} text-center text-gray-500 dark:text-gray-400
            ${compact ? 'p-1.5 text-[10px]' : 'p-3 text-sm'}`}
            style={positionStyle}>
            <span className="inline-block animate-spin mr-2">⏳</span>
            {t('linkField.loading')}
          </div>
        )}

        {/* Results list with QuickCreate option */}
        {!isLoading && (
          <div className={`${usePortal ? '' : 'absolute z-[1050]'} ${dropdownClasses} overflow-hidden`}
            style={positionStyle}>
            
            {/* Results */}
            {searchResults.length > 0 ? (
              <ul className={`overflow-auto ${compact ? 'max-h-36' : 'max-h-48'}`}>
                {searchResults.map((item, idx) => (
                  <li
                    key={idx}
                    onClick={() => handleSelect(item.value)}
                    className={`cursor-pointer text-gray-900 dark:text-gray-100 
                      hover:bg-blue-500 dark:hover:bg-blue-600 hover:text-white
                      ${compact ? 'px-2 py-1 text-xs' : 'px-3 py-2 text-sm'}
                      ${value === item.value ? 'bg-blue-50 dark:bg-blue-700 font-semibold' : ''}`}
                  >
                    {item.value}
                    {item.description && (
                      <span className={`text-gray-600 dark:text-gray-300 ml-2
                        ${compact ? 'text-[9px] ml-1' : 'text-xs ml-2'}`}>
                        {item.description}
                      </span>
                    )}
                  </li>
                ))}
              </ul>
            ) : (
              <div className={`text-center text-gray-500 dark:text-gray-400
                ${compact ? 'p-1.5 text-[10px]' : 'p-3 text-sm'}`}>
                {t('linkField.noResultsFound')}
              </div>
            )}

            {/* QuickCreate Button - Only shows if all conditions are met */}
            {canQuickCreate && (
              <>
                <div className="border-t border-gray-200 dark:border-gray-700" />
                <div
                  onClick={handleOpenQuickCreate}
                  className={`cursor-pointer flex items-center gap-2 
                    text-green-600 dark:text-green-400 
                    hover:bg-green-50 dark:hover:bg-green-900/20 
                    hover:text-green-700 dark:hover:text-green-300
                    transition-colors
                    ${compact ? 'px-2 py-1.5 text-xs' : 'px-3 py-2.5 text-sm'}`}
                >
                  <FaPlus size={compact ? 10 : 12} />
                  <span className="font-medium">
                    {t('linkField.createNewDoctype', { doctype: doctype.replace(/_/g, ' ') })}
                  </span>
                </div>
              </>
            )}
          </div>
        )}
      </div>
    );

    return usePortal ? createPortal(dropdownContent, document.body) : dropdownContent;
  };

  return (
    <>
      <div
        ref={containerRef}
        className={`relative w-full ${compact ? 'mb-2' : hideLabel ? 'mb-0' : 'mb-4'}`}
      >
        {!hideLabel && (
          <label className={`block font-medium text-gray-700 dark:text-gray-300 ${compact ? 'text-[10px] mb-0.5' : 'text-sm mb-1'}`}>
            {label}
          </label>
        )}

        <div className="relative">
          <input
            ref={inputRef}
            type="text"
            value={isDropdownOpen ? searchText : value}
            placeholder={placeholder || t('linkField.selectLabel', { label })}
            disabled={disabled}
            className={`w-full border border-gray-300 dark:border-gray-600 rounded-md 
              focus:outline-none disabled:bg-gray-100 dark:disabled:bg-gray-700 
              bg-white dark:bg-gray-700 text-gray-900 dark:text-white
              ${compact 
                ? 'px-2 py-1 text-xs focus:ring-1 focus:ring-blue-500 rounded' 
                : 'px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500'
              }
              ${value ? (compact ? 'pr-5' : 'pr-8') : ''}`}
            onFocus={() => {
              if (!disabled) {
                setDropdownOpen(true);
                setSearchText('');
                if (usePortal) {
                  updateDropdownPosition();
                }
              }
            }}
            onChange={(e) => {
              const text = e.target.value;
              setSearchText(text);
              debouncedSearch(text);
            }}
          />
          
          {/* Clear button */}
          {value && !disabled && !isDropdownOpen && (
            <button
              type="button"
              onClick={handleClear}
              className={`absolute top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300
                ${compact ? 'right-1 text-xs' : 'right-2 text-sm'}`}
            >
              ✕
            </button>
          )}
        </div>

        {/* Render dropdown */}
        {renderDropdown()}
      </div>

      {/* QuickCreate Modal */}
      <QuickCreateModal
        doctype={doctype}
        isOpen={showQuickCreate}
        onClose={() => setShowQuickCreate(false)}
        onSuccess={handleQuickCreateSuccess}
        initialValues={quickCreateInitialValues}
        parentFilters={stableFilters}
      />
    </>
  );
};

export default LinkField;