"use client"

import * as React from "react"
import { useForm, useFieldArray, useWatch } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { z } from "zod"

import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage
} from "@/components/ui/form"
import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover"
import {
  Command,
  CommandInput,
  CommandList,
  CommandItem,
  CommandGroup,
  CommandEmpty
} from "@/components/ui/command"
import { Check, ChevronsUpDown, Plus, Trash2, Save, X, AlertCircle, Eye } from "lucide-react"
import { toast } from "sonner"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog"
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip"
import { Badge } from "@/components/ui/badge"

import { createRfqItem, deleteRfqItem } from "../service"
import { RfqWithItemCount } from "@/db/schema/rfq"
import { RfqType } from "../validations"

// Zod 스키마 - 수량은 string으로 받아서 나중에 변환
const itemSchema = z.object({
  id: z.number().optional(),
  itemCode: z.string().nonempty({ message: "아이템 코드를 선택해주세요" }),
  description: z.string().optional(),
  quantity: z.coerce.number().min(1, { message: "최소 수량은 1입니다" }).default(1),
  uom: z.string().default("each"),
});

const itemsFormSchema = z.object({
  rfqId: z.number().int(),
  items: z.array(itemSchema).min(1, { message: "최소 1개 이상의 아이템을 추가해주세요" }),
});

type ItemsFormSchema = z.infer<typeof itemsFormSchema>;

interface RfqsItemsDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  rfq: RfqWithItemCount | null;
  defaultItems?: {
    id?: number;
    itemCode: string;
    quantity?: number | null;
    description?: string | null;
    uom?: string | null;
  }[];
  itemsList: { code: string | null; name: string }[];
  rfqType?: RfqType;
}

