"use client"

import * as React from "react"
import { useState, useEffect, useRef } from "react"
import { toast } from "sonner"
import { format } from "date-fns"

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Checkbox } from "@/components/ui/checkbox"
import { DatePicker } from "@/components/ui/date-picker"
import {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableHead,
  TableHeader,
  TableRow
} from "@/components/ui/table"
import { Badge } from "@/components/ui/badge"
import { ScrollArea } from "@/components/ui/scroll-area"
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger
} from "@/components/ui/tooltip"
import {
  Info,
  Clock,
  CalendarIcon,
  ClipboardCheck,
  AlertTriangle,
  CheckCircle2,
  RefreshCw,
  Save,
  FileText,
  Sparkles
} from "lucide-react"

import { formatCurrency } from "@/lib/utils"
import { updateQuotationItem } from "../services"
import { Textarea } from "@/components/ui/textarea"

// 견적 아이템 타입
interface QuotationItem {
  id: number
  quotationId: number
  prItemId: number
  materialCode: string | null
  materialDescription: string | null
  quantity: number
  uom: string | null
  unitPrice: number
  totalPrice: number
  currency: string
  vendorMaterialCode: string | null
  vendorMaterialDescription: string | null
  deliveryDate: Date | null
  leadTimeInDays: number | null
  taxRate: number | null
  taxAmount: number | null
  discountRate: number | null
  discountAmount: number | null
  remark: string | null
  isAlternative: boolean
  isRecommended: boolean // 남겨두지만 UI에서는 사용하지 않음
  createdAt: Date
  updatedAt: Date
  prItem?: {
    id: number
    materialCode: string | null
    materialDescription: string | null
    // 기타 필요한 정보
  }
}

