'use client';

/**
 * 계정과목 Select 공용 컴포넌트
 *
 * DB 마스터에서 활성 계정과목(소분류, depth=3)을 로드하여 검색 가능한 Select로 표시.
 * "[코드] 계정과목명" 형태로 표시. 코드/이름으로 검색 가능.
 * Popover + Command 패턴 (SearchableSelect 기반).
 * props로 category 제한 가능.
 */

import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import { Check, ChevronsUpDown, Loader2 } from 'lucide-react';
import { cn } from '@/components/ui/utils';
import { Button } from '@/components/ui/button';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/components/ui/command';
import { getAccountSubjects } from './actions';
import type { AccountSubject, AccountSubjectCategory } from './types';
import { formatAccountLabel } from './types';

interface AccountSubjectSelectProps {
  value: string;
  onValueChange: (value: string) => void;
  /** 특정 대분류만 표시 */
  category?: AccountSubjectCategory;
  /** 특정 중분류만 표시 */
  subCategory?: string;
  /** 특정 부문만 표시 */
  departmentType?: string;
  placeholder?: string;
  disabled?: boolean;
  className?: string;
  /** 빈 값(전체) 옵션 표시 여부 */
  showAllOption?: boolean;
  allOptionLabel?: string;
  /** 트리거 크기 */
  size?: 'default' | 'sm';
  /** value/onValueChange에 사용할 필드 (기본: code) */
  valueField?: 'code' | 'id';
}

export function AccountSubjectSelect({
  value,
  onValueChange,
  category,
  subCategory,
  departmentType,
  placeholder = '계정과목 선택',
  disabled = false,
  className,
  showAllOption = false,
  allOptionLabel = '전체',
  size = 'default',
  valueField = 'code',
}: AccountSubjectSelectProps) {
  const [subjects, setSubjects] = useState<AccountSubject[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [open, setOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const triggerRef = useRef<HTMLButtonElement>(null);

  const loadSubjects = useCallback(async () => {
    setIsLoading(true);
    try {
      const result = await getAccountSubjects({
        depth: 3,
        category: category || undefined,
        subCategory: subCategory || undefined,
        departmentType: departmentType || undefined,
      });
      if (result.success && result.data) {
        setSubjects(result.data);
      }
    } catch {
      // 조회 실패 시 빈 목록 유지
    } finally {
      setIsLoading(false);
    }
  }, [category, subCategory, departmentType]);

  useEffect(() => {
    loadSubjects();
  }, [loadSubjects]);

  // subject에서 value로 사용할 필드 추출
  const getSubjectValue = useCallback(
    (s: AccountSubject) => (valueField === 'id' ? s.id : s.code),
    [valueField]
  );

  // 선택된 계정과목 찾기
  const selectedSubject = useMemo(
    () => subjects.find((s) => getSubjectValue(s) === value),
    [subjects, value, getSubjectValue]
  );

  // 트리거에 표시할 텍스트
  const displayLabel = useMemo(() => {
    if (isLoading) return '로딩 중...';
    if (value === 'all' && showAllOption) return allOptionLabel;
    if (selectedSubject) return formatAccountLabel(selectedSubject);
    return '';
  }, [isLoading, value, showAllOption, allOptionLabel, selectedSubject]);

  const handleSelect = (subjectValue: string) => {
    onValueChange(subjectValue);
    setOpen(false);
    setSearchQuery('');
  };

  const handleOpenChange = (isOpen: boolean) => {
    setOpen(isOpen);
    if (!isOpen) {
      setSearchQuery('');
    }
  };

  const triggerClassName = size === 'sm' ? 'h-8 text-sm' : 'h-9 text-sm';

  return (
    <Popover open={open} onOpenChange={handleOpenChange} modal>
      <PopoverTrigger asChild>
        <Button
          ref={triggerRef}
          variant="outline"
          role="combobox"
          aria-expanded={open}
          disabled={disabled || isLoading}
          className={cn(
            'w-full justify-between font-normal',
            triggerClassName,
            !displayLabel && 'text-muted-foreground',
            className
          )}
        >
          <span className="truncate">
            {displayLabel || placeholder}
          </span>
          {isLoading ? (
            <Loader2 className="ml-2 h-4 w-4 shrink-0 animate-spin" />
          ) : (
            <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
          )}
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="w-[--radix-popover-trigger-width] min-w-[280px] p-0"
        align="start"
      >
        <Command shouldFilter>
          <CommandInput
            placeholder="코드 또는 계정과목명 검색..."
            value={searchQuery}
            onValueChange={setSearchQuery}
          />
          <CommandList>
            <CommandEmpty>검색 결과가 없습니다</CommandEmpty>
            <CommandGroup>
              {showAllOption && (
                <CommandItem
                  value={allOptionLabel}
                  onSelect={() => handleSelect('all')}
                  className="cursor-pointer"
                >
                  <Check
                    className={cn(
                      'mr-2 h-4 w-4',
                      value === 'all' ? 'opacity-100' : 'opacity-0'
                    )}
                  />
                  {allOptionLabel}
                </CommandItem>
              )}
              {subjects.map((subject) => {
                const subjectVal = getSubjectValue(subject);
                return (
                  <CommandItem
                    key={subject.id}
                    value={`${subject.code} ${subject.name}`}
                    onSelect={() => handleSelect(subjectVal)}
                    className="cursor-pointer"
                  >
                    <Check
                      className={cn(
                        'mr-2 h-4 w-4',
                        value === subjectVal ? 'opacity-100' : 'opacity-0'
                      )}
                    />
                    <span className="text-muted-foreground mr-1.5 font-mono text-xs">
                      {subject.code}
                    </span>
                    <span>{subject.name}</span>
                  </CommandItem>
                );
              })}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}
