/**
 * DynamicBOMSection - 동적 BOM 섹션
 *
 * 기존 BOMSection과 100% 동일한 디자인
 * 품목 검색 API 연동 (/api/proxy/items?search=xxx)
 */

'use client';

import { Fragment, useState, useEffect, useCallback, useRef } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { getPresetStyle } from '@/lib/utils/status-config';
import { NumberInput } from '@/components/ui/number-input';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  Popover,
  PopoverAnchor,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/components/ui/command';
import { Check, Package, Plus, Search, Trash2, Loader2 } from 'lucide-react';
import type { BOMLine, BOMSearchState, DynamicSection } from '../types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';

/**
 * 품목 유형(FG, PT, SM, RM, CS)을 BOM child_item_type으로 변환
 * - PRODUCT: FG(제품), PT(부품)
 * - MATERIAL: SM(원자재), RM(원자재), CS(부자재)
 */
function getChildItemType(itemType: string | undefined): 'PRODUCT' | 'MATERIAL' {
  if (!itemType) return 'PRODUCT';
  const upperType = itemType.toUpperCase();
  // SM, RM, CS는 MATERIAL
  if (['SM', 'RM', 'CS'].includes(upperType)) {
    return 'MATERIAL';
  }
  // FG, PT 등은 PRODUCT
  return 'PRODUCT';
}

// 품목 검색 결과 타입
interface SearchedItem {
  id: string;
  itemCode: string;
  itemName: string;
  specification?: string;
  material?: string;
  unit: string;
  partType?: string;
  bendingDiagram?: string;
  itemType?: string;  // FG, PT, SM, RM, CS 등 품목 유형
}

// Debounce 훅
function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debouncedValue;
}

export interface DynamicBOMSectionProps {
  section: DynamicSection;
  bomLines: BOMLine[];
  setBomLines: (lines: BOMLine[]) => void;
  bomSearchStates: Record<string, BOMSearchState>;
  setBomSearchStates: (states: Record<string, BOMSearchState>) => void;
  isSubmitting: boolean;
}

export default function DynamicBOMSection({
  section,
  bomLines,
  setBomLines,
  bomSearchStates,
  setBomSearchStates,
  isSubmitting,
}: DynamicBOMSectionProps) {
  // 품목 검색 상태
  const [searchResults, setSearchResults] = useState<Record<string, SearchedItem[]>>({});
  const [isSearching, setIsSearching] = useState<Record<string, boolean>>({});

  // 품목 검색 API 호출 (검색어 있을 때만)
  const searchItems = useCallback(async (lineId: string, query: string) => {
    // 검색어가 없으면 빈 결과 (사용자가 검색어 입력 필요)
    if (!query || query.length < 1) {
      setSearchResults((prev) => ({ ...prev, [lineId]: [] }));
      return;
    }

    setIsSearching((prev) => ({ ...prev, [lineId]: true }));

    try {
      const params = new URLSearchParams();
      params.append('search', query);
      params.append('size', '20');
      params.append('group_id', '1');  // 전체 품목 조회 (품목관리 그룹)

      const response = await fetch(`/api/proxy/items?${params.toString()}`);
      const result = await response.json();

      if (result.success) {
        const paginatedData = result.data;
        const rawItems = paginatedData?.data ?? paginatedData ?? [];

        const mappedItems: SearchedItem[] = rawItems.map((item: Record<string, unknown>) => ({
          id: String(item.id),
          itemCode: (item.code ?? item.item_code ?? '') as string,
          itemName: (item.name ?? item.item_name ?? '') as string,
          specification: (item.specification ?? '') as string,
          material: (item.material ?? '') as string,
          unit: (item.unit ?? 'EA') as string,
          partType: (item.part_type ?? '') as string,
          bendingDiagram: (item.bending_diagram ?? '') as string,
          itemType: (item.product_type ?? item.item_type ?? '') as string,  // FG, PT, SM, RM, CS
        }));

        setSearchResults((prev) => ({ ...prev, [lineId]: mappedItems }));
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('품목 검색 실패:', error);
      setSearchResults((prev) => ({ ...prev, [lineId]: [] }));
    } finally {
      setIsSearching((prev) => ({ ...prev, [lineId]: false }));
    }
  }, []);

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <div>
            <CardTitle>{section.section.title}</CardTitle>
            {section.section.description && (
              <p className="text-sm text-muted-foreground mt-1">
                {section.section.description}
              </p>
            )}
          </div>
          <Button
            type="button"
            variant="outline"
            size="sm"
            onClick={() => {
              const newLine: BOMLine = {
                id: `bom-${Date.now()}`,
                childItemCode: '',
                childItemName: '',
                quantity: 1,
                unit: 'EA',
              };
              setBomLines([...bomLines, newLine]);
            }}
            disabled={isSubmitting}
          >
            <Plus className="h-4 w-4 mr-2" />
            BOM 품목 추가
          </Button>
        </div>
      </CardHeader>
      <CardContent>
        {bomLines.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-12 text-center">
            <Package className="h-16 w-16 text-muted-foreground mb-4 opacity-20" />
            <p className="text-sm text-muted-foreground mb-2">
              아직 부품 구성이 추가되지 않았습니다
            </p>
            <p className="text-xs text-muted-foreground">
              품목의 구성 부품, 원자재, 부자재를 추가할 수 있습니다
            </p>
          </div>
        ) : (
          <div className="overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-[280px]">품목코드 / 품목명 입력</TableHead>
                  <TableHead className="w-[180px]">품목명</TableHead>
                  <TableHead className="w-[150px]">규격</TableHead>
                  <TableHead className="w-[100px]">재질</TableHead>
                  <TableHead className="w-20">수량</TableHead>
                  <TableHead className="w-16">단위</TableHead>
                  <TableHead className="w-[180px]">비고</TableHead>
                  <TableHead className="w-16">삭제</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {bomLines.map((line) => (
                  <BOMLineRow
                    key={line.id}
                    line={line}
                    bomLines={bomLines}
                    setBomLines={setBomLines}
                    bomSearchStates={bomSearchStates}
                    setBomSearchStates={setBomSearchStates}
                    searchResults={searchResults[line.id] || []}
                    isSearching={isSearching[line.id] || false}
                    searchItems={searchItems}
                  />
                ))}
              </TableBody>
            </Table>
          </div>
        )}
      </CardContent>
    </Card>
  );
}

