'use client';

/**
 * 자재투입 모달 (로트 선택 기반)
 *
 * 로트를 체크박스로 선택하면 필요수량만큼 FIFO 순서로 자동 배분합니다.
 * 같은 품목의 여러 로트를 조합하여 필요수량을 충족시킬 수 있습니다.
 */

import { useState, useEffect, useCallback, useMemo } from 'react';
import { Loader2, Check } from 'lucide-react';
import { ContentSkeleton } from '@/components/ui/skeleton';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import { toast } from 'sonner';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { getMaterialsForWorkOrder, registerMaterialInput, getMaterialsForItem, registerMaterialInputForItem, type MaterialForInput, type MaterialForItemInput } from './actions';
import type { WorkOrder } from '../ProductionDashboard/types';
import type { MaterialInput } from './types';
import { formatNumber } from '@/lib/utils/amount';

interface MaterialInputModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  order: WorkOrder | null;
  workOrderItemId?: number;       // 개소(작업지시품목) ID (첫 번째 item, 호환용)
  workOrderItemIds?: number[];    // 개소 내 모든 작업지시품목 IDs (절곡 등 복수 item)
  workOrderItemName?: string;     // 개소명 (모달 헤더 표시용)
  onComplete?: () => void;
  isCompletionFlow?: boolean;
  onSaveMaterials?: (orderId: string, materials: MaterialInput[]) => void;
  savedMaterials?: MaterialInput[];
}

interface MaterialGroup {
  itemId: number;
  groupKey: string;              // 그룹 식별 키 (itemId 또는 itemId_woItemId)
  materialName: string;
  materialCode: string;
  requiredQty: number;
  effectiveRequiredQty: number;  // 남은 필요수량 (이미 투입분 차감)
  alreadyInputted: number;       // 이미 투입된 수량
  unit: string;
  lots: MaterialForInput[];
  // dynamic_bom 추가 정보
  workOrderItemId?: number;
  lotPrefix?: string;
  partType?: string;
  category?: string;
}

const fmtQty = (v: number) => formatNumber(parseFloat(String(v)));