// debounce 함수 구현
function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void {
  let timeout: NodeJS.Timeout | null = null;

  return function (...args: Parameters<T>) {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}

interface QuotationItemEditorProps {
  items: QuotationItem[]
  onItemsChange: (items: QuotationItem[]) => void
  disabled?: boolean
  currency: string
}

export function QuotationItemEditor({
  items,
  onItemsChange,
  disabled = false,
  currency
}: QuotationItemEditorProps) {
  const [editingItem, setEditingItem] = useState<number | null>(null)
  const [isSaving, setIsSaving] = useState(false)

  // 저장이 필요한 항목들을 추적
  const [pendingChanges, setPendingChanges] = useState<Set<number>>(new Set())

  // 로컬 상태 업데이트 함수 - 화면에 즉시 반영하지만 서버에는 즉시 저장하지 않음
  const updateLocalItem = <K extends keyof QuotationItem>(
    index: number, 
    field: K, 
    value: QuotationItem[K]
  ) => {
    // 로컬 상태 업데이트
    const updatedItems = [...items]
    const item = { ...updatedItems[index] }

    // 필드 업데이트
    item[field] = value

    // 대체품 체크 해제 시 관련 필드 초기화
    if (field === 'isAlternative' && value === false) {
      item.vendorMaterialCode = null;
      item.vendorMaterialDescription = null;
      item.remark = null;
    }

    // 단가나 수량이 변경되면 총액 계산
    if (field === 'unitPrice' || field === 'quantity') {
      item.totalPrice = Number(item.unitPrice) * Number(item.quantity)

      // 세금이 있으면 세액 계산
      if (item.taxRate) {
        item.taxAmount = item.totalPrice * (item.taxRate / 100)
      }

      // 할인이 있으면 할인액 계산
      if (item.discountRate) {
        item.discountAmount = item.totalPrice * (item.discountRate / 100)
      }
    }

    // 세율이 변경되면 세액 계산
    if (field === 'taxRate') {
      item.taxAmount = item.totalPrice * (value as number / 100)
    }

    // 할인율이 변경되면 할인액 계산
    if (field === 'discountRate') {
      item.discountAmount = item.totalPrice * (value as number / 100)
    }

    // 변경된 아이템으로 교체
    updatedItems[index] = item

    // 미저장 항목으로 표시
    setPendingChanges(prev => new Set(prev).add(item.id))

    // 부모 컴포넌트에 변경 사항 알림
    onItemsChange(updatedItems)

    // 저장 필요함을 표시
    return item
  }

  // 서버에 저장하는 함수
  const saveItemToServer = async (item: QuotationItem, field: keyof QuotationItem, value: any) => {
    if (disabled) return

    try {
      setIsSaving(true)

      const result = await updateQuotationItem({
        id: item.id,
        [field]: value,
        totalPrice: item.totalPrice,
        taxAmount: item.taxAmount ?? 0,
        discountAmount: item.discountAmount ?? 0
      })

      // 저장 완료 후 pendingChanges에서 제거
      setPendingChanges(prev => {
        const newSet = new Set(prev)
        newSet.delete(item.id)
        return newSet
      })

      if (!result.success) {
        toast.error(result.message || "항목 저장 중 오류가 발생했습니다")
      }
    } catch (error) {
      console.error("항목 저장 오류:", error)
      toast.error("항목 저장 중 오류가 발생했습니다")
    } finally {
      setIsSaving(false)
    }
  }

  // debounce된 저장 함수
  const debouncedSave = useRef(debounce(
    (item: QuotationItem, field: keyof QuotationItem, value: any) => {
      saveItemToServer(item, field, value)
    },
    800 // 800ms 지연
  )).current

  // 견적 항목 업데이트 함수
  const handleItemUpdate = (index: number, field: keyof QuotationItem, value: any) => {
    const updatedItem = updateLocalItem(index, field, value)

    // debounce를 통해 서버 저장 지연
    if (!disabled) {
      debouncedSave(updatedItem, field, value)
    }
  }

  // 모든 변경 사항 저장
  const saveAllChanges = async () => {
    if (disabled || pendingChanges.size === 0) return

    setIsSaving(true)
    toast.info(`${pendingChanges.size}개 항목 저장 중...`)

    try {
      // 변경된 모든 항목 저장
      for (const itemId of pendingChanges) {
        const index = items.findIndex(item => item.id === itemId)
        if (index !== -1) {
          const item = items[index]
          await updateQuotationItem({
            id: item.id,
            unitPrice: item.unitPrice,
            totalPrice: item.totalPrice,
            taxRate: item.taxRate ?? 0,
            taxAmount: item.taxAmount ?? 0,
            discountRate: item.discountRate ?? 0,
            discountAmount: item.discountAmount ?? 0,
            deliveryDate: item.deliveryDate,
            leadTimeInDays: item.leadTimeInDays ?? 0,
            vendorMaterialCode: item.vendorMaterialCode ?? "",
            vendorMaterialDescription: item.vendorMaterialDescription ?? "",
            isAlternative: item.isAlternative,
            isRecommended: false, // 항상 false로 설정 (사용하지 않음)
            remark: item.remark ?? ""
          })
        }
      }

      // 모든 변경 사항 저장 완료
      setPendingChanges(new Set())
      toast.success("모든 변경 사항이 저장되었습니다")
    } catch (error) {
      console.error("변경 사항 저장 오류:", error)
      toast.error("변경 사항 저장 중 오류가 발생했습니다")
    } finally {
      setIsSaving(false)
    }
  }

  // blur 이벤트로 저장 트리거 (사용자가 입력 완료 후)
  const handleBlur = (index: number, field: keyof QuotationItem, value: any) => {
    const itemId = items[index].id

    // 해당 항목이 pendingChanges에 있다면 즉시 저장
    if (pendingChanges.has(itemId)) {
      const item = items[index]
      saveItemToServer(item, field, value)
    }
  }

  // 전체 단가 업데이트 (일괄 반영)
  const handleBulkUnitPriceUpdate = () => {
    if (items.length === 0) return

    // 첫 번째 아이템의 단가 가져오기
    const firstUnitPrice = items[0].unitPrice

    if (!firstUnitPrice) {
      toast.error("첫 번째 항목의 단가를 먼저 입력해주세요")
      return
    }

    // 모든 아이템에 동일한 단가 적용
    const updatedItems = items.map(item => ({
      ...item,
      unitPrice: firstUnitPrice,
      totalPrice: firstUnitPrice * item.quantity,
      taxAmount: item.taxRate ? (firstUnitPrice * item.quantity) * (item.taxRate / 100) : item.taxAmount,
      discountAmount: item.discountRate ? (firstUnitPrice * item.quantity) * (item.discountRate / 100) : item.discountAmount
    }))

    // 모든 아이템을 변경 필요 항목으로 표시
    setPendingChanges(new Set(updatedItems.map(item => item.id)))

    // 부모 컴포넌트에 변경 사항 알림
    onItemsChange(updatedItems)

    toast.info("모든 항목의 단가가 업데이트되었습니다. 변경 사항을 저장하려면 '저장' 버튼을 클릭하세요.")
  }

  // 입력 핸들러
  const handleNumberInputChange = (
    index: number,
    field: keyof QuotationItem,
    e: React.ChangeEvent<HTMLInputElement>
  ) => {
    const value = e.target.value === '' ? 0 : parseFloat(e.target.value)
    handleItemUpdate(index, field, value)
  }

  const handleTextInputChange = (
    index: number,
    field: keyof QuotationItem,
    e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    handleItemUpdate(index, field, e.target.value)
  }

  const handleDateChange = (
    index: number,
    field: keyof QuotationItem,
    date: Date | undefined
  ) => {
    handleItemUpdate(index, field, date || null)
  }

  const handleCheckboxChange = (
    index: number,
    field: keyof QuotationItem,
    checked: boolean
  ) => {
    handleItemUpdate(index, field, checked)
  }

  // 날짜 형식 지정
  const formatDeliveryDate = (date: Date | null) => {
    if (!date) return "-"
    return format(date, "yyyy-MM-dd")
  }

  // 입력 폼 필드 렌더링
  const renderInputField = (item: QuotationItem, index: number, field: keyof QuotationItem) => {
    if (field === 'unitPrice' || field === 'taxRate' || field === 'discountRate' || field === 'leadTimeInDays') {
      return (
        <Input
          type="number"
          min={0}
          step={field === 'unitPrice' ? 0.01 : field === 'taxRate' || field === 'discountRate' ? 0.1 : 1}
          value={item[field] as number || 0}
          onChange={(e) => handleNumberInputChange(index, field, e)}
          onBlur={(e) => handleBlur(index, field, parseFloat(e.target.value) || 0)}
          disabled={disabled || isSaving}
          className="w-full"
        />
      )
    } else if (field === 'vendorMaterialCode' || field === 'vendorMaterialDescription') {
      return (
        <Input
          type="text"
          value={item[field] as string || ''}
          onChange={(e) => handleTextInputChange(index, field, e)}
          onBlur={(e) => handleBlur(index, field, e.target.value)}
          disabled={disabled || isSaving || !item.isAlternative}
          className="w-full"
          placeholder={field === 'vendorMaterialCode' ? "벤더 자재그룹" : "벤더 자재명"}
        />
      )
    } else if (field === 'deliveryDate') {
      return (
        <DatePicker
          date={item.deliveryDate ? new Date(item.deliveryDate) : undefined}
          onSelect={(date) => {
            handleDateChange(index, field, date);
            // DatePicker는 blur 이벤트가 없으므로 즉시 저장 트리거
            if (date) handleBlur(index, field, date);
          }}
          disabled={disabled || isSaving}
        />
      )
    } else if (field === 'isAlternative') {
      return (
        <div className="flex items-center gap-1">
          <Checkbox
            checked={item.isAlternative}
            onCheckedChange={(checked) => {
              handleCheckboxChange(index, field, checked as boolean);
              handleBlur(index, field, checked as boolean);
            }}
            disabled={disabled || isSaving}
          />
          <span className="text-xs">대체품</span>
        </div>
      )
    }

    return null
  }

  // 대체품 필드 렌더링
  const renderAlternativeFields = (item: QuotationItem, index: number) => {
    if (!item.isAlternative) return null;

    return (
      <div className="mt-2 p-3 bg-blue-50 rounded-md space-y-2 text-sm">
        {/* <div className="flex flex-col gap-2">
          <label className="text-xs font-medium text-blue-700">벤더 자재그룹</label>
          <Input
            value={item.vendorMaterialCode || ""}
            onChange={(e) => handleTextInputChange(index, 'vendorMaterialCode', e)}
            onBlur={(e) => handleBlur(index, 'vendorMaterialCode', e.target.value)}
            disabled={disabled || isSaving}
            className="h-8 text-sm"
            placeholder="벤더 자재그룹 입력"
          />
        </div> */}
        
        <div className="flex flex-col gap-2">
          <label className="text-xs font-medium text-blue-700">벤더 자재명</label>
          <Input
            value={item.vendorMaterialDescription || ""}
            onChange={(e) => handleTextInputChange(index, 'vendorMaterialDescription', e)}
            onBlur={(e) => handleBlur(index, 'vendorMaterialDescription', e.target.value)}
            disabled={disabled || isSaving}
            className="h-8 text-sm"
            placeholder="벤더 자재명 입력"
          />
        </div>
        
        <div className="flex flex-col gap-2">
          <label className="text-xs font-medium text-blue-700">대체품 설명</label>
          <Textarea
            value={item.remark || ""}
            onChange={(e) => handleTextInputChange(index, 'remark', e)}
            onBlur={(e) => handleBlur(index, 'remark', e.target.value)}
            disabled={disabled || isSaving}
            className="min-h-[60px] text-sm"
            placeholder="원본과의 차이점, 대체 사유, 장점 등을 설명해주세요"
          />
        </div>
      </div>
    );
  };

  // 항목의 저장 상태 아이콘 표시
  const renderSaveStatus = (itemId: number) => {
    if (pendingChanges.has(itemId)) {
      return (
        <TooltipProvider>
          <Tooltip>
            <TooltipTrigger>
              <RefreshCw className="h-4 w-4 text-yellow-500 animate-spin" />
            </TooltipTrigger>
            <TooltipContent>
              <p>저장되지 않은 변경 사항이 있습니다</p>
            </TooltipContent>
          </Tooltip>
        </TooltipProvider>
      )
    }

    return null
  }

  return (
    <div className="space-y-4">
      <div className="flex justify-between items-center">
        <div className="flex items-center gap-2">
          <h3 className="text-lg font-medium">항목 목록 ({items.length}개)</h3>
          {pendingChanges.size > 0 && (
            <Badge variant="outline" className="bg-yellow-50">
              변경 {pendingChanges.size}개
            </Badge>
          )}
        </div>

        <div className="flex items-center gap-2">
          {pendingChanges.size > 0 && !disabled && (
            <Button
              variant="default"
              size="sm"
              onClick={saveAllChanges}
              disabled={isSaving}
            >
              {isSaving ? (
                <RefreshCw className="h-4 w-4 mr-2 animate-spin" />
              ) : (
                <Save className="h-4 w-4 mr-2" />
              )}
              변경사항 저장 ({pendingChanges.size}개)
            </Button>
          )}

          {!disabled && (
            <Button
              variant="outline"
              size="sm"
              onClick={handleBulkUnitPriceUpdate}
              disabled={items.length === 0 || isSaving}
            >
              첫 항목 단가로 일괄 적용
            </Button>
          )}
        </div>
      </div>

      <ScrollArea className="h-[500px] rounded-md border">
        <Table>
          <TableHeader className="sticky top-0 bg-background">
            <TableRow>
              <TableHead className="w-[50px]">번호</TableHead>
              <TableHead>자재그룹</TableHead>
              <TableHead>자재명</TableHead>
              <TableHead>수량</TableHead>
              <TableHead>단위</TableHead>
              <TableHead>단가</TableHead>
              <TableHead>금액</TableHead>
              <TableHead>
                <div className="flex items-center gap-1">
                  세율(%)
                  <TooltipProvider>
                    <Tooltip>
                      <TooltipTrigger>
                        <Info className="h-4 w-4" />
                      </TooltipTrigger>
                      <TooltipContent>
                        <p>세율을 입력하면 자동으로 세액이 계산됩니다.</p>
                      </TooltipContent>
                    </Tooltip>
                  </TooltipProvider>
                </div>
              </TableHead>
              <TableHead>
                <div className="flex items-center gap-1">
                  납품일
                  <TooltipProvider>
                    <Tooltip>
                      <TooltipTrigger>
                        <Info className="h-4 w-4" />
                      </TooltipTrigger>
                      <TooltipContent>
                        <p>납품 가능한 날짜를 선택해주세요.</p>
                      </TooltipContent>
                    </Tooltip>
                  </TooltipProvider>
                </div>
              </TableHead>
              <TableHead>리드타임(일)</TableHead>
              <TableHead>
                <div className="flex items-center gap-1">
                  대체품
                  <TooltipProvider>
                    <Tooltip>
                      <TooltipTrigger>
                        <Info className="h-4 w-4" />
                      </TooltipTrigger>
                      <TooltipContent>
                        <p>요청된 제품의 대체품을 제안할 경우 선택하세요.</p>
                        <p>대체품을 선택하면 추가 정보를 입력할 수 있습니다.</p>
                      </TooltipContent>
                    </Tooltip>
                  </TooltipProvider>
                </div>
              </TableHead>
              <TableHead className="w-[50px]">상태</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {items.length === 0 ? (
              <TableRow>
                <TableCell colSpan={12} className="text-center py-10">
                  견적 항목이 없습니다
                </TableCell>
              </TableRow>
            ) : (
              items.map((item, index) => (
                <React.Fragment key={item.id}>
                  <TableRow className={pendingChanges.has(item.id) ? "bg-yellow-50/30" : ""}>
                    <TableCell>
                      {index + 1}
                    </TableCell>
                    <TableCell>
                      {item.materialCode || "-"}
                    </TableCell>
                    <TableCell>
                      <div className="font-medium max-w-xs truncate">
                        {item.materialDescription || "-"}
                      </div>
                    </TableCell>
                    <TableCell>
                      {item.quantity}
                    </TableCell>
                    <TableCell>
                      {item.uom || "-"}
                    </TableCell>
                    <TableCell>
                      {renderInputField(item, index, 'unitPrice')}
                    </TableCell>
                    <TableCell>
                      {formatCurrency(item.totalPrice, currency)}
                    </TableCell>
                    <TableCell>
                      {renderInputField(item, index, 'taxRate')}
                    </TableCell>
                    <TableCell>
                      {renderInputField(item, index, 'deliveryDate')}
                    </TableCell>
                    <TableCell>
                      {renderInputField(item, index, 'leadTimeInDays')}
                    </TableCell>
                    <TableCell>
                      {renderInputField(item, index, 'isAlternative')}
                    </TableCell>
                    <TableCell>
                      {renderSaveStatus(item.id)}
                    </TableCell>
                  </TableRow>
                  
                  {/* 대체품으로 선택된 경우 추가 정보 행 표시 */}
                  {item.isAlternative && (
                    <TableRow className={pendingChanges.has(item.id) ? "bg-blue-50/40" : "bg-blue-50/20"}>
                      <TableCell colSpan={1}></TableCell>
                      <TableCell colSpan={10}>
                        {renderAlternativeFields(item, index)}
                      </TableCell>
                      <TableCell colSpan={1}></TableCell>
                    </TableRow>
                  )}
                </React.Fragment>
              ))
            )}
          </TableBody>
        </Table>
      </ScrollArea>

      {isSaving && (
        <div className="flex items-center justify-center text-sm text-muted-foreground">
          <Clock className="h-4 w-4 animate-spin mr-2" />
          변경 사항을 저장 중입니다...
        </div>
      )}

      <div className="bg-muted p-4 rounded-md">
        <h4 className="text-sm font-medium mb-2">안내 사항</h4>
        <ul className="text-sm space-y-1 text-muted-foreground">
          <li className="flex items-start gap-2">
            <AlertTriangle className="h-4 w-4 mt-0.5 flex-shrink-0" />
            <span>단가와 납품일은 필수로 입력해야 합니다.</span>
          </li>
          <li className="flex items-start gap-2">
            <ClipboardCheck className="h-4 w-4 mt-0.5 flex-shrink-0" />
            <span>입력 후 다른 필드로 이동하면 자동으로 저장됩니다. 여러 항목을 변경한 후 '저장' 버튼을 사용할 수도 있습니다.</span>
          </li>
          <li className="flex items-start gap-2">
            <FileText className="h-4 w-4 mt-0.5 flex-shrink-0" />
            <span><strong>대체품</strong>으로 제안하는 경우 자재명, 대체품 설명을 입력해주세요.</span>
          </li>
        </ul>
      </div>
    </div>
  )
}   