import { Search, X } from "@styled-icons/boxicons-regular";
import { HelpCircle } from "@styled-icons/boxicons-solid";
import styled from "styled-components/macro";
import { useEffect, useRef, useState } from "preact/hooks";
import { internalEmit } from "../../lib/eventEmitter";
import { useSearchAutoComplete, transformSearchQuery, UserMapping } from "../../lib/hooks/useSearchAutoComplete";
import SearchAutoComplete from "./SearchAutoComplete";
import SearchDatePicker from "./SearchDatePicker";
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
import { useApplicationState } from "../../mobx/State";
import { SIDEBAR_MEMBERS } from "../../mobx/stores/Layout";
import Tooltip from "../common/Tooltip";

const Container = styled.div`
    position: relative;
    display: flex;
    align-items: center;
    background: var(--primary-header);
    border-radius: var(--border-radius);
    width: 220px;
    height: 32px;
    
    @media (max-width: 768px) {
        width: 180px;
    }
`;

const Input = styled.input`
    flex: 1;
    border: none;
    background: transparent;
    color: var(--foreground);
    font-size: 14px;
    padding: 6px 2px 6px 8px; /* Reduced left padding for more space */
    outline: none;
    min-width: 0; /* Allow input to shrink properly */
    
    &::placeholder {
        color: var(--tertiary-foreground);
        font-size: 13px; /* Slightly smaller placeholder on mobile */
    }
    
    @media (max-width: 768px) {
        font-size: 13px;
        padding: 6px 2px 6px 6px;
    }
`;

const IconButton = styled.div`
    display: flex;
    align-items: center;
    padding: 0 8px; /* Symmetrical padding */
    color: var(--tertiary-foreground);
    cursor: pointer;
    transition: color 0.1s ease;
    flex-shrink: 0; /* Prevent icon from shrinking */
    
    &:hover {
        color: var(--foreground);
    }
    
    @media (max-width: 768px) {
        padding: 0 6px; /* Less padding on mobile */
        
        svg {
            width: 16px;
            height: 16px;
        }
    }
`;

const OptionsDropdown = styled.div`
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 8px;
    background: var(--primary-background);
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    z-index: 1000;
    overflow: hidden;
    padding: 8px;
    min-width: 300px;
    
    @media (max-width: 768px) {
        padding: 12px;
        min-width: 320px;
        max-width: calc(100vw - 20px);
        right: -10px; /* Adjust position to prevent edge cutoff */
        max-height: 40vh; /* Limit height when keyboard is up */
        overflow-y: auto; /* Make it scrollable */
        
        /* Add scrollbar styles for mobile */
        &::-webkit-scrollbar {
            width: 4px;
        }
        
        &::-webkit-scrollbar-track {
            background: transparent;
        }
        
        &::-webkit-scrollbar-thumb {
            background: var(--scrollbar-thumb);
            border-radius: 2px;
        }
    }
`;

const OptionsHeader = styled.div`
    padding: 0 8px 8px 8px;
    font-size: 12px;
    color: var(--tertiary-foreground);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    
    @media (max-width: 768px) {
        font-size: 11px;
        padding: 0 8px 8px 8px;
    }
`;

const Option = styled.div`
    display: flex;
    align-items: center;
    padding: 8px;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.15s ease;
    margin-bottom: 2px;
    
    &:hover {
        background: var(--secondary-background);
    }
    
    &:last-child {
        margin-bottom: 0;
    }
    
    @media (max-width: 768px) {
        padding: 10px 10px;
        margin-bottom: 3px;
        border-radius: 6px;
        
        /* Add touch feedback for mobile */
        &:active {
            background: var(--secondary-background);
            transform: scale(0.98);
        }
    }
`;

const OptionLabel = styled.span`
    color: var(--foreground);
    font-weight: 500;
    margin-right: 8px;
    font-family: var(--monospace-font), monospace;
    font-size: 13px;
    white-space: nowrap;
    
    @media (max-width: 768px) {
        font-size: 13px;
        margin-right: 10px;
    }
`;

const OptionDesc = styled.span`
    color: var(--tertiary-foreground);
    font-size: 13px;
    flex: 1;
    
    @media (max-width: 768px) {
        font-size: 12px;
    }
`;

const HelpIcon = styled(HelpCircle)`
    color: var(--tertiary-foreground);
    margin-left: auto;
    flex-shrink: 0;
    opacity: 0;
    transition: opacity 0.15s ease;
    
    ${Option}:hover & {
        opacity: 0.7;
    }
`;

