'use client';

import { useEffect, useRef, useState } from 'react';
import { Input } from '@/components/ui/input';
import { meetingAttendanceApi } from '@/services/api/meeting-attendance';
import { useDebounce } from '@/hooks/useDebounce';
import { colors, typography } from '@/styles/theme';

export interface CityAutocompleteInputProps {
  id?: string;
  name?: string;
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  disabled?: boolean;
  className?: string;
  style?: React.CSSProperties;
  maxLength?: number;
  'aria-invalid'?: boolean;
  'data-testid'?: string;
}

export default function CityAutocompleteInput(props: CityAutocompleteInputProps) {
  const { value, onChange, placeholder, disabled, className, style, maxLength = 100 } = props;
  const debouncedValue = useDebounce(value, 200);
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  const [suggestions, setSuggestions] = useState<string[]>([]);
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    meetingAttendanceApi
      .listCitySuggestions({ keyword: debouncedValue || undefined, limit: 20 })
      .then((resp: any) => {
        if (cancelled) return;
        const list: string[] = Array.isArray(resp)
          ? resp
          : Array.isArray(resp?.items)
            ? resp.items
            : Array.isArray(resp?.data)
              ? resp.data
              : [];
        setSuggestions(list);
      })
      .catch(() => {
        if (!cancelled) setSuggestions([]);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [debouncedValue]);

  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (!containerRef.current) return;
      if (!containerRef.current.contains(e.target as Node)) setOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, []);

  const filtered = value
    ? suggestions.filter((s) => s.toLowerCase().includes(value.toLowerCase()) && s !== value)
    : suggestions;

  return (
    <div ref={containerRef} className="relative">
      <Input
        id={props.id}
        name={props.name}
        value={value}
        onChange={(e) => {
          onChange(e.target.value);
          if (!open) setOpen(true);
        }}
        onFocus={() => setOpen(true)}
        placeholder={placeholder}
        disabled={disabled}
        className={className}
        style={style}
        maxLength={maxLength}
        autoComplete="off"
        aria-invalid={props['aria-invalid']}
        data-testid={props['data-testid']}
      />
      {open && !disabled && filtered.length > 0 && (
        <div
          className="absolute left-0 right-0 mt-1 z-50 max-h-64 overflow-y-auto rounded-md bg-white shadow-lg"
          style={{ border: `1px solid ${colors.border}` }}
          role="listbox"
        >
          {filtered.map((city) => (
            <button
              key={city}
              type="button"
              role="option"
              onMouseDown={(e) => {
                e.preventDefault();
                onChange(city);
                setOpen(false);
              }}
              className="w-full text-left px-3 py-2 text-sm hover:bg-gray-50"
              style={{ color: colors.textPrimary }}
            >
              {city}
            </button>
          ))}
        </div>
      )}
      {open && !disabled && !loading && filtered.length === 0 && value.trim() && (
        <div
          className="absolute left-0 right-0 mt-1 z-50 rounded-md bg-white shadow-lg px-3 py-2"
          style={{ border: `1px solid ${colors.border}` }}
        >
          <span className={typography.caption} style={{ color: colors.textTertiary }}>
            {value.trim()}
          </span>
        </div>
      )}
    </div>
  );
}