export function MaterialInputModal({
  open,
  onOpenChange,
  order,
  workOrderItemId,
  workOrderItemIds,
  workOrderItemName,
  onComplete,
  isCompletionFlow = false,
  onSaveMaterials,
}: MaterialInputModalProps) {
  const [materials, setMaterials] = useState<MaterialForInput[]>([]);
  const [selectedLotKeys, setSelectedLotKeys] = useState<Set<string>>(new Set());
  const [isLoading, setIsLoading] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);

  // 목업 자재 데이터 (개발용)
  const MOCK_MATERIALS: MaterialForInput[] = Array.from({ length: 5 }, (_, i) => ({
    stockLotId: 100 + i,
    itemId: 200 + i,
    lotNo: `LOT-2026-${String(i + 1).padStart(3, '0')}`,
    materialCode: `MAT-${String(i + 1).padStart(3, '0')}`,
    materialName: `자재 ${i + 1}`,
    specification: '',
    unit: 'EA',
    requiredQty: 100,
    lotAvailableQty: 500 - i * 50,
    fifoRank: i + 1,
  }));

  // 로트 키 생성
  const getLotKey = (material: MaterialForInput) =>
    String(material.stockLotId ?? `item-${material.itemId}`);

  // 품목별 그룹핑
  const materialGroups: MaterialGroup[] = useMemo(() => {
    // dynamic_bom 항목은 (itemId, workOrderItemId) 쌍으로 그룹핑
    const groups = new Map<string, MaterialForInput[]>();
    for (const m of materials) {
      const groupKey = m.workOrderItemId ? `${m.itemId}_${m.workOrderItemId}` : String(m.itemId);
      const existing = groups.get(groupKey) || [];
      existing.push(m);
      groups.set(groupKey, existing);
    }
    return Array.from(groups.entries()).map(([groupKey, lots]) => {
      const first = lots[0];
      const itemInput = first as unknown as MaterialForItemInput;
      const alreadyInputted = itemInput.alreadyInputted ?? 0;
      const effectiveRequiredQty = Math.max(0, itemInput.remainingRequiredQty ?? first.requiredQty);
      return {
        itemId: first.itemId,
        groupKey,
        materialName: first.materialName,
        materialCode: first.materialCode,
        requiredQty: first.requiredQty,
        effectiveRequiredQty,
        alreadyInputted,
        unit: first.unit,
        lots: lots.sort((a, b) => a.fifoRank - b.fifoRank),
        workOrderItemId: first.workOrderItemId,
        lotPrefix: first.lotPrefix,
        partType: first.partType,
        category: first.category,
      };
    });
  }, [materials]);

  // 선택된 로트에 FIFO 순서로 자동 배분 계산
  const allocations = useMemo(() => {
    const result = new Map<string, number>();
    for (const group of materialGroups) {
      let remaining = group.effectiveRequiredQty;
      for (const lot of group.lots) {
        const lotKey = getLotKey(lot);
        if (selectedLotKeys.has(lotKey) && lot.stockLotId && remaining > 0) {
          const alloc = Math.min(lot.lotAvailableQty, remaining);
          result.set(lotKey, alloc);
          remaining -= alloc;
        }
      }
    }
    return result;
  }, [materialGroups, selectedLotKeys]);

  // 전체 배정 완료 여부
  const allGroupsFulfilled = useMemo(() => {
    if (materialGroups.length === 0) return false;
    return materialGroups.every((group) => {
      const allocated = group.lots.reduce(
        (sum, lot) => sum + (allocations.get(getLotKey(lot)) || 0),
        0
      );
      return group.effectiveRequiredQty <= 0 || allocated >= group.effectiveRequiredQty;
    });
  }, [materialGroups, allocations]);

  // 배정된 항목 존재 여부
  const hasAnyAllocation = useMemo(() => {
    return Array.from(allocations.values()).some((v) => v > 0);
  }, [allocations]);

  // 로트 선택/해제
  const toggleLot = useCallback((lotKey: string) => {
    setSelectedLotKeys((prev) => {
      const next = new Set(prev);
      if (next.has(lotKey)) {
        next.delete(lotKey);
      } else {
        next.add(lotKey);
      }
      return next;
    });
  }, []);

  // API로 자재 목록 로드
  const loadMaterials = useCallback(async () => {
    if (!order) return;

    setIsLoading(true);
    try {
      // 목업 아이템인 경우 목업 자재 데이터 사용
      if (order.id.startsWith('mock-')) {
        setMaterials(MOCK_MATERIALS);
        setIsLoading(false);
        return;
      }

      // 개소 대표 아이템 1개만 조회 (dynamic_bom은 개소 내 모든 아이템에 동일하게 저장됨)
      const itemId = workOrderItemId
        ?? (workOrderItemIds && workOrderItemIds.length > 0 ? workOrderItemIds[0] : null);

      if (itemId) {
        const result = await getMaterialsForItem(order.id, itemId);
        if (result.success) {
          const tagged = result.data.map((m) => ({
            ...m,
            workOrderItemId: m.workOrderItemId || itemId,
          }));
          setMaterials(tagged);
        } else {
          toast.error(result.error || '자재 목록 조회에 실패했습니다.');
        }
      } else {
        // 전체 작업지시 기준 조회
        const result = await getMaterialsForWorkOrder(order.id);
        if (result.success) {
          setMaterials(result.data);
        } else {
          toast.error(result.error || '자재 목록 조회에 실패했습니다.');
        }
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('[MaterialInputModal] loadMaterials error:', error);
      toast.error('자재 목록 로드 중 오류가 발생했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, [order, workOrderItemId, workOrderItemIds]);

  // 모달이 열릴 때 데이터 로드 + 선택 초기화
  useEffect(() => {
    if (open && order) {
      loadMaterials();
      setSelectedLotKeys(new Set());
    }
  }, [open, order, loadMaterials]);

  // 투입 등록
  const handleSubmit = async () => {
    if (!order) return;

    // 배분된 로트만 추출 (dynamic_bom이면 work_order_item_id 포함)
    const inputs: { stock_lot_id: number; qty: number; work_order_item_id?: number }[] = [];
    for (const [lotKey, allocQty] of allocations) {
      if (allocQty > 0) {
        const material = materials.find((m) => getLotKey(m) === lotKey);
        if (material?.stockLotId) {
          const input: { stock_lot_id: number; qty: number; work_order_item_id?: number } = {
            stock_lot_id: material.stockLotId,
            qty: allocQty,
          };
          if (material.workOrderItemId) {
            input.work_order_item_id = material.workOrderItemId;
          }
          inputs.push(input);
        }
      }
    }

    if (inputs.length === 0) {
      toast.error('투입할 로트를 선택해주세요.');
      return;
    }

    setIsSubmitting(true);
    try {
      // 대표 아이템 기준 자재 투입 등록
      let result: { success: boolean; error?: string };
      const targetItemId = workOrderItemId
        ?? (workOrderItemIds && workOrderItemIds.length > 0 ? workOrderItemIds[0] : null);

      if (targetItemId) {
        const simpleInputs = inputs.map(({ stock_lot_id, qty }) => ({ stock_lot_id, qty }));
        result = await registerMaterialInputForItem(order.id, targetItemId, simpleInputs);
      } else {
        result = await registerMaterialInput(order.id, inputs);
      }

      if (result.success) {
        toast.success('자재 투입이 등록되었습니다.');

        if (onSaveMaterials) {
          const savedList: MaterialInput[] = [];
          for (const [lotKey, allocQty] of allocations) {
            if (allocQty > 0) {
              const material = materials.find((m) => getLotKey(m) === lotKey);
              if (material) {
                savedList.push({
                  id: String(material.stockLotId),
                  lotNo: material.lotNo || '',
                  materialName: material.materialName,
                  quantity: material.lotAvailableQty,
                  unit: material.unit,
                  inputQuantity: allocQty,
                });
              }
            }
          }
          onSaveMaterials(order.id, savedList);
        }

        resetAndClose();

        if (isCompletionFlow && onComplete) {
          onComplete();
        }
      } else {
        toast.error(result.error || '자재 투입 등록에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('[MaterialInputModal] handleSubmit error:', error);
      toast.error('자재 투입 등록 중 오류가 발생했습니다.');
    } finally {
      setIsSubmitting(false);
    }
  };

  const resetAndClose = () => {
    setSelectedLotKeys(new Set());
    onOpenChange(false);
  };

  if (!order) return null;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="!max-w-3xl p-0 gap-0">
        {/* 헤더 */}
        <DialogHeader className="p-6 pb-4">
          <DialogTitle className="text-xl font-semibold">
            자재 투입{workOrderItemName ? ` - ${workOrderItemName}` : ''}
          </DialogTitle>
          <p className="text-sm text-gray-500 mt-1">
            로트를 선택하면 필요수량만큼 자동 배분됩니다.
          </p>
        </DialogHeader>

        <div className="px-6 pb-6 space-y-4">
          {/* 자재 목록 */}
          {isLoading ? (
            <ContentSkeleton type="table" rows={4} />
          ) : materials.length === 0 ? (
            <div className="border rounded-lg py-12 text-center text-sm text-gray-500">
              이 공정에 배정된 자재가 없습니다.
            </div>
          ) : (
            <div className="space-y-4 max-h-[60vh] overflow-y-auto">
              {materialGroups.map((group) => {
                const groupAllocated = group.lots.reduce(
                  (sum, lot) => sum + (allocations.get(getLotKey(lot)) || 0),
                  0
                );
                const isAlreadyComplete = group.effectiveRequiredQty <= 0;
                const isFulfilled = isAlreadyComplete || groupAllocated >= group.effectiveRequiredQty;

                return (
                  <div key={group.groupKey} className="border rounded-lg overflow-hidden">
                    {/* 품목 그룹 헤더 */}
                    <div className="flex items-center justify-between px-4 py-2.5 bg-gray-50 border-b">
                      <div className="flex items-center gap-2">
                        {group.category && (
                          <span className={`text-[10px] px-1.5 py-0.5 rounded font-medium ${
                            group.category === 'guideRail' ? 'bg-blue-100 text-blue-700' :
                            group.category === 'bottomBar' ? 'bg-green-100 text-green-700' :
                            group.category === 'shutterBox' ? 'bg-orange-100 text-orange-700' :
                            group.category === 'smokeBarrier' ? 'bg-red-100 text-red-700' :
                            'bg-gray-100 text-gray-600'
                          }`}>
                            {group.category === 'guideRail' ? '가이드레일' :
                             group.category === 'bottomBar' ? '하단마감재' :
                             group.category === 'shutterBox' ? '셔터박스' :
                             group.category === 'smokeBarrier' ? '연기차단재' :
                             group.category}
                          </span>
                        )}
                        <span className="text-sm font-semibold text-gray-900">
                          {group.materialName}
                        </span>
                        {group.materialCode && (
                          <span className="text-xs text-gray-400">
                            {group.materialCode}
                          </span>
                        )}
                      </div>
                      <div className="flex items-center gap-3">
                        <span className="text-xs text-gray-500">
                          {group.alreadyInputted > 0 ? (
                            <>
                              필요:{' '}
                              <span className="font-semibold text-gray-900">
                                {fmtQty(group.effectiveRequiredQty)}
                              </span>{' '}
                              {group.unit}
                              <span className="ml-1 text-gray-400">
                                (기투입: {fmtQty(group.alreadyInputted)})
                              </span>
                            </>
                          ) : (
                            <>
                              필요:{' '}
                              <span className="font-semibold text-gray-900">
                                {fmtQty(group.requiredQty)}
                              </span>{' '}
                              {group.unit}
                            </>
                          )}
                        </span>
                        <span
                          className={`text-xs font-semibold px-2 py-0.5 rounded-full flex items-center gap-1 ${
                            isAlreadyComplete
                              ? 'bg-emerald-100 text-emerald-700'
                              : isFulfilled
                                ? 'bg-emerald-100 text-emerald-700'
                                : groupAllocated > 0
                                  ? 'bg-amber-100 text-amber-700'
                                  : 'bg-gray-100 text-gray-500'
                          }`}
                        >
                          {isAlreadyComplete ? (
                            <>
                              <Check className="h-3 w-3" />
                              투입 완료
                            </>
                          ) : isFulfilled ? (
                            <>
                              <Check className="h-3 w-3" />
                              배정 완료
                            </>
                          ) : (
                            `${fmtQty(groupAllocated)} / ${fmtQty(group.effectiveRequiredQty)}`
                          )}
                        </span>
                      </div>
                    </div>

                    {/* 로트 테이블 */}
                    <Table>
                      <TableHeader>
                        <TableRow>
                          <TableHead className="text-center w-20">선택</TableHead>
                          <TableHead className="text-center">로트번호</TableHead>
                          <TableHead className="text-center">가용수량</TableHead>
                          <TableHead className="text-center">단위</TableHead>
                          <TableHead className="text-center">배정수량</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {group.lots.map((lot, idx) => {
                          const lotKey = getLotKey(lot);
                          const hasStock = lot.stockLotId !== null;
                          const isSelected = selectedLotKeys.has(lotKey);
                          const allocated = allocations.get(lotKey) || 0;
                          const canSelect = hasStock && !isAlreadyComplete && (!isFulfilled || isSelected);

                          return (
                            <TableRow
                              key={`${lotKey}-${idx}`}
                              className={
                                isSelected && allocated > 0
                                  ? 'bg-blue-50/50'
                                  : ''
                              }
                            >
                              <TableCell className="text-center">
                                {hasStock ? (
                                  <button
                                    onClick={() => toggleLot(lotKey)}
                                    disabled={!canSelect}
                                    className={cn(
                                      'min-w-[56px] px-3 py-1.5 rounded-lg text-xs font-semibold transition-all',
                                      isSelected
                                        ? 'bg-blue-600 text-white shadow-sm'
                                        : canSelect
                                          ? 'bg-gray-100 text-gray-600 hover:bg-gray-200'
                                          : 'bg-gray-100 text-gray-400 cursor-not-allowed'
                                    )}
                                  >
                                    {isSelected ? '선택됨' : '선택'}
                                  </button>
                                ) : null}
                              </TableCell>
                              <TableCell className="text-center text-sm">
                                {lot.lotNo || (
                                  <span className="text-gray-400">
                                    재고 없음
                                  </span>
                                )}
                              </TableCell>
                              <TableCell className="text-center text-sm">
                                {hasStock ? (
                                  fmtQty(lot.lotAvailableQty)
                                ) : (
                                  <span className="text-red-500">0</span>
                                )}
                              </TableCell>
                              <TableCell className="text-center text-sm">
                                {lot.unit}
                              </TableCell>
                              <TableCell className="text-center text-sm font-medium">
                                {allocated > 0 ? (
                                  <span className="text-blue-600">
                                    {fmtQty(allocated)}
                                  </span>
                                ) : (
                                  <span className="text-gray-300">-</span>
                                )}
                              </TableCell>
                            </TableRow>
                          );
                        })}
                      </TableBody>
                    </Table>
                  </div>
                );
              })}
            </div>
          )}

          {/* 버튼 영역 */}
          <div className="flex gap-3">
            <Button
              variant="outline"
              onClick={resetAndClose}
              disabled={isSubmitting}
              className="flex-1 py-6 text-base font-medium"
            >
              취소
            </Button>
            <Button
              onClick={handleSubmit}
              disabled={isSubmitting || !hasAnyAllocation}
              className="flex-1 py-6 text-base font-medium bg-gray-900 hover:bg-gray-800"
            >
              {isSubmitting ? (
                <>
                  <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                  등록 중...
                </>
              ) : (
                '투입'
              )}
            </Button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
