'use client'

import React, { useEffect, useMemo, useRef, useState } from 'react'
import { cn, Input, Popover, PopoverAnchor, PopoverContent } from 'ui'

import { DefaultCommandList } from './DefaultCommandList'
import { useFilterBar } from './FilterBarContext'
import { FilterCondition } from './FilterCondition'
import { useDeferredBlur, useHighlightNavigation } from './hooks'
import { buildPropertyItems } from './menuItems'
import { FilterGroup as FilterGroupType } from './types'
import { buildFilterPlaceholder, pathsEqual } from './utils'

export type FilterGroupProps = {
  group: FilterGroupType
  path: number[]
}

export function FilterGroup({ group, path }: FilterGroupProps) {
  const {
    filterProperties,
    activeInput,
    freeformText,
    supportsOperators,
    actions,
    variant,
    highlightedConditionPath,
    freeformDefaultProperty,
    handleInputBlur,
    handleGroupFreeformFocus,
    handleGroupFreeformChange,
    handleLogicalOperatorChange,
    handleKeyDown,
    handleSelectMenuItem,
  } = useFilterBar()

  const [localFreeformValue, setLocalFreeformValue] = useState('')
  const freeformInputRef = useRef<HTMLInputElement>(null)
  const wrapperRef = useRef<HTMLDivElement>(null)
  const [isHoveringOperator, setIsHoveringOperator] = useState(false)

  const isActive = activeInput?.type === 'group' && pathsEqual(path, activeInput.path)

  useEffect(() => {
    if (freeformText === '') {
      setLocalFreeformValue('')
    }
  }, [freeformText])

  useEffect(() => {
    if (isActive && freeformInputRef.current) {
      freeformInputRef.current.focus()
    }
  }, [isActive])

  const handleFreeformBlur = useDeferredBlur(
    wrapperRef as React.RefObject<HTMLElement>,
    handleInputBlur
  )

  const handleFreeformChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setLocalFreeformValue(e.target.value)
    handleGroupFreeformChange(path, e.target.value)
  }

  const handleLogicalOperatorClick = () => {
    handleLogicalOperatorChange(path)
  }

  const isConditionActive = (conditionPath: number[]) => {
    if (!activeInput) return false
    return activeInput.type === 'value' && pathsEqual(conditionPath, activeInput.path)
  }

  const isOperatorActive = (conditionPath: number[]) => {
    if (!activeInput) return false
    return activeInput.type === 'operator' && pathsEqual(conditionPath, activeInput.path)
  }

  const isPropertyActiveForCondition = (conditionPath: number[]) => {
    if (!activeInput) return false
    return activeInput.type === 'property' && pathsEqual(conditionPath, activeInput.path)
  }

  const isConditionHighlighted = (conditionPath: number[]) => {
    if (!highlightedConditionPath) return false
    return pathsEqual(conditionPath, highlightedConditionPath)
  }

  // Free-text search only applies to the root group's input — nested groups don't synthesize
  // a "Search <property>" item.
  const resolvedFreeformDefaultProperty = useMemo(
    () =>
      path.length === 0 && freeformDefaultProperty
        ? filterProperties.find((p) => p.name === freeformDefaultProperty)
        : undefined,
    [path.length, freeformDefaultProperty, filterProperties]
  )

  const items = useMemo(
    () =>
      buildPropertyItems({
        filterProperties,
        inputValue: (isActive ? freeformText : localFreeformValue) || '',
        actions,
        supportsOperators,
        freeformDefaultProperty: resolvedFreeformDefaultProperty,
      }),
    [
      filterProperties,
      isActive,
      freeformText,
      localFreeformValue,
      actions,
      supportsOperators,
      resolvedFreeformDefaultProperty,
    ]
  )

  const emptyPlaceholder = useMemo(
    () =>
      buildFilterPlaceholder(filterProperties, {
        hasActions: actions && actions.length > 0,
      }),
    [filterProperties, actions]
  )

  // Only the root group should expand to fill available space
  const isRootGroup = path.length === 0

  const {
    highlightedIndex,
    handleKeyDown: handleFreeformKeyDown,
    reset: resetFreeformHighlight,
  } = useHighlightNavigation(
    items.length,
    (index) => {
      if (items[index]) handleSelectMenuItem(items[index])
    },
    handleKeyDown,
    { skipEnterWhenFilterHighlighted: highlightedConditionPath !== null }
  )

  useEffect(() => {
    if (!isActive) resetFreeformHighlight()
  }, [isActive, resetFreeformHighlight])

  return (
    <div
      ref={wrapperRef}
      className={`flex items-stretch gap-0 shrink-0 ${
        path.length > 0
          ? "before:content-['('] before:text-foreground-muted after:content-[')'] after:text-foreground-muted"
          : ''
      } ${isRootGroup ? 'flex-1 min-w-0' : ''}`}
    >
      <div
        className={cn(
          'flex items-center flex-wrap',
          isRootGroup ? 'flex-1 min-w-0' : '',
          variant === 'pill' ? 'gap-1' : 'gap-0'
        )}
      >
        {group.conditions.map((condition, index) => {
          const currentPath = [...path, index]

          return (
            <React.Fragment key={index}>
              {index > 0 && supportsOperators && (
                <span
                  className={`text-xs font-medium cursor-pointer ${
                    isHoveringOperator
                      ? 'bg-surface-400 text-foreground dark:bg-surface-400'
                      : 'text-foreground-muted'
                  }`}
                  onClick={handleLogicalOperatorClick}
                  onMouseEnter={() => setIsHoveringOperator(true)}
                  onMouseLeave={() => setIsHoveringOperator(false)}
                >
                  {group.logicalOperator}
                </span>
              )}
              {'logicalOperator' in condition ? (
                <FilterGroup group={condition} path={currentPath} />
              ) : (
                <FilterCondition
                  condition={condition}
                  path={currentPath}
                  isActive={isConditionActive(currentPath)}
                  isOperatorActive={isOperatorActive(currentPath)}
                  isPropertyActive={isPropertyActiveForCondition(currentPath)}
                  isHighlighted={isConditionHighlighted(currentPath)}
                />
              )}
            </React.Fragment>
          )
        })}
        <Popover open={isActive && items.length > 0 && !highlightedConditionPath}>
          <PopoverAnchor asChild>
            {isRootGroup ? (
              <Input
                ref={freeformInputRef}
                type="text"
                value={isActive ? freeformText : localFreeformValue}
                onChange={handleFreeformChange}
                onFocus={() => handleGroupFreeformFocus(path)}
                onBlur={handleFreeformBlur}
                onKeyDown={handleFreeformKeyDown}
                className="border-none bg-transparent text-xs focus:outline-hidden focus:ring-0 focus:shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 w-full flex-1 h-auto min-w-0 px-2 py-1"
                placeholder={
                  group.conditions.length === 0 ? emptyPlaceholder : 'Add more filters...'
                }
                data-testid="filter-bar-freeform-input"
                autoComplete="off"
                data-1p-ignore
                data-lpignore="true"
                data-form-type="other"
              />
            ) : (
              <div className="relative inline-block py-1">
                <Input
                  ref={freeformInputRef}
                  type="text"
                  value={isActive ? freeformText : localFreeformValue}
                  onChange={handleFreeformChange}
                  onFocus={() => handleGroupFreeformFocus(path)}
                  onBlur={handleFreeformBlur}
                  onKeyDown={handleFreeformKeyDown}
                  className="h-full border-none bg-transparent py-0 text-xs md:text-xs focus:outline-hidden focus:ring-0 focus:shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 w-full absolute left-0 top-0 px-2"
                  placeholder="+ Add filter"
                  autoComplete="off"
                  data-1p-ignore
                  data-lpignore="true"
                  data-form-type="other"
                />
                <span className="invisible whitespace-pre text-xs block">
                  {(isActive ? freeformText : localFreeformValue) || '+'}
                </span>
              </div>
            )}
          </PopoverAnchor>
          <PopoverContent
            className="min-w-[220px] max-w-[360px] p-0"
            align="start"
            side="bottom"
            onOpenAutoFocus={(e) => e.preventDefault()}
            onCloseAutoFocus={(e) => e.preventDefault()}
            onInteractOutside={(e) => {
              const target = e.target as Node
              if (wrapperRef.current && !wrapperRef.current.contains(target)) {
                handleInputBlur()
              }
            }}
          >
            <DefaultCommandList
              items={items}
              highlightedIndex={highlightedIndex}
              onSelect={handleSelectMenuItem}
              includeIcon
            />
          </PopoverContent>
        </Popover>
      </div>
    </div>
  )
}