// BOM 라인 Row 컴포넌트 (검색 debounce 처리용)
function BOMLineRow({
  line,
  bomLines,
  setBomLines,
  bomSearchStates,
  setBomSearchStates,
  searchResults,
  isSearching,
  searchItems,
}: {
  line: BOMLine;
  bomLines: BOMLine[];
  setBomLines: (lines: BOMLine[]) => void;
  bomSearchStates: Record<string, BOMSearchState>;
  setBomSearchStates: (states: Record<string, BOMSearchState>) => void;
  searchResults: SearchedItem[];
  isSearching: boolean;
  searchItems: (lineId: string, query: string) => void;
}) {
  const searchState = bomSearchStates[line.id] || { searchValue: '', isOpen: false };
  const searchValue = searchState.searchValue;
  const searchOpen = searchState.isOpen;

  // Debounce 검색
  const debouncedSearchValue = useDebounce(searchValue, 300);

  // 안정적인 검색 함수 ref
  const searchItemsRef = useRef(searchItems);
  searchItemsRef.current = searchItems;

  // 검색어 변경 시 검색 실행
  useEffect(() => {
    if (searchOpen) {
      searchItemsRef.current(line.id, debouncedSearchValue);
    }
  }, [debouncedSearchValue, searchOpen, line.id]);

  return (
    <Fragment>
      <TableRow>
        <TableCell>
          <div className="flex gap-1">
            <Popover
              open={searchOpen}
              onOpenChange={(open) => {
                setBomSearchStates({
                  ...bomSearchStates,
                  [line.id]: { ...searchState, isOpen: open },
                });
              }}
            >
              <div className="flex-1 relative">
                <PopoverAnchor asChild>
                  <Input
                    placeholder="품목코드 또는 품목명 입력..."
                    value={line.childItemCode || searchValue}
                    onChange={(e) => {
                      setBomSearchStates({
                        ...bomSearchStates,
                        [line.id]: { searchValue: e.target.value, isOpen: true },
                      });
                    }}
                    onFocus={() => {
                      if (!line.childItemCode) {
                        setBomSearchStates({
                          ...bomSearchStates,
                          [line.id]: { ...searchState, isOpen: true },
                        });
                      }
                    }}
                    className="w-full"
                    readOnly={!!line.childItemCode}
                  />
                </PopoverAnchor>
                {line.childItemCode && (
                  <div className="absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none">
                    <Check className="h-4 w-4 text-green-600" />
                  </div>
                )}
              </div>
              <PopoverTrigger asChild>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    setBomSearchStates({
                      ...bomSearchStates,
                      [line.id]: { searchValue: '', isOpen: true },
                    });
                  }}
                >
                  <Search className="h-4 w-4" />
                </Button>
              </PopoverTrigger>
              <PopoverContent
                className="w-[400px] p-0"
                side="bottom"
                align="start"
                sideOffset={4}
              >
                <Command>
                  <CommandInput
                    placeholder="품목코드 또는 품목명 검색..."
                    value={searchValue}
                    onValueChange={(value) => {
                      setBomSearchStates({
                        ...bomSearchStates,
                        [line.id]: { ...searchState, searchValue: value },
                      });
                    }}
                  />
                  <CommandList>
                    {isSearching ? (
                      <div className="flex items-center justify-center py-6">
                        <Loader2 className="h-4 w-4 animate-spin mr-2" />
                        <span className="text-sm text-muted-foreground">
                          검색 중...
                        </span>
                      </div>
                    ) : !searchValue ? (
                      <div className="flex flex-col items-center justify-center py-6 text-center">
                        <Search className="h-8 w-8 text-muted-foreground mb-2 opacity-40" />
                        <span className="text-sm text-muted-foreground">
                          품목코드 또는 품목명을 입력하세요
                        </span>
                      </div>
                    ) : searchResults.length === 0 ? (
                      <CommandEmpty>
                        검색 결과가 없습니다.
                      </CommandEmpty>
                    ) : (
                      <CommandGroup>
                        {searchResults.map((item) => (
                          <CommandItem
                            key={item.id}
                            value={`${item.itemCode} ${item.itemName}`}
                            onSelect={() => {
                              const isBendingPart = item.partType === 'BENDING';
                              // 품목 유형에 따라 PRODUCT/MATERIAL 결정
                              const childItemType = getChildItemType(item.itemType);

                              setBomLines(
                                bomLines.map((l) =>
                                  l.id === line.id
                                    ? {
                                        ...l,
                                        childItemId: item.id || '',
                                        childItemType,  // PRODUCT 또는 MATERIAL
                                        childItemCode: item.itemCode || '',
                                        childItemName: item.itemName || '',
                                        specification: item.specification || '',
                                        material: item.material || '',
                                        unit: item.unit || 'EA',
                                        unitPrice: 0,
                                        isBending: isBendingPart,
                                        bendingDiagram: isBendingPart
                                          ? item.bendingDiagram
                                          : undefined,
                                      }
                                    : l
                                )
                              );
                              setBomSearchStates({
                                ...bomSearchStates,
                                [line.id]: { searchValue: '', isOpen: false },
                              });
                            }}
                            className="cursor-pointer"
                          >
                            <div className="flex items-center justify-between w-full">
                              <div className="flex-1">
                                <div className="flex items-center gap-2">
                                  <code className="text-xs bg-gray-100 px-2 py-0.5 rounded">
                                    {item.itemCode}
                                  </code>
                                  <span className="text-sm">{item.itemName}</span>
                                  {item.specification && (
                                    <span className="text-xs text-muted-foreground">
                                      ({item.specification})
                                    </span>
                                  )}
                                </div>
                              </div>
                              <Badge variant="secondary" className="ml-2">
                                {item.unit}
                              </Badge>
                            </div>
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    )}
                  </CommandList>
                </Command>
              </PopoverContent>
            </Popover>
          </div>
        </TableCell>
        <TableCell className="text-sm">{line.childItemName || '-'}</TableCell>
        <TableCell className="text-sm text-muted-foreground">
          {line.specification || '-'}
        </TableCell>
        <TableCell className="text-sm text-muted-foreground">
          {line.material || '-'}
        </TableCell>
        <TableCell>
          <NumberInput
            value={line.quantity}
            onChange={(value) => {
              setBomLines(
                bomLines.map((l) =>
                  l.id === line.id ? { ...l, quantity: value ?? 0 } : l
                )
              );
            }}
            min={0}
            step={0.01}
            allowDecimal
            className="w-full"
          />
        </TableCell>
        <TableCell>
          <Badge variant="secondary">{line.unit}</Badge>
        </TableCell>
        <TableCell>
          <Input
            value={line.note || ''}
            onChange={(e) => {
              setBomLines(
                bomLines.map((l) =>
                  l.id === line.id ? { ...l, note: e.target.value } : l
                )
              );
            }}
            placeholder="비고"
            className="w-full text-xs"
          />
        </TableCell>
        <TableCell>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            onClick={() => {
              setBomLines(bomLines.filter((l) => l.id !== line.id));
            }}
          >
            <Trash2 className="h-4 w-4 text-red-600" />
          </Button>
        </TableCell>
      </TableRow>

      {/* 절곡품인 경우 전개도 정보 표시 */}
      {line.isBending && line.bendingDiagram && (
        <TableRow>
          <TableCell colSpan={8} className="bg-blue-50 p-4">
            <div className="space-y-3">
              <div className="flex items-center gap-2">
                <Badge variant="outline" className={getPresetStyle('info')}>
                  절곡품 전개도 정보
                </Badge>
              </div>

              {/* 전개도 이미지 */}
              <div>
                <Label className="text-xs mb-2 block">전개도 이미지</Label>
                <div className="border rounded-lg p-2 bg-white">
                  <img
                    src={line.bendingDiagram}
                    alt="절곡 전개도"
                    className="max-w-full h-auto max-h-[300px] object-contain mx-auto"
                  />
                </div>
              </div>
            </div>
          </TableCell>
        </TableRow>
      )}
    </Fragment>
  );
}