'use client';

/**
 * 작업일지 모달
 *
 * document-system 통합 버전 (2026-01-22)
 * 공정별 작업일지 지원 (2026-01-29)
 * 공정관리 양식 매핑 연동 (2026-02-11)
 * - DocumentViewer 사용
 * - 공정관리에서 매핑된 workLogTemplateId/Name 기반으로 콘텐츠 분기
 * - 양식 미매핑 시 processType 폴백
 */

import { useState, useEffect, useCallback, useRef } from 'react';
import { Loader2, Save } from 'lucide-react';
import { DocumentViewer } from '@/components/document-system';
import { Button } from '@/components/ui/button';
import { toast } from 'sonner';
import { getWorkOrderById, getMaterialInputLots, patchDocumentSnapshot } from '../WorkOrders/actions';
import { saveWorkLog, getWorkLog } from './actions';
import type { MaterialInputLot } from '../WorkOrders/actions';
import type { WorkOrder, ProcessType } from '../WorkOrders/types';
import { WorkLogContent } from './WorkLogContent';
import {
  ScreenWorkLogContent,
  SlatWorkLogContent,
  BendingWorkLogContent,
} from '../WorkOrders/documents';

interface WorkLogModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  workOrderId: string | null;
  processType?: ProcessType;
  /** 공정관리에서 매핑된 작업일지 양식 ID */
  workLogTemplateId?: number;
  /** 공정관리에서 매핑된 작업일지 양식명 (예: '스크린 작업일지') */
  workLogTemplateName?: string;
}

/**
 * 양식명 → 공정 타입 매핑
 * 공정관리에서 매핑된 양식명을 기반으로 콘텐츠 컴포넌트를 결정
 */
function resolveProcessTypeFromTemplate(templateName?: string): ProcessType | 'template' | undefined {
  if (!templateName) return undefined;
  // 재공품 전용 작업일지는 템플릿 기반(범용) 렌더링
  if (templateName.includes('재공품')) return 'template';
  if (templateName.includes('스크린')) return 'screen';
  if (templateName.includes('슬랫')) return 'slat';
  if (templateName.includes('절곡')) return 'bending';
  return undefined;
}

