'use client';

/**
 * 중간검사 성적서 모달
 *
 * DocumentViewer 껍데기 안에 공정별 검사 성적서 콘텐츠를 표시
 * - screen: ScreenInspectionContent
 * - slat: SlatInspectionContent
 * - bending: BendingInspectionContent
 *
 * Phase 4: API 연동 - getInspectionReport로 검사 데이터 자체 로딩
 */

import { useState, useEffect, useRef, useCallback } from 'react';
import { Loader2, Save, Send } from 'lucide-react';
import { DocumentViewer } from '@/components/document-system';
import { Button } from '@/components/ui/button';
import { toast } from 'sonner';
import {
  getWorkOrderById,
  saveInspectionData,
  getInspectionReport,
  getInspectionTemplate,
  saveInspectionDocument,
  resolveInspectionDocument,
  submitDocumentForApproval,
  patchDocumentSnapshot,
} from '../actions';
import type { WorkOrder, ProcessType } from '../types';
import type { InspectionReportData, InspectionReportNodeGroup } from '../actions';
import { ScreenInspectionContent } from './ScreenInspectionContent';
import { SlatInspectionContent } from './SlatInspectionContent';
import { BendingInspectionContent } from './BendingInspectionContent';
import { BendingWipInspectionContent } from './BendingWipInspectionContent';
import { SlatJointBarInspectionContent } from './SlatJointBarInspectionContent';
import { TemplateInspectionContent } from './TemplateInspectionContent';
import type { InspectionContentRef } from './ScreenInspectionContent';
import type { InspectionData } from '@/components/production/WorkerScreen/InspectionInputModal';
import type { WorkItemData } from '@/components/production/WorkerScreen/types';
import type { InspectionSetting } from '@/types/process';
import type { InspectionTemplateData } from '@/components/production/WorkerScreen/types';

const PROCESS_LABELS: Record<ProcessType, string> = {
  screen: '스크린',
  slat: '슬랫',
  bending: '절곡',
  bending_wip: '절곡 재공품',
};

// 작업 아이템별 검사 데이터 맵 타입
export type InspectionDataMap = Map<string, InspectionData>;

interface InspectionReportModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  workOrderId: string | null;
  processType?: ProcessType;
  readOnly?: boolean;
  isJointBar?: boolean;
  inspectionData?: InspectionData;
  /** 작업 아이템 목록 - 행 개수 동적 생성용 */
  workItems?: WorkItemData[];
  /** 아이템별 검사 데이터 맵 */
  inspectionDataMap?: InspectionDataMap;
  /** 중간검사 설정 - 도해/검사기준 이미지 표시용 */
  inspectionSetting?: InspectionSetting;
  /** 문서 템플릿 데이터 (있으면 동적 렌더링 모드) */
  templateData?: InspectionTemplateData;
}

/**
 * API 응답의 inspection_data를 InspectionData 형식으로 변환
 */
function toInspectionData(raw: Record<string, unknown>): InspectionData {
  return raw as unknown as InspectionData;
}

/**
 * API 응답을 WorkItemData[] + InspectionDataMap으로 변환
 * node_groups가 있으면 개소(node) 단위, 없으면 개별 아이템 단위 (폴백)
 */
function buildFromReportData(
  reportData: InspectionReportData,
  processType: ProcessType
): { workItems: WorkItemData[]; inspectionDataMap: InspectionDataMap } {
  const workItems: WorkItemData[] = [];
  const inspectionDataMap: InspectionDataMap = new Map();

  // node_groups가 있으면 개소(node) 단위로 생성 — WorkerScreen과 동일
  if (reportData.node_groups && reportData.node_groups.length > 0) {
    reportData.node_groups.forEach((group: InspectionReportNodeGroup, index: number) => {
      const nodeKey = group.node_id != null ? String(group.node_id) : `unassigned-${index}`;
      const syntheticId = `report-node-${nodeKey}`;
      const itemNames = group.items.map((it) => it.item_name).filter(Boolean);

      workItems.push({
        id: syntheticId,
        apiItemId: group.items[0]?.id,
        itemNo: index + 1,
        itemCode: '',
        itemName: itemNames.join(', ') || '-',
        floor: group.floor || '-',
        code: group.code || '-',
        width: group.width || 0,
        height: group.height || 0,
        quantity: group.total_quantity,
        processType: processType === 'bending_wip' ? 'bending' : processType,
        steps: [],
      });

      // 개소 내 아이템 중 inspection_data가 있으면 병합
      for (const item of group.items) {
        if (item.inspection_data) {
          inspectionDataMap.set(syntheticId, toInspectionData(item.inspection_data));
          break; // 개소 단위 검사 데이터는 첫 번째 것 사용
        }
      }
    });

    return { workItems, inspectionDataMap };
  }

  // 폴백: 개별 아이템 단위 (node_groups 없는 구버전 응답)
  for (const item of reportData.items) {
    const syntheticId = `report-item-${item.id}`;

    workItems.push({
      id: syntheticId,
      apiItemId: item.id,
      itemNo: item.sort_order,
      itemCode: '',
      itemName: item.item_name,
      floor: '',
      code: '',
      width: 0,
      height: 0,
      quantity: item.quantity,
      processType: processType === 'bending_wip' ? 'bending' : processType,
      steps: [],
    });

    if (item.inspection_data) {
      inspectionDataMap.set(syntheticId, toInspectionData(item.inspection_data));
    }
  }

  return { workItems, inspectionDataMap };
}