export function RfqsItemsDialog({
  open,
  onOpenChange,
  rfq,
  defaultItems = [],
  itemsList,
  rfqType
}: RfqsItemsDialogProps) {
  const rfqId = rfq?.rfqId ?? 0;

  // 편집 가능 여부 확인 - DRAFT 상태일 때만 편집 가능
  const isEditable = rfq?.status === "DRAFT";

  // 초기 아이템 ID 목록을 추적하기 위한 상태 추가
  const [initialItemIds, setInitialItemIds] = React.useState<(number | undefined)[]>([]);

  // 삭제된 아이템 ID를 저장하는 상태 추가
  const [deletedItemIds, setDeletedItemIds] = React.useState<number[]>([]);

  // 1) form
  const form = useForm<ItemsFormSchema>({
    resolver: zodResolver(itemsFormSchema),
    defaultValues: {
      rfqId,
      items: defaultItems.length > 0 ? defaultItems.map((it) => ({
        id: it.id,
        quantity: it.quantity ?? 1,
        uom: it.uom ?? "each",
        itemCode: it.itemCode ?? "",
        description: it.description ?? "",
      })) : [{ itemCode: "", description: "", quantity: 1, uom: "each" }],
    },
    mode: "onChange", // 입력 필드가 변경될 때마다 유효성 검사
  });

  // 다이얼로그가 열릴 때마다 폼 초기화 및 초기 아이템 ID 저장
  React.useEffect(() => {
    if (open) {
      const initialItems = defaultItems.length > 0
        ? defaultItems.map((it) => ({
          id: it.id,
          quantity: it.quantity ?? 1,
          uom: it.uom ?? "each",
          itemCode: it.itemCode ?? "",
          description: it.description ?? "",
        }))
        : [{ itemCode: "", description: "", quantity: 1, uom: "each" }];

      form.reset({
        rfqId,
        items: initialItems,
      });

      // 초기 아이템 ID 목록 저장
      setInitialItemIds(defaultItems.map(item => item.id));

      // 삭제된 아이템 목록 초기화
      setDeletedItemIds([]);
      setHasUnsavedChanges(false);
    }
  }, [open, defaultItems, rfqId, form]);

  // 새로운 요소에 대한 ref 배열
  const inputRefs = React.useRef<Array<HTMLButtonElement | null>>([]);
  const [isSubmitting, setIsSubmitting] = React.useState(false);
  const [hasUnsavedChanges, setHasUnsavedChanges] = React.useState(false);
  const [isExitDialogOpen, setIsExitDialogOpen] = React.useState(false);

  // 폼 변경 감지 - 편집 가능한 경우에만 변경 감지
  React.useEffect(() => {
    if (!isEditable) return;

    const subscription = form.watch(() => {
      setHasUnsavedChanges(true);
    });
    return () => subscription.unsubscribe();
  }, [form, isEditable]);

  // 2) field array
  const { fields, append, remove } = useFieldArray({
    control: form.control,
    name: "items",
  });

  // 3) watch items array
  const watchItems = form.watch("items");

  // 4) Add item row with auto-focus
  function handleAddItem() {
    if (!isEditable) return;

    // 명시적으로 숫자 타입으로 지정
    append({
      itemCode: "",
      description: "",
      quantity: 1,
      uom: "each"
    });
    setHasUnsavedChanges(true);

    // 다음 렌더링 사이클에서 새로 추가된 항목에 포커스
    setTimeout(() => {
      const newIndex = fields.length;
      const button = inputRefs.current[newIndex];
      if (button) {
        button.click();
      }
    }, 100);
  }

  // 항목 직접 삭제 - 기존 ID가 있을 경우 삭제 목록에 추가
  const handleRemoveItem = (index: number) => {
    if (!isEditable) return;

    const itemToRemove = form.getValues().items[index];

    // 기존 ID가 있는 아이템이라면 삭제 목록에 추가
    if (itemToRemove.id !== undefined) {
      setDeletedItemIds(prev => [...prev, itemToRemove.id as number]);
    }

    remove(index);
    setHasUnsavedChanges(true);

    // 포커스 처리: 다음 항목이 있으면 다음 항목으로, 없으면 마지막 항목으로
    setTimeout(() => {
      const nextIndex = Math.min(index, fields.length - 1);
      if (nextIndex >= 0 && inputRefs.current[nextIndex]) {
        inputRefs.current[nextIndex]?.click();
      }
    }, 50);
  };

  // 다이얼로그 닫기 전 확인
  const handleDialogClose = (open: boolean) => {
    if (!open && hasUnsavedChanges && isEditable) {
      setIsExitDialogOpen(true);
    } else {
      onOpenChange(open);
    }
  };

  // 필드 포커스 유틸리티 함수
  const focusField = (selector: string) => {
    if (!isEditable) return;

    setTimeout(() => {
      const element = document.querySelector(selector) as HTMLInputElement | null;
      if (element) {
        element.focus();
      }
    }, 10);
  };

  // 5) Submit - 업데이트된 제출 로직 (생성/수정 + 삭제 처리)
  async function onSubmit(data: ItemsFormSchema) {
    if (!isEditable) return;

    try {
      setIsSubmitting(true);

      // 각 아이템이 유효한지 확인 
      const anyInvalidItems = data.items.some(item => !item.itemCode || item.quantity < 1);

      if (anyInvalidItems) {
        toast.error("유효하지 않은 아이템이 있습니다. 모든 필드를 확인해주세요.");
        setIsSubmitting(false);
        return;
      }

      // 1. 삭제 처리 - 삭제된 아이템 ID가 있으면 삭제 요청 
      const deletePromises = deletedItemIds.map(id =>
        deleteRfqItem({
          id: id,
          rfqId: rfqId,
          rfqType: rfqType ?? RfqType.PURCHASE
        })
      );

      // 2. 생성/수정 처리 - 폼에 남아있는 아이템들
      const upsertPromises = data.items.map((item) =>
        createRfqItem({
          rfqId: rfqId,
          itemCode: item.itemCode,
          description: item.description,
          // 명시적으로 숫자로 변환
          quantity: Number(item.quantity),
          uom: item.uom,
          rfqType: rfqType ?? RfqType.PURCHASE,
          id: item.id // 기존 ID가 있으면 업데이트, 없으면 생성
        })
      );

      // 모든 요청 병렬 처리
      await Promise.all([...deletePromises, ...upsertPromises]);

      toast.success("RFQ 아이템이 성공적으로 저장되었습니다!");
      setHasUnsavedChanges(false);
      onOpenChange(false);
    } catch (err) {
      toast.error(`오류가 발생했습니다: ${String(err)}`);
    } finally {
      setIsSubmitting(false);
    }
  }

  // 단축키 처리 - 편집 가능한 경우에만 단축키 활성화
  React.useEffect(() => {
    if (!isEditable) return;

    const handleKeyDown = (e: KeyboardEvent) => {
      // Alt+N: 새 항목 추가
      if (e.altKey && e.key === 'n') {
        e.preventDefault();
        handleAddItem();
      }
      // Ctrl+S: 저장
      if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault();
        form.handleSubmit(onSubmit)();
      }
      // Esc: 포커스된 팝오버 닫기
      if (e.key === 'Escape') {
        document.querySelectorAll('[role="combobox"][aria-expanded="true"]').forEach(
          (el) => (el as HTMLButtonElement).click()
        );
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [form, isEditable]);

  return (
    <>
      <Dialog open={open} onOpenChange={handleDialogClose}>
        <DialogContent className="max-w-none w-[1200px]">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              {isEditable ? "RFQ 아이템 관리" : "RFQ 아이템 조회"}
              <Badge variant="outline" className="ml-2">
                {rfq?.rfqCode || `RFQ #${rfqId}`}
              </Badge>
              {rfqType && (
                <Badge variant={rfqType === RfqType.PURCHASE ? "default" : "secondary"} className="ml-1">
                  {rfqType === RfqType.PURCHASE ? "구매 RFQ" : "예산 RFQ"}
                </Badge>
              )}
              {rfq?.status && (
                <Badge
                  variant={rfq.status === "DRAFT" ? "outline" : "secondary"}
                  className="ml-1"
                >
                  {rfq.status}
                </Badge>
              )}
            </DialogTitle>
            <DialogDescription>
              {isEditable
                ? (rfq?.description || '아이템을 각 행에 하나씩 추가할 수 있습니다.')
                : '드래프트 상태가 아닌 RFQ는 아이템을 편집할 수 없습니다.'}
            </DialogDescription>
          </DialogHeader>
          <div className="overflow-x-auto w-full">
            <Form {...form}>
              <form onSubmit={form.handleSubmit(onSubmit)}>
                <div className="space-y-4">
                  {/* 헤더 행 (라벨) */}
                  <div className="flex items-center gap-2 border-b pb-2 font-medium text-sm">
                    <div className="w-[250px] pl-3">아이템</div>
                    <div className="w-[400px] pl-2">설명</div>
                    <div className="w-[80px] pl-2 text-center">수량</div>
                    <div className="w-[80px] pl-2 text-center">단위</div>
                    {isEditable && <div className="w-[42px]"></div>}
                  </div>

                  {/* 아이템 행들 */}
                  <div className="max-h-[50vh] overflow-y-auto pr-1 space-y-3">
                    {fields.map((field, index) => {
                      // 현재 row의 itemCode
                      const codeValue = watchItems[index]?.itemCode || "";
                      // "이미" 사용된 코드를 모두 구함
                      const usedCodes = watchItems
                        .map((it, i) => i === index ? null : it.itemCode)
                        .filter(Boolean) as string[];

                      // itemsList에서 "현재 선택한 code"만 예외적으로 허용하고,
                      // 다른 행에서 이미 사용한 code는 제거
                      const filteredItems = (itemsList || [])
                        .filter((it) => {
                          if (!it.code) return false;
                          if (it.code === codeValue) return true;
                          return !usedCodes.includes(it.code);
                        })
                        .map((it) => ({
                          code: it.code ?? "",   // fallback
                          name: it.name,
                        }));

                      // 선택된 아이템 찾기
                      const selected = filteredItems.find(it => it.code === codeValue);

                      return (
                        <div key={field.id} className="flex items-center gap-2 group hover:bg-gray-50 p-1 rounded-md transition-colors">
                          {/* -- itemCode + Popover(Select) -- */}
                          {isEditable ? (
                            // 전체 FormField 컴포넌트와 아이템 선택 로직 개선
                            <FormField
                              control={form.control}
                              name={`items.${index}.itemCode`}
                              render={({ field }) => {
                                const [popoverOpen, setPopoverOpen] = React.useState(false);
                                const selected = filteredItems.find(it => it.code === field.value);

                                return (
                                  <FormItem className="flex items-center gap-2 w-[250px]" style={{width:250}}>
                                    <FormControl>
                                      <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
                                        <PopoverTrigger asChild>
                                          <Button
                                            // 컴포넌트에 ref 전달
                                            ref={el => {
                                              inputRefs.current[index] = el;
                                            }}
                                            variant="outline"
                                            role="combobox"
                                            aria-expanded={popoverOpen}
                                            className="flex items-center"
                                            data-error={!!form.formState.errors.items?.[index]?.itemCode}
                                            data-state={selected ? "filled" : "empty"}
                                            style={{width:250}}
                                          >
                                            <div className="flex-1 overflow-hidden mr-2 text-left">
                                              <span className="block truncate" style={{width:200}}>
                                                {selected ? `${selected.code} - ${selected.name}` : "아이템 선택..."}
                                              </span>
                                            </div>
                                            <ChevronsUpDown className="h-4 w-4 flex-shrink-0 opacity-50" />
                                          </Button>
                                        </PopoverTrigger>
                                        <PopoverContent className="w-[400px] p-0">
                                          <Command>
                                            <CommandInput placeholder="아이템 검색..." className="h-9" autoFocus />
                                            <CommandList>
                                              <CommandEmpty>아이템을 찾을 수 없습니다.</CommandEmpty>
                                              <CommandGroup>
                                                {filteredItems.map((it) => {
                                                  const label = `${it.code} - ${it.name}`;
                                                  return (
                                                    <CommandItem
                                                      key={it.code}
                                                      value={label}
                                                      onSelect={() => {
                                                        field.onChange(it.code);
                                                        setPopoverOpen(false);
                                                        // 자동으로 다음 필드로 포커스 이동
                                                        focusField(`input[name="items.${index}.description"]`);
                                                      }}
                                                    >
                                                      <div className="flex-1 overflow-hidden">
                                                        <span className="block truncate">{label}</span>
                                                      </div>
                                                      <Check
                                                        className={
                                                          "ml-auto h-4 w-4" +
                                                          (it.code === field.value ? " opacity-100" : " opacity-0")
                                                        }
                                                      />
                                                    </CommandItem>
                                                  );
                                                })}
                                              </CommandGroup>
                                            </CommandList>
                                          </Command>
                                        </PopoverContent>
                                      </Popover>
                                    </FormControl>
                                    {form.formState.errors.items?.[index]?.itemCode && (
                                      <AlertCircle className="h-4 w-4 text-destructive" />
                                    )}
                                  </FormItem>
                                );
                              }}
                            />
                          ) : (
                            <div className="flex items-center w-[250px] pl-3">
                              {selected ? `${selected.code} - ${selected.name}` : codeValue}
                            </div>
                          )}

                          {/* ID 필드 추가 (숨김) */}
                          <FormField
                            control={form.control}
                            name={`items.${index}.id`}
                            render={({ field }) => (
                              <input type="hidden" {...field} />
                            )}
                          />

                          {/* description */}
                          {isEditable ? (
                            <FormField
                              control={form.control}
                              name={`items.${index}.description`}
                              render={({ field }) => (
                                <FormItem className="w-[400px]">
                                  <FormControl>
                                    <Input
                                      className="w-full"
                                      placeholder="아이템 상세 정보"
                                      {...field}
                                      onKeyDown={(e) => {
                                        if (e.key === 'Enter') {
                                          e.preventDefault();
                                          focusField(`input[name="items.${index}.quantity"]`);
                                        }
                                      }}
                                    />
                                  </FormControl>
                                  <FormMessage />
                                </FormItem>
                              )}
                            />
                          ) : (
                            <div className="w-[400px] pl-2">
                              {watchItems[index]?.description || ""}
                            </div>
                          )}

                          {/* quantity */}
                          {isEditable ? (
                            <FormField
                              control={form.control}
                              name={`items.${index}.quantity`}
                              render={({ field }) => (
                                <FormItem className="w-[80px] relative">
                                  <FormControl>
                                    <Input
                                      type="number"
                                      className="w-full text-center"
                                      min="1"
                                      {...field}
                                      // 값 변경 핸들러 개선
                                      onChange={(e) => {
                                        const value = e.target.value === '' ? 1 : parseInt(e.target.value, 10);
                                        field.onChange(isNaN(value) ? 1 : value);
                                      }}
                                      // 최소값 보장 (빈 문자열 방지)
                                      onBlur={(e) => {
                                        if (e.target.value === '' || parseInt(e.target.value, 10) < 1) {
                                          field.onChange(1);
                                        }
                                      }}
                                      onKeyDown={(e) => {
                                        if (e.key === 'Enter') {
                                          e.preventDefault();
                                          focusField(`input[name="items.${index}.uom"]`);
                                        }
                                      }}
                                    />
                                  </FormControl>
                                  {form.formState.errors.items?.[index]?.quantity && (
                                    <AlertCircle className="h-4 w-4 text-destructive absolute right-2 top-2" />
                                  )}
                                </FormItem>
                              )}
                            />
                          ) : (
                            <div className="w-[80px] text-center">
                              {watchItems[index]?.quantity}
                            </div>
                          )}

                          {/* uom */}
                          {isEditable ? (
                            <FormField
                              control={form.control}
                              name={`items.${index}.uom`}
                              render={({ field }) => (
                                <FormItem className="w-[80px]">
                                  <FormControl>
                                    <Input
                                      placeholder="each"
                                      className="w-full text-center"
                                      {...field}
                                      onKeyDown={(e) => {
                                        if (e.key === 'Enter') {
                                          e.preventDefault();
                                          // 마지막 행이면 새로운 행 추가
                                          if (index === fields.length - 1) {
                                            handleAddItem();
                                          } else {
                                            // 아니면 다음 행의 아이템 선택으로 이동
                                            const button = inputRefs.current[index + 1];
                                            if (button) {
                                              setTimeout(() => button.click(), 10);
                                            }
                                          }
                                        }
                                      }}
                                    />
                                  </FormControl>
                                  <FormMessage />
                                </FormItem>
                              )}
                            />
                          ) : (
                            <div className="w-[80px] text-center">
                              {watchItems[index]?.uom || "each"}
                            </div>
                          )}

                          {/* remove row - 편집 모드에서만 표시 */}
                          {isEditable && (
                            <TooltipProvider>
                              <Tooltip>
                                <TooltipTrigger asChild>
                                  <Button
                                    type="button"
                                    variant="ghost"
                                    size="icon"
                                    onClick={() => handleRemoveItem(index)}
                                    className="group-hover:opacity-100 transition-opacity"
                                    aria-label="아이템 삭제"
                                  >
                                    <Trash2 className="h-4 w-4 text-destructive" />
                                  </Button>
                                </TooltipTrigger>
                                <TooltipContent>
                                  <p>아이템 삭제</p>
                                </TooltipContent>
                              </Tooltip>
                            </TooltipProvider>
                          )}
                        </div>
                      );
                    })}
                  </div>

                  <div className="flex justify-between items-center pt-2 border-t">
                    <div className="flex items-center gap-2">
                      {isEditable ? (
                        <>
                          <TooltipProvider>
                            <Tooltip>
                              <TooltipTrigger asChild>
                                <Button type="button" variant="outline" onClick={handleAddItem} className="gap-1">
                                  <Plus className="h-4 w-4" />
                                  아이템 추가
                                </Button>
                              </TooltipTrigger>
                              <TooltipContent side="bottom">
                                <p>단축키: Alt+N</p>
                              </TooltipContent>
                            </Tooltip>
                          </TooltipProvider>
                          <span className="text-sm text-muted-foreground">
                            {fields.length}개 아이템
                          </span>
                          {deletedItemIds.length > 0 && (
                            <span className="text-sm text-destructive">
                              ({deletedItemIds.length}개 아이템 삭제 예정)
                            </span>
                          )}
                        </>
                      ) : (
                        <span className="text-sm text-muted-foreground">
                          {fields.length}개 아이템
                        </span>
                      )}
                    </div>

                    {isEditable && (
                      <div className="text-xs text-muted-foreground">
                        <span className="inline-flex items-center gap-1 mr-2">
                          <kbd className="px-1 py-0.5 bg-gray-100 rounded text-xs">Tab</kbd>
                          <span>필드 간 이동</span>
                        </span>
                        <span className="inline-flex items-center gap-1">
                          <kbd className="px-1 py-0.5 bg-gray-100 rounded text-xs">Enter</kbd>
                          <span>다음 필드로 이동</span>
                        </span>
                      </div>
                    )}
                  </div>
                </div>

                <DialogFooter className="mt-6 gap-2">
                  {isEditable ? (
                    <>
                      <TooltipProvider>
                        <Tooltip>
                          <TooltipTrigger asChild>
                            <Button type="button" variant="outline" onClick={() => handleDialogClose(false)}>
                              <X className="mr-2 h-4 w-4" />
                              취소
                            </Button>
                          </TooltipTrigger>
                          <TooltipContent>변경사항을 저장하지 않고 나가기</TooltipContent>
                        </Tooltip>
                      </TooltipProvider>

                      <TooltipProvider>
                        <Tooltip>
                          <TooltipTrigger asChild>
                            <Button
                              type="submit"
                              disabled={isSubmitting || (!form.formState.isDirty && deletedItemIds.length === 0) || !form.formState.isValid}
                            >
                              {isSubmitting ? (
                                <>처리 중...</>
                              ) : (
                                <>
                                  <Save className="mr-2 h-4 w-4" />
                                  저장
                                </>
                              )}
                            </Button>
                          </TooltipTrigger>
                          <TooltipContent>
                            <p>단축키: Ctrl+S</p>
                          </TooltipContent>
                        </Tooltip>
                      </TooltipProvider>
                    </>
                  ) : (
                    <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
                      <X className="mr-2 h-4 w-4" />
                      닫기
                    </Button>
                  )}
                </DialogFooter>
              </form>
            </Form>
          </div>
        </DialogContent>
      </Dialog>

      {/* 저장하지 않고 나가기 확인 다이얼로그 - 편집 모드에서만 활성화 */}
      {isEditable && (
        <AlertDialog open={isExitDialogOpen} onOpenChange={setIsExitDialogOpen}>
          <AlertDialogContent>
            <AlertDialogHeader>
              <AlertDialogTitle>저장되지 않은 변경사항</AlertDialogTitle>
              <AlertDialogDescription>
                저장되지 않은 변경사항이 있습니다. 그래도 나가시겠습니까?
              </AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
              <AlertDialogCancel>취소</AlertDialogCancel>
              <AlertDialogAction onClick={() => {
                setIsExitDialogOpen(false);
                onOpenChange(false);
              }}>
                저장하지 않고 나가기
              </AlertDialogAction>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialog>
      )}
    </>
  );
}