'use client';

/**
 * FQC 제품검사 성적서 - 양식 기반 렌더링 (8컬럼)
 *
 * documents 시스템의 template 구조를 기반으로 렌더링:
 * - 결재라인 (3인: 작성/검토/승인)
 * - 기본정보 (7필드: 납품명, 제품명, 발주처, LOT NO, 로트크기, 검사일자, 검사자)
 * - 검사항목 테이블 (8컬럼 시각 레이아웃)
 *   - 1~6: section_item 읽기전용 (No, 검사항목, 세부항목, 검사기준, 검사방법, 검사주기)
 *   - 7~8: template column 편집 (측정값, 판정)
 *   - rowSpan: category 단독 + method+frequency 복합키 병합
 *   - measurement_type: checkbox→양호/불량, numeric→숫자입력, none→비활성
 * - 종합판정 (자동 계산, measurement_type='none' 제외)
 *
 * readonly=true  → 조회 모드
 * readonly=false → 편집 모드
 */

import { useState, useMemo, useCallback, useImperativeHandle, forwardRef } from 'react';
import { ConstructionApprovalTable } from '@/components/document-system';
import type {
  FqcTemplate,
  FqcDocumentData,
  FqcTemplateItem,
} from '../fqcActions';

// ===== Types =====

export interface FqcDocumentContentRef {
  /** 현재 입력 데이터를 document_data 형식으로 반환 */
  getInspectionData: () => {
    records: Array<{
      section_id: number | null;
      column_id: number | null;
      row_index: number;
      field_key: string;
      field_value: string | null;
    }>;
    overallJudgment: '합격' | '불합격' | null;
  };
}

interface FqcDocumentContentProps {
  /** 양식 정의 (template) */
  template: FqcTemplate;
  /** 기존 문서 데이터 (저장된 검사 결과) */
  documentData?: FqcDocumentData[];
  /** 문서번호 */
  documentNo?: string;
  /** 작성일자 */
  createdDate?: string;
  /** 기본필드 오버라이드 (API에서 auto-fill된 값) */
  basicFieldValues?: Record<string, string>;
  /** 읽기전용 모드 */
  readonly?: boolean;
}

type JudgmentValue = '적합' | '부적합' | null;

// ===== rowSpan 병합 유틸 =====

/** 단일 필드 기준 연속 rowSpan 계산 (category용) */
function buildFieldRowSpan(items: FqcTemplateItem[], field: 'category') {
  const spans = new Map<number, number>();
  const covered = new Set<number>();

  let i = 0;
  while (i < items.length) {
    const value = items[i][field];
    if (!value || value === '-') { i++; continue; }

    let span = 1;
    while (i + span < items.length && items[i + span][field] === value) {
      covered.add(i + span);
      span++;
    }
    if (span > 1) spans.set(i, span);
    i += span;
  }
  return { spans, covered };
}

/** 복합 키 기준 연속 rowSpan 계산 (method+frequency용) */
function buildCompositeRowSpan(items: FqcTemplateItem[]) {
  const spans = new Map<number, number>();
  const covered = new Set<number>();

  let i = 0;
  while (i < items.length) {
    const method = items[i].method || '';
    const freq = items[i].frequency || '';
    if (!method && !freq) { i++; continue; }

    const key = `${method}|${freq}`;
    let span = 1;
    while (i + span < items.length) {
      const nextMethod = items[i + span].method || '';
      const nextFreq = items[i + span].frequency || '';
      if (!nextMethod && !nextFreq) break;
      if (`${nextMethod}|${nextFreq}` !== key) break;
      covered.add(i + span);
      span++;
    }
    if (span > 1) spans.set(i, span);
    i += span;
  }
  return { spans, covered };
}

/** category별 그룹 번호 생성 */
function buildCategoryNumbers(items: FqcTemplateItem[]): Map<number, number> {
  const numbers = new Map<number, number>();
  let num = 0;
  let lastCategory = '';

  for (let i = 0; i < items.length; i++) {
    const cat = items[i].category;
    if (cat && cat !== '-' && cat !== lastCategory) {
      num++;
      lastCategory = cat;
    }
    numbers.set(i, num);
  }
  return numbers;
}

// ===== Component =====