interface SearchOption {
    label: string;
    description: string;
    tooltip: string;
}

const searchOptions: SearchOption[] = [
    {
        label: "from:",
        description: "user",
        tooltip: "Filter messages by author"
    },
    {
        label: "mentions:",
        description: "user",
        tooltip: "Find messages mentioning a user"
    },
    {
        label: "has:",
        description: "video, image, link, audio, file",
        tooltip: "Messages with specific attachment types"
    },
    {
        label: "before:",
        description: "specific date",
        tooltip: "Messages before this date"
    },
    {
        label: "during:",
        description: "specific date",
        tooltip: "Messages on this date"
    },
    {
        label: "after:",
        description: "specific date",
        tooltip: "Messages after this date"
    },
    {
        label: "between:",
        description: "date range",
        tooltip: "Messages between two dates"
    },
    {
        label: "server-wide",
        description: "Entire server",
        tooltip: "Search in entire server instead of just this channel"
    }
];

export function SearchBar() {
    const layout = useApplicationState().layout;
    const [query, setQuery] = useState("");
    const [showOptions, setShowOptions] = useState(false);
    const [isSearching, setIsSearching] = useState(false);
    const [userMappings, setUserMappings] = useState<UserMapping>({});
    const [showDatePicker, setShowDatePicker] = useState<"before" | "after" | "during" | "between" | null>(null);
    const [showAttachmentTypes, setShowAttachmentTypes] = useState(false);
    const [activeDateRange, setActiveDateRange] = useState<{
        start: string;
        end: string;
        startDisplay: string;
        endDisplay: string;
    } | null>(null);
    const [showServerWideError, setShowServerWideError] = useState(false);
    const [showDateRangeError, setShowDateRangeError] = useState(false);
    const [showMultipleHasError, setShowMultipleHasError] = useState(false);
    const [showDuplicateFilterError, setShowDuplicateFilterError] = useState(false);
    const inputRef = useRef<HTMLInputElement>(null);
    const skipNextFocus = useRef(false);
    
    // Setup autocomplete
    const {
        state: autocompleteState,
        setState: setAutocompleteState,
        onKeyUp,
        onKeyDown: originalOnAutocompleteKeyDown,
        onChange: onAutocompleteChange,
        onClick: originalOnAutocompleteClick,
        onFocus: onAutocompleteFocus,
        onBlur: onAutocompleteBlur,
    } = useSearchAutoComplete(setQuery, userMappings, setUserMappings);
    
    // Wrap the autocomplete click to show options menu after selection
    const onAutocompleteClick = (userId: string, username: string) => {
        originalOnAutocompleteClick(userId, username);
        // Show options menu after user selection
        setTimeout(() => {
            setShowOptions(true);
        }, 100);
    };
    
    // Wrap the onKeyDown handler to show options menu after Enter selection
    const onAutocompleteKeyDown = (e: KeyboardEvent) => {
        const handled = originalOnAutocompleteKeyDown(e);
        // If Enter or Tab was pressed and autocomplete was active, show options menu
        if (handled && (e.key === "Enter" || e.key === "Tab") && autocompleteState.type !== "none") {
            setTimeout(() => {
                setShowOptions(true);
            }, 100);
        }
        return handled;
    };
    
    const handleFocus = () => {
        // Check if we should skip showing options this time
        if (skipNextFocus.current) {
            skipNextFocus.current = false;
            onAutocompleteFocus();
            return;
        }
        
        onAutocompleteFocus();
        // Don't show options if we're in the middle of typing a filter
        const hasIncompleteFilter = query.match(/\b(from:|mentions:|has:|before:|after:|during:|between:)\s*$/);
        if (!hasIncompleteFilter && !showDatePicker && !showAttachmentTypes && autocompleteState.type === "none") {
            setShowOptions(true);
        }
    };
    
    const handleClick = () => {
        // Check if we're currently editing a filter
        const cursorPos = inputRef.current?.selectionStart || 0;
        const beforeCursor = query.slice(0, cursorPos);
        
        // Check if cursor is within a filter
        const isInFilter = beforeCursor.match(/\b(from:|mentions:|has:|before:|after:|during:|between:)[^\\s]*$/);
        
        // Show options when clicking on the input, if not editing a filter
        if (!isInFilter && !showOptions && autocompleteState.type === "none" && !showDatePicker && !showAttachmentTypes) {
            setShowOptions(true);
        }
    };
    
    const handleBlur = () => {
        onAutocompleteBlur();
        // Delay to allow clicking on options
        setTimeout(() => {
            // Check if we have an incomplete filter that should keep autocomplete open
            const hasUserFilter = query.match(/\b(from:|mentions:)[\s\S]*$/);
            const hasIncompleteDateFilter = query.match(/\b(before:|after:|during:)\s*$/);
            
            // Don't close options/autocomplete if we have a user filter
            if (!hasUserFilter && !hasIncompleteDateFilter && !showDatePicker) {
                setShowOptions(false);
                if (autocompleteState.type === "none") {
                    setAutocompleteState({ type: "none" });
                }
            }
        }, 200);
    };
    
    const handleInput = (e: Event) => {
        const value = (e.target as HTMLInputElement).value;
        const cursorPos = (e.target as HTMLInputElement).selectionStart || 0;
        
        // Check if user is trying to add space after incomplete filter
        const incompleteFilterWithSpace = value.match(/\b(from:|mentions:)\s+$/);
        if (incompleteFilterWithSpace && autocompleteState.type === "user") {
            // Don't allow space after filter unless user was selected
            return;
        }
        
        setQuery(value);
        
        // Check for filters
        const beforeCursor = value.slice(0, cursorPos);
        
        // Check for user filters (from: and mentions:) - these should trigger autocomplete
        const fromMatch = beforeCursor.match(/\bfrom:[\s\S]*$/);
        const mentionsMatch = beforeCursor.match(/\bmentions:[\s\S]*$/);
        
        if (fromMatch || mentionsMatch) {
            // Close other dropdowns
            setShowOptions(false);
            setShowDatePicker(null);
            setShowAttachmentTypes(false);
            // Trigger autocomplete immediately for user filters
            onAutocompleteChange(e);
            return;
        }
        
        // Check for date filters
        const beforeMatch = beforeCursor.match(/\bbefore:\s*$/);
        const afterMatch = beforeCursor.match(/\bafter:\s*$/);
        const duringMatch = beforeCursor.match(/\bduring:\s*$/);
        const betweenMatch = beforeCursor.match(/\bbetween:\s*$/);
        const hasMatch = beforeCursor.match(/\bhas:\s*$/);
        
        if (beforeMatch) {
            setShowDatePicker("before");
            setShowOptions(false);
            setShowAttachmentTypes(false);
            setAutocompleteState({ type: "none" });
        } else if (afterMatch) {
            setShowDatePicker("after");
            setShowOptions(false);
            setShowAttachmentTypes(false);
            setAutocompleteState({ type: "none" });
        } else if (duringMatch) {
            setShowDatePicker("during");
            setShowOptions(false);
            setShowAttachmentTypes(false);
            setAutocompleteState({ type: "none" });
        } else if (betweenMatch) {
            setShowDatePicker("between");
            setShowOptions(false);
            setShowAttachmentTypes(false);
            setAutocompleteState({ type: "none" });
        } else if (hasMatch) {
            // Show attachment type options
            setShowAttachmentTypes(true);
            setShowOptions(false);
            setShowDatePicker(null);
            setAutocompleteState({ type: "none" });
        } else {
            // Check if "has:" was removed and close attachment types dropdown
            if (showAttachmentTypes && !value.includes("has:")) {
                setShowAttachmentTypes(false);
            }
            
            // Only trigger autocomplete if no date/has filter is active
            const filterActive = value.match(/\b(before:|after:|during:|between:|has:)\s*$/);
            if (!filterActive) {
                onAutocompleteChange(e);
                if (showDatePicker) {
                    setShowDatePicker(null);
                }
            }
        }
    };
    
    const handleSearch = () => {
        let trimmedQuery = query.trim();
        
        // Check for incomplete filters
        const hasIncompleteUserFilter = trimmedQuery.match(/\b(from:|mentions:)\s*$/);
        const hasIncompleteDateFilter = trimmedQuery.match(/\b(before:|after:|during:|between:)\s*$/);
        const hasIncompleteHasFilter = trimmedQuery.match(/\bhas:\s*$/);
        
        if (hasIncompleteUserFilter || hasIncompleteDateFilter || hasIncompleteHasFilter) {
            // Don't search if there's an incomplete filter
            return;
        }
        
        // Check for duplicate filters (only one of each type allowed)
        const checkDuplicates = (pattern: RegExp, filterName: string): boolean => {
            const matches = trimmedQuery.match(pattern) || [];
            if (matches.length > 1) {
                setShowDuplicateFilterError(true);
                setTimeout(() => setShowDuplicateFilterError(false), 3000);
                return true;
            }
            return false;
        };
        
        // Check each filter type for duplicates
        if (checkDuplicates(/\bfrom:@?[\w-]+/gi, "from")) return;
        if (checkDuplicates(/\bmentions:@?[\w-]+/gi, "mentions")) return;
        if (checkDuplicates(/\bbefore:\d{4}-\d{2}-\d{2}/gi, "before")) return;
        if (checkDuplicates(/\bafter:\d{4}-\d{2}-\d{2}/gi, "after")) return;
        if (checkDuplicates(/\bduring:\d{4}-\d{2}-\d{2}/gi, "during")) return;
        if (checkDuplicates(/\bbetween:\d{4}-\d{2}-\d{2}\.\.\d{4}-\d{2}-\d{2}/gi, "between")) return;
        
        // Check for multiple has: filters (only one attachment type filter allowed)
        const hasFilterMatches = trimmedQuery.match(/\bhas:(video|image|link|audio|file)/gi) || [];
        if (hasFilterMatches.length > 1) {
            // Show tooltip error message - only one attachment type filter is allowed
            setShowMultipleHasError(true);
            // Auto-hide after 3 seconds
            setTimeout(() => setShowMultipleHasError(false), 3000);
            return;
        }
        
        // Check for multiple date-range occurrences
        const dateRangeCount = (trimmedQuery.match(/\bdate-range\b/g) || []).length;
        if (dateRangeCount > 1) {
            // Show tooltip error message - only one date range is allowed
            setShowDateRangeError(true);
            // Auto-hide after 3 seconds
            setTimeout(() => setShowDateRangeError(false), 3000);
            return;
        }
        
        // Check if we have "date-range" in the query and replace it with actual dates
        if (dateRangeCount === 1 && activeDateRange) {
            // Replace "date-range" with the actual between filter for processing
            trimmedQuery = trimmedQuery.replace(/\bdate-range\b/, `between:${activeDateRange.start}..${activeDateRange.end}`);
        }
        
        // Transform query to use user IDs
        const searchParams = transformSearchQuery(trimmedQuery, userMappings);
        
        // Check if only server-wide is present without other filters
        if (searchParams.server_wide && 
            !searchParams.query && 
            !searchParams.author && 
            !searchParams.mention && 
            !searchParams.date_start && 
            !searchParams.date_end && 
            !searchParams.has) {
            
            // Show tooltip error message - server-wide requires other filters
            setShowServerWideError(true);
            // Auto-hide after 3 seconds
            setTimeout(() => setShowServerWideError(false), 3000);
            return;
        }
        
        // Check if we have any search criteria (query text or filters)
        // Allow empty query string if filters are present
        const hasFilters = searchParams.author || 
                          searchParams.mention || 
                          searchParams.date_start || 
                          searchParams.date_end ||
                          searchParams.has ||
                          searchParams.server_wide;
        
        const hasSearchCriteria = (searchParams.query && searchParams.query.trim() !== "") || hasFilters;
        
        if (hasSearchCriteria) {
            // Ensure the sidebar container is visible for desktop users
            if (!isTouchscreenDevice && !layout.getSectionState(SIDEBAR_MEMBERS, true)) {
                layout.setSectionState(SIDEBAR_MEMBERS, true, true);
                // Small delay to ensure the sidebar container is rendered first
                setTimeout(() => {
                    internalEmit("RightSidebar", "open", "search", searchParams);
                }, 50);
            } else {
                // Sidebar is already visible, emit immediately
                internalEmit("RightSidebar", "open", "search", searchParams);
            }
            
            setShowOptions(false);
            setIsSearching(true);
            setAutocompleteState({ type: "none" });
            inputRef.current?.blur();
            
            // On mobile, automatically slide to show search results
            if (isTouchscreenDevice) {
                setTimeout(() => {
                    const panels = document.querySelector("#app > div > div > div");
                    panels?.scrollTo({
                        behavior: "smooth",
                        left: panels.clientWidth * 3,
                    });
                }, 100); // Small delay to ensure sidebar is opened first
            }
        }
    };
    
    const handleKeyDown = (e: KeyboardEvent) => {
        const currentValue = (e.currentTarget as HTMLInputElement).value;
        const cursorPos = (e.currentTarget as HTMLInputElement).selectionStart || 0;
        
        // Handle backspace/delete for date filters and server-wide
        if (e.key === "Backspace" || e.key === "Delete") {
            const beforeCursor = currentValue.slice(0, cursorPos);
            const afterCursor = currentValue.slice(cursorPos);
            
            // Check for date filters with backspace
            if (e.key === "Backspace") {
                // Handle single date filters (before:, after:, during:)
                const singleDateMatch = beforeCursor.match(/\b(before|after|during):(\d{4}-\d{2}-\d{2})\s*$/);
                if (singleDateMatch) {
                    e.preventDefault();
                    const filterStart = singleDateMatch.index!;
                    
                    // Remove the entire filter and date
                    const newValue = currentValue.slice(0, filterStart) + afterCursor;
                    setQuery(newValue);
                    
                    // Position cursor where filter was
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(filterStart, filterStart);
                        }
                    }, 0);
                    return;
                }
                
                // Handle filter-only patterns (e.g., "before:" without date)
                const filterOnlyMatch = beforeCursor.match(/\b(before|after|during|between):\s*$/);
                if (filterOnlyMatch) {
                    e.preventDefault();
                    const filterStart = filterOnlyMatch.index!;
                    
                    // Remove the entire filter
                    const newValue = currentValue.slice(0, filterStart) + afterCursor;
                    setQuery(newValue);
                    
                    // Close date picker if open
                    setShowDatePicker(null);
                    
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(filterStart, filterStart);
                        }
                    }, 0);
                    return;
                }
                
                // Handle between date range filter
                const betweenMatch = beforeCursor.match(/\bbetween:(\d{4}-\d{2}-\d{2})\.\.(\d{4}-\d{2}-\d{2})\s*$/);
                if (betweenMatch) {
                    e.preventDefault();
                    const filterStart = betweenMatch.index!;
                    const startDate = betweenMatch[1];
                    
                    // Remove end date but keep "between:YYYY-MM-DD.."
                    const newValue = currentValue.slice(0, filterStart) + "between:" + startDate + ".." + afterCursor;
                    setQuery(newValue);
                    
                    const newCursorPos = filterStart + "between:".length + startDate.length + 2;
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(newCursorPos, newCursorPos);
                        }
                    }, 0);
                    return;
                }
                
                // Handle partial between filter (between:YYYY-MM-DD..)
                const partialBetweenMatch = beforeCursor.match(/\bbetween:(\d{4}-\d{2}-\d{2})\.\.\s*$/);
                if (partialBetweenMatch) {
                    e.preventDefault();
                    const filterStart = partialBetweenMatch.index!;
                    const startDate = partialBetweenMatch[1];
                    
                    // Remove ".." to get "between:YYYY-MM-DD"
                    const newValue = currentValue.slice(0, filterStart) + "between:" + startDate + afterCursor;
                    setQuery(newValue);
                    
                    const newCursorPos = filterStart + "between:".length + startDate.length;
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(newCursorPos, newCursorPos);
                        }
                    }, 0);
                    return;
                }
                
                // Handle between with only start date (between:YYYY-MM-DD)
                const betweenStartOnlyMatch = beforeCursor.match(/\bbetween:(\d{4}-\d{2}-\d{2})\s*$/);
                if (betweenStartOnlyMatch) {
                    e.preventDefault();
                    const filterStart = betweenStartOnlyMatch.index!;
                    
                    // Remove date but keep "between:"
                    const newValue = currentValue.slice(0, filterStart) + "between:" + afterCursor;
                    setQuery(newValue);
                    
                    const newCursorPos = filterStart + "between:".length;
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(newCursorPos, newCursorPos);
                            // Open the date picker in between mode
                            setShowDatePicker("between");
                            setShowOptions(false);
                        }
                    }, 0);
                    return;
                }
                
                // Handle date-range keyword removal
                const dateRangeMatch = beforeCursor.match(/\bdate-range\s*$/);
                if (dateRangeMatch) {
                    e.preventDefault();
                    const filterStart = dateRangeMatch.index!;
                    
                    // Remove the keyword and clear the stored date range
                    const newValue = currentValue.slice(0, filterStart) + afterCursor;
                    setQuery(newValue);
                    setActiveDateRange(null);
                    
                    // Position cursor where filter was
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(filterStart, filterStart);
                        }
                    }, 0);
                    return;
                }
                
                // Handle has: filter removal
                const hasMatch = beforeCursor.match(/\bhas:(video|image|link|audio|file)\s*$/);
                if (hasMatch) {
                    e.preventDefault();
                    const filterStart = hasMatch.index!;
                    
                    // Remove the entire filter
                    const newValue = currentValue.slice(0, filterStart) + afterCursor;
                    setQuery(newValue);
                    
                    // Position cursor where filter was
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(filterStart, filterStart);
                        }
                    }, 0);
                    return;
                }
                
                // Handle has: without value
                const hasOnlyMatch = beforeCursor.match(/\bhas:\s*$/);
                if (hasOnlyMatch) {
                    e.preventDefault();
                    const filterStart = hasOnlyMatch.index!;
                    
                    // Remove the entire filter
                    const newValue = currentValue.slice(0, filterStart) + afterCursor;
                    setQuery(newValue);
                    
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(filterStart, filterStart);
                        }
                    }, 0);
                    return;
                }
                
                // Original server-wide handling
                const serverWideMatch = beforeCursor.match(/\bserver-wide\s*$/);
                if (serverWideMatch) {
                    e.preventDefault();
                    const newValue = currentValue.slice(0, serverWideMatch.index) + afterCursor;
                    setQuery(newValue);
                    // Set cursor position to where server-wide started
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(serverWideMatch.index, serverWideMatch.index);
                        }
                    }, 0);
                    return;
                }
            } else if (e.key === "Delete") {
                // Handle date filters with delete key
                // Check if we're at a filter: position
                const filterMatch = afterCursor.match(/^(before|after|during|between):(\d{4}-\d{2}-\d{2})?/);
                if (filterMatch && beforeCursor.match(/\s$|^$/)) {
                    e.preventDefault();
                    const filterType = filterMatch[1];
                    const hasDate = filterMatch[2];
                    
                    if (hasDate) {
                        // Remove entire filter and date
                        const newValue = beforeCursor + afterCursor.slice(filterMatch[0].length).trimStart();
                        setQuery(newValue);
                    } else {
                        // Just filter: without date, remove it
                        const newValue = beforeCursor + afterCursor.slice(filterType.length + 1).trimStart();
                        setQuery(newValue);
                    }
                    
                    setTimeout(() => {
                        if (inputRef.current) {
                            inputRef.current.setSelectionRange(beforeCursor.length, beforeCursor.length);
                        }
                    }, 0);
                    return;
                }
                
                // Handle has: filter with delete key
                const hasAfter = afterCursor.match(/^has:(video|image|link|audio|file)?\s*/);
                if (hasAfter) {
                    e.preventDefault();
                    const newValue = beforeCursor + afterCursor.slice(hasAfter[0].length);
                    setQuery(newValue);
                    return;
                }
                
                // Original server-wide handling
                const serverWideAfter = afterCursor.match(/^server-wide\s*/);
                if (serverWideAfter) {
                    e.preventDefault();
                    const newValue = beforeCursor + afterCursor.slice(serverWideAfter[0].length);
                    setQuery(newValue);
                    return;
                }
            }
        }
        
        // Check if user is trying to type space when there's an incomplete filter
        if (e.key === " " || e.key === "Spacebar") {
            const beforeCursor = currentValue.slice(0, cursorPos);
            const afterCursor = currentValue.slice(cursorPos);
            
            // Check if cursor is within or right after a filter
            const lastFromIndex = beforeCursor.lastIndexOf("from:");
            const lastMentionsIndex = beforeCursor.lastIndexOf("mentions:");
            
            if (lastFromIndex !== -1 || lastMentionsIndex !== -1) {
                const filterIndex = Math.max(lastFromIndex, lastMentionsIndex);
                const afterFilter = beforeCursor.slice(filterIndex);
                
                // Check if we're still within the filter (no space after it in the part before cursor)
                if (!afterFilter.includes(" ")) {
                    // Also check if there's no space immediately after cursor (editing in middle of username)
                    const hasSpaceAfterCursor = afterCursor.startsWith(" ");
                    
                    if (!hasSpaceAfterCursor) {
                        // We're within a filter and trying to add space - always prevent
                        e.preventDefault();
                        return;
                    }
                }
            }
        }
        
        // Let autocomplete handle key events first
        if (onAutocompleteKeyDown(e)) {
            return;
        }
        
        if (e.key === "Enter") {
            // Don't search if autocomplete is showing
            if (autocompleteState.type === "none") {
                handleSearch();
            }
        } else if (e.key === "Escape") {
            if (query) {
                setQuery("");
            } else {
                inputRef.current?.blur();
            }
            if (isSearching) {
                internalEmit("RightSidebar", "close");
                setIsSearching(false);
            }
        }
    };
    
    const handleClear = () => {
        setQuery("");
        setIsSearching(false);
        inputRef.current?.focus();
        internalEmit("RightSidebar", "close");
    };
    
    const handleOptionClick = (option: SearchOption) => {
        // If it's a date filter, just show the date picker without adding text
        if (option.label === "before:" || option.label === "after:" || option.label === "during:" || option.label === "between:") {
            setShowDatePicker(option.label.slice(0, -1) as "before" | "after" | "during" | "between");
            setShowOptions(false);
            // Ensure autocomplete is hidden
            setAutocompleteState({ type: "none" });
        } else if (option.label === "has:") {
            // For has: filter, add it and show attachment type options
            const newQuery = query + (query ? " " : "") + "has:";
            setQuery(newQuery);
            setShowOptions(false);
            setShowAttachmentTypes(true);
            // Ensure autocomplete is hidden
            setAutocompleteState({ type: "none" });
            
            // Move cursor after "has:"
            setTimeout(() => {
                if (inputRef.current) {
                    const endPos = newQuery.length;
                    inputRef.current.setSelectionRange(endPos, endPos);
                    inputRef.current.focus();
                }
            }, 0);
        } else if (option.label === "server-wide") {
            // For server-wide, add it as a standalone filter with auto-space
            const newQuery = query + (query ? " " : "") + "server-wide ";
            setQuery(newQuery);
            setShowOptions(false);
            // Ensure autocomplete is hidden
            setAutocompleteState({ type: "none" });
            
            // Set flag to skip showing options on the next focus
            skipNextFocus.current = true;
            
            // Move cursor to end after the space
            setTimeout(() => {
                if (inputRef.current) {
                    const endPos = newQuery.length;
                    inputRef.current.setSelectionRange(endPos, endPos);
                    inputRef.current.focus();
                }
            }, 0);
        } else if (option.label === "from:" || option.label === "mentions:") {
            // For user filters, add the text and let the user type to trigger autocomplete
            const newQuery = query + (query ? " " : "") + option.label;
            setQuery(newQuery);
            setShowOptions(false);
            
            // Focus and position cursor
            setTimeout(() => {
                if (inputRef.current) {
                    const endPos = newQuery.length;
                    inputRef.current.setSelectionRange(endPos, endPos);
                    inputRef.current.focus();
                }
            }, 0);
        } else {
            // For other filters, add the text immediately
            const newQuery = query + (query ? " " : "") + option.label;
            setQuery(newQuery);
            // Ensure autocomplete is hidden
            setAutocompleteState({ type: "none" });
            inputRef.current?.focus();
        }
    };
    
    const handleAttachmentTypeClick = (type: string) => {
        // Add the attachment type to the query
        const newQuery = query + type + " ";
        setQuery(newQuery);
        setShowAttachmentTypes(false);
        
        // Move cursor to end and focus
        setTimeout(() => {
            if (inputRef.current) {
                const endPos = newQuery.length;
                inputRef.current.setSelectionRange(endPos, endPos);
                inputRef.current.focus();
            }
        }, 0);
    };
    
    // Format date to YYYY-MM-DD in local timezone
    const formatLocalDate = (date: Date) => {
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        return `${year}-${month}-${day}`;
    };
    
    const handleDateSelect = (date: Date) => {
        const dateStr = formatLocalDate(date); // Use local date formatting
        
        // Add the filter and date to the query with auto-space
        const filterText = `${showDatePicker}:${dateStr} `;
        const newQuery = query + (query ? " " : "") + filterText;
        
        setQuery(newQuery);
        setShowDatePicker(null);
        
        // Move cursor to end after the space
        setTimeout(() => {
            if (inputRef.current) {
                const endPos = newQuery.length;
                inputRef.current.setSelectionRange(endPos, endPos);
                inputRef.current.focus();
            }
        }, 0);
    };
    
    const handleRangeSelect = (startDate: Date, endDate: Date) => {
        const startStr = formatLocalDate(startDate);
        const endStr = formatLocalDate(endDate);
        
        // Store the actual date range in state
        setActiveDateRange({
            start: startStr,
            end: endStr,
            startDisplay: startDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),
            endDisplay: endDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })
        });
        
        // Only add "date-range" to the query, not the actual dates
        const filterText = `date-range `;
        const newQuery = query + (query ? " " : "") + filterText;
        
        setQuery(newQuery);
        setShowDatePicker(null);
        
        // Move cursor to end after the space
        setTimeout(() => {
            if (inputRef.current) {
                const endPos = newQuery.length;
                inputRef.current.setSelectionRange(endPos, endPos);
                inputRef.current.focus();
            }
        }, 0);
    };
    
    
    // Global keyboard shortcut
    useEffect(() => {
        const handleGlobalKeydown = (e: KeyboardEvent) => {
            if ((e.metaKey || e.ctrlKey) && e.key === "k") {
                e.preventDefault();
                inputRef.current?.focus();
            }
        };
        
        window.addEventListener("keydown", handleGlobalKeydown);
        return () => window.removeEventListener("keydown", handleGlobalKeydown);
    }, []);
    
    // Close date picker or attachment types when clicking outside
    useEffect(() => {
        if (showDatePicker || showAttachmentTypes) {
            const handleClickOutside = (e: MouseEvent) => {
                // Check if click is outside the container
                const container = e.target as HTMLElement;
                if (!container.closest('[data-search-container]') && !container.closest('[data-date-picker]')) {
                    setShowDatePicker(null);
                    setShowAttachmentTypes(false);
                }
            };
            
            document.addEventListener("mousedown", handleClickOutside);
            return () => document.removeEventListener("mousedown", handleClickOutside);
        }
    }, [showDatePicker, showAttachmentTypes]);
    
    return (
        <Container data-search-container onMouseDown={(e) => e.stopPropagation()}>
            <Input
                ref={inputRef}
                type="text"
                placeholder="Search"
                value={query}
                onFocus={handleFocus}
                onBlur={handleBlur}
                onClick={handleClick}
                onInput={handleInput}
                onKeyDown={handleKeyDown}
                onKeyUp={onKeyUp}
            />
            {isSearching ? (
                <IconButton onClick={handleClear}>
                    <X size={18} />
                </IconButton>
            ) : (
                <IconButton onClick={handleSearch}>
                    <Search size={18} />
                </IconButton>
            )}
            {autocompleteState.type !== "none" && (
                <SearchAutoComplete
                    state={autocompleteState}
                    setState={setAutocompleteState}
                    onClick={onAutocompleteClick}
                />
            )}
            {showOptions && autocompleteState.type === "none" && !showDatePicker && !showAttachmentTypes && (
                <OptionsDropdown onClick={(e) => e.stopPropagation()}>
                    <OptionsHeader>{"Search Options"}</OptionsHeader>
                    {searchOptions.map((option) => (
                        <Option
                            key={option.label}
                            onClick={() => handleOptionClick(option)}
                        >
                            <OptionLabel>{option.label}</OptionLabel>
                            <OptionDesc>{option.description}</OptionDesc>
                            <Tooltip content={option.tooltip} placement="top">
                                <HelpIcon size={16} />
                            </Tooltip>
                        </Option>
                    ))}
                </OptionsDropdown>
            )}
            {showDatePicker && (
                <SearchDatePicker
                    onSelect={handleDateSelect}
                    onRangeSelect={handleRangeSelect}
                    filterType={showDatePicker}
                />
            )}
            {showAttachmentTypes && (
                <OptionsDropdown onClick={(e) => e.stopPropagation()}>
                    <OptionsHeader>Attachment Types</OptionsHeader>
                    <Option onClick={() => handleAttachmentTypeClick("video")}>
                        <OptionLabel>video</OptionLabel>
                        <OptionDesc>Messages with videos</OptionDesc>
                    </Option>
                    <Option onClick={() => handleAttachmentTypeClick("image")}>
                        <OptionLabel>image</OptionLabel>
                        <OptionDesc>Messages with images</OptionDesc>
                    </Option>
                    <Option onClick={() => handleAttachmentTypeClick("link")}>
                        <OptionLabel>link</OptionLabel>
                        <OptionDesc>Messages with links</OptionDesc>
                    </Option>
                    <Option onClick={() => handleAttachmentTypeClick("audio")}>
                        <OptionLabel>audio</OptionLabel>
                        <OptionDesc>Messages with audio</OptionDesc>
                    </Option>
                    <Option onClick={() => handleAttachmentTypeClick("file")}>
                        <OptionLabel>file</OptionLabel>
                        <OptionDesc>Messages with files</OptionDesc>
                    </Option>
                </OptionsDropdown>
            )}
        </Container>
    );
}