export function WorkLogModal({
  open,
  onOpenChange,
  workOrderId,
  processType,
  workLogTemplateId,
  workLogTemplateName,
}: WorkLogModalProps) {
  const [order, setOrder] = useState<WorkOrder | null>(null);
  const [materialLots, setMaterialLots] = useState<MaterialInputLot[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [bendingImages, setBendingImages] = useState<Record<string, string>>({});
  const contentWrapperRef = useRef<HTMLDivElement>(null);
  // Lazy Snapshot 대상 문서 ID
  const [snapshotDocumentId, setSnapshotDocumentId] = useState<number | null>(null);

  // 목업 WorkOrder 생성
  const createMockOrder = (id: string, pType?: ProcessType): WorkOrder => ({
    id,
    workOrderNo: 'KD-WO-260129-01',
    lotNo: 'KD-SA-260129-01',
    processId: 1,
    processName: pType === 'slat' ? '슬랫' : pType === 'bending' ? '절곡' : '스크린',
    processCode: pType || 'screen',
    processType: pType || 'screen',
    status: 'in_progress',
    client: '(주)경동',
    projectName: '서울 강남 현장',
    dueDate: '2026-02-05',
    assignee: '홍길동',
    assignees: [{ id: '1', name: '홍길동', isPrimary: true }],
    orderDate: '2026-01-20',
    scheduledDate: '2026-01-29',
    shipmentDate: '2026-02-05',
    salesOrderDate: '2026-01-15',
    isAssigned: true,
    isStarted: true,
    priority: 3,
    priorityLabel: '긴급',
    shutterCount: 12,
    department: '생산부',
    items: [
      { id: '1', no: 1, status: 'in_progress', itemCode: '', productName: '와이어 스크린', floorCode: '1층/FSS-01', specification: '8,260 X 8,350', quantity: 2, unit: 'EA', orderNodeId: null, orderNodeName: '' },
      { id: '2', no: 2, status: 'waiting', itemCode: '', productName: '메쉬 스크린', floorCode: '2층/FSS-03', specification: '6,400 X 5,200', quantity: 4, unit: 'EA', orderNodeId: null, orderNodeName: '' },
      { id: '3', no: 3, status: 'completed', itemCode: '', productName: '광폭 와이어', floorCode: '3층/FSS-05', specification: '12,000 X 4,500', quantity: 1, unit: 'EA', orderNodeId: null, orderNodeName: '' },
    ],
    currentStep: 2,
    issues: [],
    note: '',
  });

  // 모달 열릴 때 데이터 fetch
  useEffect(() => {
    if (open && workOrderId) {
      // 목업 ID인 경우 API 호출 생략
      if (workOrderId.startsWith('mock-')) {
        setOrder(createMockOrder(workOrderId, processType));
        setError(null);
        return;
      }

      setIsLoading(true);
      setError(null);

      Promise.all([
        getWorkOrderById(workOrderId),
        getMaterialInputLots(workOrderId),
        getWorkLog(workOrderId),
      ])
        .then(([orderResult, lotsResult, workLogResult]) => {
          if (orderResult.success && orderResult.data) {
            setOrder(orderResult.data);
          } else {
            setError(orderResult.error || '데이터를 불러올 수 없습니다.');
          }
          if (lotsResult.success) {
            setMaterialLots(lotsResult.data);
          }
          // bending_images 맵 저장
          if (workLogResult.success && workLogResult.data?.bending_images) {
            setBendingImages(workLogResult.data.bending_images);
          }
          // Lazy Snapshot: 문서가 있고 rendered_html이 없으면 스냅샷 대상
          if (workLogResult.success && workLogResult.data?.document) {
            const doc = workLogResult.data.document as { id?: number; rendered_html?: string | null };
            if (doc.id && !doc.rendered_html) {
              setSnapshotDocumentId(doc.id);
            }
          }
        })
        .catch(() => {
          setError('서버 오류가 발생했습니다.');
        })
        .finally(() => {
          setIsLoading(false);
        });
    } else if (!open) {
      // 모달 닫힐 때 상태 초기화
      setOrder(null);
      setMaterialLots([]);
      setBendingImages({});
      setSnapshotDocumentId(null);
      setError(null);
    }
  }, [open, workOrderId, processType]);

  // Lazy Snapshot: 콘텐츠 렌더링 완료 후 rendered_html이 없는 문서에 스냅샷 저장
  useEffect(() => {
    if (!snapshotDocumentId || isLoading || !order) return;

    const timer = setTimeout(() => {
      const html = contentWrapperRef.current?.innerHTML;
      if (html && html.length > 50) {
        patchDocumentSnapshot(snapshotDocumentId, html).then((result) => {
          if (result.success) {
            setSnapshotDocumentId(null);
          }
        });
      }
    }, 500);

    return () => clearTimeout(timer);
  }, [snapshotDocumentId, isLoading, order]);

  // 저장 핸들러
  const handleSave = useCallback(async () => {
    if (!workOrderId || !order) return;

    setIsSaving(true);
    try {
      // 현재 아이템 데이터를 table_data로 변환
      const tableData = (order.items || []).map((item) => ({
        id: item.id,
        item_name: item.productName,
        specification: item.specification || item.floorCode,
        quantity: item.quantity,
        unit: item.unit || 'EA',
      }));

      // HTML 스냅샷 캡처 (MNG 출력용)
      const renderedHtml = contentWrapperRef.current?.innerHTML || undefined;

      const result = await saveWorkLog(workOrderId, {
        table_data: tableData,
        title: workLogTemplateName || '작업일지',
        rendered_html: renderedHtml,
      });

      if (result.success) {
        toast.success('작업일지가 저장되었습니다.');
      } else {
        toast.error(result.error || '저장에 실패했습니다.');
      }
    } catch {
      toast.error('저장 중 오류가 발생했습니다.');
    } finally {
      setIsSaving(false);
    }
  }, [workOrderId, order, workLogTemplateName]);

  if (!workOrderId) return null;

  // 로딩/에러 상태는 DocumentViewer 내부에서 처리
  const subtitle = order ? `${order.processName} 생산부서` : undefined;

  // 양식 미매핑 안내
  const renderNoTemplate = () => (
    <div className="flex flex-col items-center justify-center h-64 gap-4 bg-white">
      <p className="text-muted-foreground">
        이 공정에 작업일지 양식이 매핑되지 않았습니다.
      </p>
      <p className="text-sm text-muted-foreground">
        공정관리에서 작업일지 양식을 설정해주세요.
      </p>
    </div>
  );

  // 공정관리 양식 매핑 기반 콘텐츠 분기
  const renderContent = () => {
    if (!order) return null;

    // 1순위: 공정관리에서 매핑된 양식명으로 결정
    const templateType = resolveProcessTypeFromTemplate(workLogTemplateName);

    // 2순위: 작업지시 공정명에서 판별 (process_id가 자식 공정인 경우)
    const orderProcessType = order.processName?.includes('재공품')
      ? 'bending' as const  // 재공품도 절곡 레이아웃 유지 (기본필드만 다름)
      : undefined;

    // 3순위: processType 폴백 (양식 미매핑 시)
    const type = templateType || orderProcessType || processType || order.processType;

    // 양식이 매핑되어 있지 않은 경우 안내
    if (!workLogTemplateId && !processType && !orderProcessType) {
      return renderNoTemplate();
    }

    switch (type) {
      case 'screen':
        return <ScreenWorkLogContent data={order} materialLots={materialLots} />;
      case 'slat':
        return <SlatWorkLogContent data={order} materialLots={materialLots} />;
      case 'bending': {
        const lotNoMap: Record<string, string> = {};
        for (const lot of materialLots) {
          if (lot.item_code.startsWith('BD-')) {
            lotNoMap[lot.item_code] = lot.lot_no;
          }
        }
        // STOCK 단일부품: 원자재 LOT 번호를 직접 전달
        const rawMaterialLotNo = materialLots.find(lot => !lot.item_code.startsWith('BD-'))?.lot_no;
        const isWipOrder = order.processName?.includes('재공품') || order.projectName === '재고생산';
        return (
          <BendingWorkLogContent
            data={order}
            lotNoMap={lotNoMap}
            bendingImages={bendingImages}
            rawMaterialLotNo={rawMaterialLotNo}
            isWip={isWipOrder}
          />
        );
      }
      case 'template':
        // 재공품 등 템플릿 기반 작업일지 → 범용 WorkLogContent
        return <WorkLogContent data={order} />;
      default:
        return <WorkLogContent data={order} />;
    }
  };

  // 양식명으로 문서 제목 결정 (작업지시 공정명 폴백)
  const documentTitle = workLogTemplateName
    || (order?.processName ? `${order.processName} 작업일지` : '작업일지');

  const toolbarExtra = (
    <Button onClick={handleSave} disabled={isSaving} size="sm">
      {isSaving ? (
        <Loader2 className="w-4 h-4 mr-1.5 animate-spin" />
      ) : (
        <Save className="w-4 h-4 mr-1.5" />
      )}
      {isSaving ? '저장 중...' : '저장'}
    </Button>
  );

  return (
    <DocumentViewer
      title={documentTitle}
      subtitle={subtitle}
      preset="inspection"
      open={open}
      onOpenChange={onOpenChange}
      toolbarExtra={toolbarExtra}
    >
      {isLoading ? (
        <div className="flex items-center justify-center h-64 bg-white">
          <Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
        </div>
      ) : error || !order ? (
        <div className="flex flex-col items-center justify-center h-64 gap-4 bg-white">
          <p className="text-muted-foreground">{error || '데이터를 불러올 수 없습니다.'}</p>
        </div>
      ) : (
        <div ref={contentWrapperRef}>
          {renderContent()}
        </div>
      )}
    </DocumentViewer>
  );
}