export const FqcDocumentContent = forwardRef<FqcDocumentContentRef, FqcDocumentContentProps>(
  function FqcDocumentContent(
    {
      template,
      documentData = [],
      documentNo = '',
      createdDate = '',
      basicFieldValues = {},
      readonly = true,
    },
    ref
  ) {
    // 데이터 섹션 찾기 (items가 있는 섹션)
    const dataSection = useMemo(
      () => template.sections.find(s => s.items.length > 0),
      [template.sections]
    );

    const sectionItems = useMemo(
      () => dataSection?.items.sort((a, b) => a.sortOrder - b.sortOrder) ?? [],
      [dataSection]
    );

    // 컬럼 ID 찾기
    const judgmentColumnId = useMemo(
      () => template.columns.find(c => c.label === '판정')?.id ?? null,
      [template.columns]
    );
    const measurementColumnId = useMemo(
      () => template.columns.find(c => c.label === '측정값')?.id ?? null,
      [template.columns]
    );

    // rowSpan 계산
    const categoryCoverage = useMemo(() => buildFieldRowSpan(sectionItems, 'category'), [sectionItems]);
    const methodFreqCoverage = useMemo(() => buildCompositeRowSpan(sectionItems), [sectionItems]);
    const categoryNumbers = useMemo(() => buildCategoryNumbers(sectionItems), [sectionItems]);

    // 기존 문서 데이터에서 판정값 + 측정값 추출
    const initialJudgments = useMemo(() => {
      const map: Record<number, JudgmentValue> = {};
      if (!dataSection || !judgmentColumnId) return map;
      for (const d of documentData) {
        if (d.sectionId === dataSection.id && d.columnId === judgmentColumnId && d.fieldKey === 'result') {
          map[d.rowIndex] = (d.fieldValue as JudgmentValue) ?? null;
        }
      }
      return map;
    }, [documentData, dataSection, judgmentColumnId]);

    const initialMeasurements = useMemo(() => {
      const map: Record<number, string> = {};
      if (!dataSection || !measurementColumnId) return map;
      for (const d of documentData) {
        if (d.sectionId === dataSection.id && d.columnId === measurementColumnId && d.fieldKey === 'measured_value') {
          map[d.rowIndex] = d.fieldValue ?? '';
        }
      }
      return map;
    }, [documentData, dataSection, measurementColumnId]);

    // 상태 (편집 모드용)
    const [judgments, setJudgments] = useState<Record<number, JudgmentValue>>(initialJudgments);
    const [measurements, setMeasurements] = useState<Record<number, string>>(initialMeasurements);

    // 판정 토글
    const toggleJudgment = useCallback(
      (rowIndex: number, value: JudgmentValue) => {
        if (readonly) return;
        setJudgments(prev => ({
          ...prev,
          [rowIndex]: prev[rowIndex] === value ? null : value,
        }));
      },
      [readonly]
    );

    // 측정값 변경
    const updateMeasurement = useCallback(
      (rowIndex: number, value: string) => {
        if (readonly) return;
        setMeasurements(prev => ({ ...prev, [rowIndex]: value }));
      },
      [readonly]
    );

    // 종합판정 자동 계산 (measurement_type='none' 제외)
    const overallJudgment = useMemo(() => {
      if (!dataSection) return null;
      const activeItems = sectionItems.filter(item => item.measurementType !== 'none');
      if (activeItems.length === 0) return null;

      const activeIndices = sectionItems
        .map((item, idx) => item.measurementType !== 'none' ? idx : -1)
        .filter(idx => idx >= 0);

      const values = activeIndices.map(idx => judgments[idx]);
      const hasValue = values.some(v => v !== undefined && v !== null);
      if (!hasValue) return null;
      if (values.some(v => v === '부적합')) return '불합격' as const;
      if (values.every(v => v === '적합')) return '합격' as const;
      return null;
    }, [dataSection, sectionItems, judgments]);

    // ref를 통해 데이터 추출 (편집 모드에서 저장 시 사용)
    useImperativeHandle(ref, () => ({
      getInspectionData: () => {
        const records: Array<{
          section_id: number | null;
          column_id: number | null;
          row_index: number;
          field_key: string;
          field_value: string | null;
        }> = [];

        if (dataSection) {
          sectionItems.forEach((item, idx) => {
            // 판정
            if (judgmentColumnId && item.measurementType !== 'none') {
              const value = judgments[idx];
              if (value) {
                records.push({
                  section_id: dataSection.id,
                  column_id: judgmentColumnId,
                  row_index: idx,
                  field_key: 'result',
                  field_value: value,
                });
              }
            }
            // 측정값
            if (measurementColumnId && item.measurementType !== 'none') {
              const value = measurements[idx];
              if (value !== undefined && value !== '') {
                records.push({
                  section_id: dataSection.id,
                  column_id: measurementColumnId,
                  row_index: idx,
                  field_key: 'measured_value',
                  field_value: value,
                });
              }
            }
          });
        }

        // 종합판정
        records.push({
          section_id: null,
          column_id: null,
          row_index: 0,
          field_key: 'footer_judgement',
          field_value: overallJudgment,
        });

        return { records, overallJudgment };
      },
    }));

    // 결재라인 데이터 매핑
    const approvers = useMemo(() => {
      const lines = template.approvalLines.sort((a, b) => a.sortOrder - b.sortOrder);
      return {
        writer: lines[0] ? { name: lines[0].name, department: lines[0].department } : undefined,
        approver1: lines[1] ? { name: lines[1].name, department: lines[1].department } : undefined,
        approver2: lines[2] ? { name: lines[2].name, department: lines[2].department } : undefined,
      };
    }, [template.approvalLines]);

    // 기본필드 라벨-값 쌍
    const basicFieldPairs = useMemo(() => {
      const sorted = [...template.basicFields].sort((a, b) => a.sortOrder - b.sortOrder);
      const pairs: Array<{ label: string; value: string }> = [];
      for (const field of sorted) {
        const bfKey = `bf_${field.id}`;
        const legacyKey = `bf_${field.label}`;
        const value = basicFieldValues[bfKey]
          || documentData.find(d => d.fieldKey === bfKey && !d.sectionId)?.fieldValue
          || basicFieldValues[legacyKey]
          || documentData.find(d => d.fieldKey === legacyKey && !d.sectionId)?.fieldValue
          || field.defaultValue
          || '';
        pairs.push({ label: field.label, value });
      }
      return pairs;
    }, [template.basicFields, basicFieldValues, documentData]);

    // 이미지 섹션 (items가 없는 섹션)
    const imageSections = useMemo(
      () => template.sections.filter(s => s.items.length === 0 && s.imagePath),
      [template.sections]
    );

    return (
      <div className="bg-white p-8 min-h-full text-[11px]">
        {/* 헤더: 제목 (좌측) + 결재란 (우측) */}
        <div className="flex justify-between items-start mb-4">
          <div>
            <h1 className="text-2xl font-bold tracking-widest mb-2">
              {template.title || template.name || '제 품 검 사 성 적 서'}
            </h1>
            <div className="text-[10px] space-y-1">
              <div className="flex gap-4">
                <span>문서번호: <strong>{documentNo}</strong></span>
                <span>작성일자: <strong>{createdDate}</strong></span>
              </div>
            </div>
          </div>

          <ConstructionApprovalTable approvers={approvers} />
        </div>

        {/* 기본 정보 */}
        <div className="border border-gray-400 mb-4">
          <div className="bg-gray-200 text-center py-1 font-bold border-b border-gray-400">
            기본 정보
          </div>
          <table className="w-full">
            <tbody>
              {Array.from({ length: Math.ceil(basicFieldPairs.length / 2) }, (_, rowIdx) => {
                const left = basicFieldPairs[rowIdx * 2];
                const right = basicFieldPairs[rowIdx * 2 + 1];
                const isLast = rowIdx === Math.ceil(basicFieldPairs.length / 2) - 1;
                return (
                  <tr key={rowIdx} className={isLast ? '' : 'border-b border-gray-300'}>
                    {left && (
                      <>
                        <td className="bg-gray-100 px-2 py-1 w-28 font-medium border-r border-gray-300">
                          {left.label}
                        </td>
                        <td className="px-2 py-1 border-r border-gray-300">
                          {left.value || '-'}
                        </td>
                      </>
                    )}
                    {right ? (
                      <>
                        <td className="bg-gray-100 px-2 py-1 w-28 font-medium border-r border-gray-300">
                          {right.label}
                        </td>
                        <td className="px-2 py-1">{right.value || '-'}</td>
                      </>
                    ) : (
                      <td colSpan={2} />
                    )}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {/* 이미지 섹션 (검사 기준서 등) */}
        {imageSections.map(section => (
          <div key={section.id} className="border border-gray-400 mb-4">
            <div className="bg-gray-200 text-center py-1 font-bold border-b border-gray-400">
              {section.title || section.name}
            </div>
            <div className="p-4 flex items-center justify-center min-h-[100px]">
              {section.imagePath ? (
                <img
                  src={section.imagePath || ''}
                  alt={section.name}
                  className="max-h-[300px] max-w-full object-contain"
                />
              ) : (
                <div className="text-gray-400 text-center">
                  <div className="border-2 border-dashed border-gray-300 p-8 rounded">
                    이미지 없음
                  </div>
                </div>
              )}
            </div>
          </div>
        ))}

        {/* 검사항목 테이블 (8컬럼 시각 레이아웃) */}
        {dataSection && (
          <table className="w-full border-collapse border border-gray-400 mb-4">
            <thead>
              <tr className="bg-gray-100">
                <th className="border border-gray-400 px-2 py-1 w-10 text-center">No.</th>
                <th className="border border-gray-400 px-2 py-1 w-24">검사항목</th>
                <th className="border border-gray-400 px-2 py-1">세부항목</th>
                <th className="border border-gray-400 px-2 py-1">검사기준</th>
                <th className="border border-gray-400 px-2 py-1 w-16 text-center whitespace-pre-line">{'검사\n방법'}</th>
                <th className="border border-gray-400 px-2 py-1 w-16 text-center whitespace-pre-line">{'검사\n주기'}</th>
                <th className="border border-gray-400 px-2 py-1 w-16 text-center">측정값</th>
                <th className="border border-gray-400 px-2 py-1 w-28 text-center">판정</th>
              </tr>
            </thead>
            <tbody>
              {sectionItems.map((item, idx) => (
                <tr key={item.id} className="border-b border-gray-300">
                  {/* 1. No. — category 그룹 병합과 동일 */}
                  {!categoryCoverage.covered.has(idx) && (
                    <td
                      className="border border-gray-400 px-2 py-1 text-center align-middle font-medium"
                      rowSpan={categoryCoverage.spans.get(idx) || 1}
                    >
                      {categoryNumbers.get(idx)}
                    </td>
                  )}
                  {/* 2. 검사항목 — category 그룹 병합 */}
                  {!categoryCoverage.covered.has(idx) && (
                    <td
                      className="border border-gray-400 px-2 py-1 align-middle font-medium whitespace-pre-line"
                      rowSpan={categoryCoverage.spans.get(idx) || 1}
                    >
                      {item.category || '-'}
                    </td>
                  )}
                  {/* 3. 세부항목 */}
                  <td className="border border-gray-400 px-2 py-1 whitespace-pre-line">
                    {item.itemName === '-' ? '' : item.itemName}
                  </td>
                  {/* 4. 검사기준 */}
                  <td className="border border-gray-400 px-2 py-1 whitespace-pre-line">
                    {item.standard || '-'}
                  </td>
                  {/* 5. 검사방법 — method+frequency 복합키 병합 */}
                  {!methodFreqCoverage.covered.has(idx) && (
                    <td
                      className="border border-gray-400 px-2 py-1 text-center align-middle whitespace-pre-line"
                      rowSpan={methodFreqCoverage.spans.get(idx) || 1}
                    >
                      {item.method || ''}
                    </td>
                  )}
                  {/* 6. 검사주기 — method+frequency 복합키 병합 (동일 span) */}
                  {!methodFreqCoverage.covered.has(idx) && (
                    <td
                      className="border border-gray-400 px-2 py-1 text-center align-middle whitespace-pre-line"
                      rowSpan={methodFreqCoverage.spans.get(idx) || 1}
                    >
                      {item.frequency || ''}
                    </td>
                  )}
                  {/* 7. 측정값 */}
                  <td className="border border-gray-400 px-1 py-1 text-center align-middle">
                    <MeasurementCell
                      item={item}
                      rowIndex={idx}
                      value={measurements[idx] ?? ''}
                      judgment={judgments[idx] ?? null}
                      onChange={updateMeasurement}
                      onToggle={toggleJudgment}
                      readonly={readonly}
                      type="measurement"
                    />
                  </td>
                  {/* 8. 판정 */}
                  <td className="border border-gray-400 px-1 py-1 text-center align-middle">
                    <MeasurementCell
                      item={item}
                      rowIndex={idx}
                      value={measurements[idx] ?? ''}
                      judgment={judgments[idx] ?? null}
                      onChange={updateMeasurement}
                      onToggle={toggleJudgment}
                      readonly={readonly}
                      type="judgment"
                    />
                  </td>
                </tr>
              ))}

              {sectionItems.length === 0 && (
                <tr>
                  <td colSpan={8} className="border border-gray-400 px-2 py-4 text-center text-gray-400">
                    검사항목이 없습니다.
                  </td>
                </tr>
              )}

              {/* 종합판정 */}
              <tr>
                <td
                  className="border border-gray-400 bg-gray-100 px-2 py-2 font-bold text-center"
                  colSpan={7}
                >
                  종합판정
                </td>
                <td
                  className={`border border-gray-400 px-2 py-2 text-center font-bold text-sm ${
                    overallJudgment === '합격'
                      ? 'text-blue-600'
                      : overallJudgment === '불합격'
                        ? 'text-red-600'
                        : 'text-gray-400'
                  }`}
                >
                  {overallJudgment || '-'}
                </td>
              </tr>
            </tbody>
          </table>
        )}

        {/* 서명 영역 */}
        <div className="mt-8 text-center text-[10px]">
          <p>위 내용과 같이 제품검사 결과를 보고합니다.</p>
          <div className="mt-6">
            <p>{createdDate}</p>
          </div>
        </div>
      </div>
    );
  }
);

// ===== 측정값/판정 셀 =====

interface MeasurementCellProps {
  item: FqcTemplateItem;
  rowIndex: number;
  value: string;
  judgment: JudgmentValue;
  onChange: (rowIndex: number, value: string) => void;
  onToggle: (rowIndex: number, value: JudgmentValue) => void;
  readonly: boolean;
  type: 'measurement' | 'judgment';
}

function MeasurementCell({ item, rowIndex, value, judgment, onChange, onToggle, readonly, type }: MeasurementCellProps) {
  // none → 비활성
  if (item.measurementType === 'none') {
    return <span className="text-gray-300">-</span>;
  }

  if (type === 'measurement') {
    // checkbox → 양호/불량 텍스트
    if (item.measurementType === 'checkbox') {
      if (readonly) {
        return <span className="text-[10px]">{value || '-'}</span>;
      }
      return (
        <div className="flex items-center justify-center gap-1">
          <button
            type="button"
            onClick={() => onChange(rowIndex, value === '양호' ? '' : '양호')}
            className={`px-1 py-0.5 rounded text-[9px] border transition-colors ${
              value === '양호'
                ? 'bg-blue-600 text-white border-blue-600'
                : 'bg-white text-gray-500 border-gray-300 hover:border-blue-400'
            }`}
          >
            양호
          </button>
          <button
            type="button"
            onClick={() => onChange(rowIndex, value === '불량' ? '' : '불량')}
            className={`px-1 py-0.5 rounded text-[9px] border transition-colors ${
              value === '불량'
                ? 'bg-red-600 text-white border-red-600'
                : 'bg-white text-gray-500 border-gray-300 hover:border-red-400'
            }`}
          >
            불량
          </button>
        </div>
      );
    }

    // numeric → 숫자 입력
    if (item.measurementType === 'numeric') {
      if (readonly) {
        return <span className="text-[10px]">{value || '-'}</span>;
      }
      return (
        <input
          type="number"
          value={value}
          onChange={e => onChange(rowIndex, e.target.value)}
          className="w-full text-center text-[10px] border border-gray-300 rounded px-1 py-0.5 focus:outline-none focus:border-blue-400"
          placeholder="-"
        />
      );
    }

    return <span className="text-gray-300">-</span>;
  }

  // type === 'judgment'
  if (readonly) {
    return (
      <div className="flex items-center justify-center gap-1 text-[10px]">
        <span className={judgment === '적합' ? 'font-bold text-blue-600' : 'text-gray-400'}>
          {judgment === '적합' ? '■' : '□'} 적합
        </span>
        <span className={judgment === '부적합' ? 'font-bold text-red-600' : 'text-gray-400'}>
          {judgment === '부적합' ? '■' : '□'} 부적합
        </span>
      </div>
    );
  }

  return (
    <div className="flex items-center justify-center gap-1">
      <button
        type="button"
        onClick={() => onToggle(rowIndex, '적합')}
        className={`px-1.5 py-0.5 rounded text-[9px] border transition-colors ${
          judgment === '적합'
            ? 'bg-blue-600 text-white border-blue-600'
            : 'bg-white text-gray-500 border-gray-300 hover:border-blue-400'
        }`}
      >
        적합
      </button>
      <button
        type="button"
        onClick={() => onToggle(rowIndex, '부적합')}
        className={`px-1.5 py-0.5 rounded text-[9px] border transition-colors ${
          judgment === '부적합'
            ? 'bg-red-600 text-white border-red-600'
            : 'bg-white text-gray-500 border-gray-300 hover:border-red-400'
        }`}
      >
        부적합
      </button>
    </div>
  );
}