export function InspectionReportModal({
  open,
  onOpenChange,
  workOrderId,
  processType = 'screen',
  readOnly = true,
  isJointBar = false,
  inspectionData,
  workItems: propWorkItems,
  inspectionDataMap: propInspectionDataMap,
  inspectionSetting,
  templateData,
}: InspectionReportModalProps) {
  const [order, setOrder] = useState<WorkOrder | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const contentRef = useRef<InspectionContentRef>(null);
  const contentWrapperRef = useRef<HTMLDivElement>(null);

  // API에서 로딩된 검사 데이터 (props 없을 때 fallback)
  const [apiWorkItems, setApiWorkItems] = useState<WorkItemData[] | null>(null);
  const [apiInspectionDataMap, setApiInspectionDataMap] = useState<InspectionDataMap | null>(null);
  const [reportSummary, setReportSummary] = useState<InspectionReportData['summary'] | null>(null);
  // 자체 로딩한 템플릿 데이터 (prop으로 안 넘어올 때)
  const [selfTemplateData, setSelfTemplateData] = useState<InspectionTemplateData | null>(null);
  // 기존 문서의 document_data EAV 레코드 (bending 복원용)
  const [documentRecords, setDocumentRecords] = useState<Array<{
    section_id: number | null;
    column_id: number | null;
    row_index: number;
    field_key: string;
    field_value: string | null;
  }> | null>(null);
  // 기존 문서 ID/상태 (결재 상신용)
  const [savedDocumentId, setSavedDocumentId] = useState<number | null>(null);
  const [savedDocumentStatus, setSavedDocumentStatus] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  // Lazy Snapshot 대상 문서 ID (rendered_html이 없는 문서)
  const [snapshotDocumentId, setSnapshotDocumentId] = useState<number | null>(null);

  // props에서 목업 제외한 실제 개소만 사용 (WorkerScreen에서 apiItems + mockItems가 합쳐져 전달됨)
  // ★ 반드시 workItems와 inspectionDataMap을 같은 소스에서 가져와야 key 포맷이 일치함
  //   props: key = "${orderId}-node-${nodeKey}" (예: "18-node-1층/FSS-01")
  //   API:   key = "report-item-${itemId}" (예: "report-item-42")
  const propFiltered = propWorkItems?.filter(w => !w.id.startsWith('mock-'));
  const propHasWorkItems = propFiltered && propFiltered.length > 0;
  const propHasInspectionData = propInspectionDataMap != null;
  const usePropsSource = propHasWorkItems && propHasInspectionData;
  const effectiveWorkItems = usePropsSource ? propFiltered : apiWorkItems ?? undefined;
  const effectiveInspectionDataMap = usePropsSource ? propInspectionDataMap : apiInspectionDataMap ?? undefined;



  // 목업 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,
    processType: pType,
    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: '',
  });

  useEffect(() => {
    if (open && workOrderId) {
      // 목업 ID인 경우 API 호출 생략
      if (workOrderId.startsWith('mock-')) {
        setOrder(createMockOrder(workOrderId, processType));
        setApiWorkItems(null);
        setApiInspectionDataMap(null);
        setReportSummary(null);
        setError(null);
        return;
      }

      setIsLoading(true);
      setError(null);

      // 작업지시 기본정보 + 검사 성적서 + 템플릿 + 기존 문서 동시 로딩
      Promise.all([
        getWorkOrderById(workOrderId),
        getInspectionReport(workOrderId),
        // prop으로 템플릿이 안 넘어왔으면 자체 로딩
        !templateData ? getInspectionTemplate(workOrderId) : Promise.resolve(null),
        // 기존 저장된 문서 조회 (document_data EAV 복원용)
        resolveInspectionDocument(workOrderId),
      ])
        .then(([orderResult, reportResult, templateResult, resolveResult]) => {
          // 1) WorkOrder 기본정보
          if (orderResult.success && orderResult.data) {
            const orderData = orderResult.data;
            // API 성적서 응답에서 수주 정보 보강
            if (reportResult.success && reportResult.data?.order) {
              const reportOrder = reportResult.data.order;
              if (reportOrder.client_name && !orderData.client) {
                orderData.client = reportOrder.client_name;
              }
              if (reportOrder.site_name && !orderData.projectName) {
                orderData.projectName = reportOrder.site_name;
              }
            }
            setOrder(orderData);
          } else {
            setError(orderResult.error || '데이터를 불러올 수 없습니다.');
          }

          // 2) 검사 성적서 데이터 → workItems + inspectionDataMap 구성
          if (reportResult.success && reportResult.data) {
            const { workItems: apiItems, inspectionDataMap: apiMap } =
              buildFromReportData(reportResult.data, processType);
            setApiWorkItems(apiItems);
            setApiInspectionDataMap(apiMap);
            setReportSummary(reportResult.data.summary);
          } else {
            // 성적서 API 실패해도 기본 WorkOrder는 표시 (fallback to props)
            setApiWorkItems(null);
            setApiInspectionDataMap(null);
            setReportSummary(null);
          }

          // 3) 템플릿 데이터 (자체 로딩한 경우)
          if (templateResult && templateResult.success && templateResult.data) {
            setSelfTemplateData(templateResult.data);
          }

          // 4) 기존 문서의 document_data EAV 레코드 + ID/상태 추출
          if (resolveResult?.success && resolveResult.data) {
            const resolveData = resolveResult.data as Record<string, unknown>;
            const existingDoc = resolveData.existing_document as
              | { id?: number; status?: string; data?: Array<{ section_id: number | null; column_id: number | null; row_index: number; field_key: string; field_value: string | null }> }
              | null;
            if (existingDoc?.data && existingDoc.data.length > 0) {
              setDocumentRecords(existingDoc.data);
            } else {
              setDocumentRecords(null);
            }
            // 문서 ID/상태 저장 (결재 상신용)
            setSavedDocumentId(existingDoc?.id ?? null);
            setSavedDocumentStatus(existingDoc?.status ?? null);
            // Lazy Snapshot 대상 문서 ID
            setSnapshotDocumentId((resolveData.snapshot_document_id as number) ?? null);
          } else {
            setDocumentRecords(null);
            setSavedDocumentId(null);
            setSavedDocumentStatus(null);
            setSnapshotDocumentId(null);
          }
        })
        .catch(() => {
          setError('서버 오류가 발생했습니다.');
        })
        .finally(() => {
          setIsLoading(false);
        });
    } else if (!open) {
      setOrder(null);
      setApiWorkItems(null);
      setApiInspectionDataMap(null);
      setReportSummary(null);
      setSelfTemplateData(null);
      setDocumentRecords(null);
      setSavedDocumentId(null);
      setSavedDocumentStatus(null);
      setSnapshotDocumentId(null);
      setError(null);
    }
  }, [open, workOrderId, processType, templateData]);

  // 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); // DOM 렌더링 완료 대기

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

  // 템플릿 결정: prop 우선, 없으면 자체 로딩 결과 사용
  const resolvedTemplateData = templateData || selfTemplateData;
  const activeTemplate = resolvedTemplateData?.has_template ? resolvedTemplateData.template : null;
  const activeStepId = resolvedTemplateData?.templates?.[0]?.step_id ?? null;

  const handleSave = useCallback(async () => {
    if (!workOrderId || !contentRef.current) return;

    const data = contentRef.current.getInspectionData();
    // HTML 스냅샷 캡처 (MNG 출력용)
    const renderedHtml = contentWrapperRef.current?.innerHTML || undefined;
    setIsSaving(true);
    try {
      // 템플릿 모드: Document 기반 저장 (정규화 형식)
      if (activeTemplate) {
        const inspData = data as {
          template_id: number;
          records: Array<{
            section_id: number | null;
            column_id: number | null;
            row_index: number;
            field_key: string;
            field_value: string | null;
          }>;
        };
        const result = await saveInspectionDocument(workOrderId, {
          step_id: activeStepId ?? undefined,
          title: activeTemplate.title || activeTemplate.name,
          data: inspData.records,
          rendered_html: renderedHtml,
        });
        if (result.success) {
          toast.success('검사 문서가 저장되었습니다.');
          // 저장 후 문서 ID/상태 갱신 (결재 상신 활성화용)
          const docData = result.data as { id?: number; status?: string } | undefined;
          if (docData?.id) {
            setSavedDocumentId(docData.id);
            setSavedDocumentStatus(docData.status ?? 'DRAFT');
          }
        } else {
          toast.error(result.error || '저장에 실패했습니다.');
        }
      } else {
        // 레거시 모드: 기존 저장
        const result = await saveInspectionData(workOrderId, processType, data);
        if (result.success) {
          toast.success('검사 데이터가 저장되었습니다.');
        } else {
          toast.error(result.error || '저장에 실패했습니다.');
        }
      }
    } catch {
      toast.error('저장 중 오류가 발생했습니다.');
    } finally {
      setIsSaving(false);
    }
  }, [workOrderId, processType, activeTemplate, activeStepId]);

  // 결재 상신 핸들러
  const handleSubmitForApproval = useCallback(async () => {
    if (!savedDocumentId) return;

    setIsSubmitting(true);
    try {
      const result = await submitDocumentForApproval(savedDocumentId);
      if (result.success) {
        toast.success('결재 상신이 완료되었습니다.');
        setSavedDocumentStatus('PENDING');
        onOpenChange(false);
      } else {
        toast.error(result.error || '결재 상신에 실패했습니다.');
      }
    } catch {
      toast.error('결재 상신 중 오류가 발생했습니다.');
    } finally {
      setIsSubmitting(false);
    }
  }, [savedDocumentId, onOpenChange]);

  if (!workOrderId) return null;

  const processLabel = PROCESS_LABELS[processType] || '스크린';
  const subtitle = order ? `${processLabel} 생산부서` : undefined;
  const modalTitle = processType === 'bending_wip'
    ? '절곡품 재고생산 작업일지 중간검사성적서'
    : (isJointBar || (order?.items?.some(item => item.productName?.includes('조인트바'))))
      ? '중간검사성적서 (조인트바)'
      : '중간검사 성적서';

  const renderContent = () => {
    if (!order) return null;

    // 템플릿 모드: TemplateInspectionContent 사용
    if (activeTemplate) {
      return (
        <TemplateInspectionContent
          ref={contentRef}
          data={order}
          template={activeTemplate}
          readOnly={readOnly}
          workItems={effectiveWorkItems}
          inspectionDataMap={effectiveInspectionDataMap}
          documentRecords={documentRecords ?? undefined}
        />
      );
    }

    // 레거시 모드: 공정별 하드코딩 컴포넌트
    const commonProps = {
      ref: contentRef,
      data: order,
      readOnly,
      inspectionData,
      workItems: effectiveWorkItems,
      inspectionDataMap: effectiveInspectionDataMap,
      inspectionSetting,
    };

    switch (processType) {
      case 'screen':
        return <ScreenInspectionContent {...commonProps} />;
      case 'slat':
        // 조인트바 여부 체크: isJointBar prop 또는 items에서 자동 감지
        if (isJointBar || order.items?.some(item => item.productName?.includes('조인트바'))) {
          return <SlatJointBarInspectionContent {...commonProps} />;
        }
        return <SlatInspectionContent {...commonProps} />;
      case 'bending':
        return <BendingInspectionContent {...commonProps} />;
      case 'bending_wip':
        return <BendingWipInspectionContent {...commonProps} />;
      default:
        return <ScreenInspectionContent {...commonProps} />;
    }
  };

  // 결재 상신 가능 여부: 저장된 DRAFT 문서가 있을 때
  const canSubmitForApproval = savedDocumentId != null && savedDocumentStatus === 'DRAFT';

  const toolbarExtra = !readOnly ? (
    <div className="flex items-center gap-2">
      <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>
      {canSubmitForApproval && (
        <Button
          onClick={handleSubmitForApproval}
          disabled={isSubmitting}
          size="sm"
          className="bg-blue-600 hover:bg-blue-700 text-white"
        >
          {isSubmitting ? (
            <Loader2 className="w-4 h-4 mr-1.5 animate-spin" />
          ) : (
            <Send className="w-4 h-4 mr-1.5" />
          )}
          {isSubmitting ? '상신 중...' : '결재 상신'}
        </Button>
      )}
    </div>
  ) : undefined;

  // 검사 진행 상태 표시 (summary 있을 때)
  const summaryInfo = reportSummary && reportSummary.total_items > 0
    ? `검사 ${reportSummary.inspected_items}/${reportSummary.total_items}건`
    : undefined;

  return (
    <DocumentViewer
      title={modalTitle}
      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>
      ) : (
        <>
          {summaryInfo && (
            <div className="px-6 pt-2 text-xs text-gray-500 bg-white">
              {summaryInfo}
              {reportSummary!.failed_items > 0 && (
                <span className="ml-2 text-red-500">
                  (부적합 {reportSummary!.failed_items}건)
                </span>
              )}
            </div>
          )}
          <div ref={contentWrapperRef}>
            {renderContent()}
          </div>
        </>
      )}
    </DocumentViewer>
  );
}