// PDF 텍스트 패턴 기반 자동 서명 필드 생성 시스템

interface SignaturePattern {
    regex: RegExp;
    name: string;
    priority: number;
    offsetX?: number;  // 텍스트로부터 X축 오프셋
    offsetY?: number;  // 텍스트로부터 Y축 오프셋
    width?: number;    // 서명 필드 너비
    height?: number;   // 서명 필드 높이
  }
  
  interface DetectedSignatureLocation {
    pageIndex: number;
    text: string;
    rect: {
      x1: number;
      y1: number;
      x2: number;
      y2: number;
    };
    pattern: SignaturePattern;
    confidence: number;
  }
  
  class AutoSignatureFieldDetector {
    private instance: WebViewerInstance;
    private signaturePatterns: SignaturePattern[];
  
    constructor(instance: WebViewerInstance) {
      this.instance = instance;
      this.signaturePatterns = this.initializePatterns();
    }
  
    private initializePatterns(): SignaturePattern[] {
      return [
        // 한국어 패턴들 (우선순위 높음)
        {
          regex: /서명\s*[:：]\s*[_\-\s]{3,}/gi,
          name: "한국어_서명_콜론",
          priority: 10,
          offsetX: 80,   // "서명:" 텍스트 오른쪽으로 80px
          offsetY: -5,   // 약간 위로
          width: 150,
          height: 40
        },
        {
          regex: /서명란\s*[_\-\s]{0,}/gi,
          name: "한국어_서명란",
          priority: 9,
          offsetX: 60,
          offsetY: -5,
          width: 150,
          height: 40
        },
        {
          regex: /서명\s*[_\-\s]{5,}/gi,
          name: "한국어_서명_라인",
          priority: 8,
          offsetX: 50,
          offsetY: -5,
          width: 150,
          height: 40
        },
        {
          regex: /(계약자|갑|을)\s*서명\s*[:：]?\s*[_\-\s]{0,}/gi,
          name: "한국어_계약자_서명",
          priority: 9,
          offsetX: 100,
          offsetY: -5,
          width: 150,
          height: 40
        },
        
        // 영어 패턴들
        {
          regex: /signature\s*[:：]\s*[_\-\s]{3,}/gi,
          name: "영어_signature_콜론",
          priority: 8,
          offsetX: 120,
          offsetY: -5,
          width: 150,
          height: 40
        },
        {
          regex: /sign\s+here\s*[:：]?\s*[_\-\s]{0,}/gi,
          name: "영어_sign_here",
          priority: 9,
          offsetX: 100,
          offsetY: -5,
          width: 150,
          height: 40
        },
        {
          regex: /sign\s*[:：]\s*[_\-\s]{3,}/gi,
          name: "영어_sign_콜론",
          priority: 7,
          offsetX: 60,
          offsetY: -5,
          width: 150,
          height: 40
        },
  
        // 날짜와 함께 나오는 패턴들
        {
          regex: /날짜\s*[:：]\s*[_\-\s]{3,}.*?서명\s*[:：]\s*[_\-\s]{3,}/gi,
          name: "날짜_서명_조합",
          priority: 10,
          offsetX: 0,
          offsetY: -5,
          width: 150,
          height: 40
        },
        {
          regex: /date\s*[:：]\s*[_\-\s]{3,}.*?signature\s*[:：]\s*[_\-\s]{3,}/gi,
          name: "date_signature_조합",
          priority: 10,
          offsetX: 0,
          offsetY: -5,
          width: 150,
          height: 40
        },
  
        // 일반적인 양식 패턴들
        {
          regex: /이름\s*[:：]\s*[_\-\s]{5,}.*?서명\s*[:：]\s*[_\-\s]{5,}/gi,
          name: "이름_서명_조합",
          priority: 8,
          offsetX: 0,
          offsetY: -5,
          width: 150,
          height: 40
        },
        {
          regex: /name\s*[:：]\s*[_\-\s]{5,}.*?signature\s*[:：]\s*[_\-\s]{5,}/gi,
          name: "name_signature_조합",
          priority: 8,
          offsetX: 0,
          offsetY: -5,
          width: 150,
          height: 40
        }
      ];
    }
  
    // 📄 메인 함수: 문서에서 서명 패턴 감지 및 필드 생성
    async detectAndCreateSignatureFields(): Promise<string[]> {
      console.log("🔍 자동 서명 필드 감지 시작...");
      
      try {
        const { Core } = this.instance;
        const { documentViewer } = Core;
        
        await Core.PDFNet.initialize();
        const doc = await documentViewer.getDocument().getPDFDoc();
        
        // 1. 기존 서명 필드 확인
        const existingFields = await this.getExistingSignatureFields(doc);
        console.log(`📊 기존 서명 필드: ${existingFields.length}개`);
        
        if (existingFields.length > 0) {
          console.log("✅ 기존 서명 필드가 있으므로 자동 생성 스킵");
          return existingFields.map(f => f.name);
        }
  
        // 2. 텍스트 패턴 기반 서명 위치 감지
        const detectedLocations = await this.detectSignatureLocations(doc);
        console.log(`🎯 감지된 서명 위치: ${detectedLocations.length}개`);
  
        // 3. 감지된 위치에 서명 필드 생성
        const createdFields: string[] = [];
        for (const location of detectedLocations) {
          try {
            const fieldName = await this.createSignatureFieldAtLocation(doc, location);
            createdFields.push(fieldName);
            console.log(`✅ 서명 필드 생성: ${fieldName}`);
          } catch (error) {
            console.error(`📛 서명 필드 생성 실패:`, error);
          }
        }
  
        // 4. 문서 업데이트
        if (createdFields.length > 0) {
          await documentViewer.refreshAll();
          await documentViewer.updateView();
          console.log(`🎉 총 ${createdFields.length}개 서명 필드 자동 생성 완료`);
        } else {
          console.warn("⚠️ 서명 패턴을 찾지 못했습니다. 기본 서명 필드 생성...");
          const defaultField = await this.createDefaultSignatureField(doc);
          createdFields.push(defaultField);
        }
  
        return createdFields;
  
      } catch (error) {
        console.error("📛 자동 서명 필드 생성 실패:", error);
        return [];
      }
    }
  
    // 기존 서명 필드 확인
    private async getExistingSignatureFields(doc: any): Promise<any[]> {
      const { Core } = this.instance;
      const fields = [];
  
      try {
        const pageCount = await doc.getPageCount();
        
        for (let i = 1; i <= pageCount; i++) {
          const page = await doc.getPage(i);
          const numAnnots = await page.getNumAnnots();
          
          for (let j = 0; j < numAnnots; j++) {
            const annot = await page.getAnnot(j);
            const annotType = await annot.getType();
            
            if (annotType === Core.PDFNet.Annot.Type.e_Widget) {
              const widget = await Core.PDFNet.WidgetAnnot.cast(annot);
              const field = await widget.getField();
              const fieldType = await field.getType();
              
              if (fieldType === Core.PDFNet.Field.Type.e_signature) {
                const fieldName = await field.getName();
                fields.push({ name: fieldName, widget, page: i });
              }
            }
          }
        }
      } catch (error) {
        console.warn("기존 필드 확인 중 에러:", error);
      }
  
      return fields;
    }
  
    // 텍스트 패턴 기반 서명 위치 감지
    private async detectSignatureLocations(doc: any): Promise<DetectedSignatureLocation[]> {
      const { Core } = this.instance;
      const detectedLocations: DetectedSignatureLocation[] = [];
  
      try {
        const pageCount = await doc.getPageCount();
        
        for (let pageNum = 1; pageNum <= pageCount; pageNum++) {
          const page = await doc.getPage(pageNum);
          
          // 텍스트 추출
          const textExtractor = await Core.PDFNet.TextExtractor.create();
          await textExtractor.begin(page);
          
          // 텍스트와 위치 정보 추출
          const wordList = [];
          let line = await textExtractor.getFirstLine();
          
          while (line) {
            let word = await line.getFirstWord();
            while (word) {
              const wordText = await word.getString();
              const wordBox = await word.getBBox();
              
              wordList.push({
                text: wordText,
                x1: await wordBox.getX1(),
                y1: await wordBox.getY1(),
                x2: await wordBox.getX2(),
                y2: await wordBox.getY2()
              });
              
              word = await word.getNext();
            }
            line = await line.getNext();
          }
  
          // 전체 페이지 텍스트 조합
          const fullText = wordList.map(w => w.text).join(' ');
          
          // 패턴 매칭
          for (const pattern of this.signaturePatterns) {
            const matches = Array.from(fullText.matchAll(pattern.regex));
            
            for (const match of matches) {
              // 매치된 텍스트의 위치 찾기
              const matchText = match[0];
              const matchStart = match.index || 0;
              
              // 대략적인 위치 계산 (개선 가능)
              const location = this.calculateTextLocation(wordList, matchStart, matchText.length);
              
              if (location) {
                detectedLocations.push({
                  pageIndex: pageNum - 1,
                  text: matchText,
                  rect: {
                    x1: location.x1 + (pattern.offsetX || 0),
                    y1: location.y1 + (pattern.offsetY || 0),
                    x2: location.x1 + (pattern.offsetX || 0) + (pattern.width || 150),
                    y2: location.y1 + (pattern.offsetY || 0) + (pattern.height || 40)
                  },
                  pattern: pattern,
                  confidence: pattern.priority
                });
                
                console.log(`🎯 패턴 매치: "${matchText}" (${pattern.name}) 페이지 ${pageNum}`);
              }
            }
          }
        }
        
        // 신뢰도 순으로 정렬 (중복 제거 포함)
        return this.deduplicateAndSort(detectedLocations);
        
      } catch (error) {
        console.error("텍스트 패턴 감지 실패:", error);
        return [];
      }
    }
  
    // 텍스트 위치 계산 (개선된 버전)
    private calculateTextLocation(wordList: any[], startIndex: number, length: number): any {
      if (wordList.length === 0) return null;
      
      // 간단한 구현: 첫 번째 단어의 위치 사용
      // 실제로는 더 정교한 텍스트 매칭 필요
      const totalChars = wordList.map(w => w.text).join(' ').length;
      const ratio = startIndex / totalChars;
      const targetWordIndex = Math.floor(ratio * wordList.length);
      
      const targetWord = wordList[Math.min(targetWordIndex, wordList.length - 1)];
      return targetWord;
    }
  
    // 중복 제거 및 정렬
    private deduplicateAndSort(locations: DetectedSignatureLocation[]): DetectedSignatureLocation[] {
      // 같은 페이지의 너무 가까운 위치들 제거
      const filtered = locations.filter((loc, index) => {
        return !locations.slice(0, index).some(prevLoc => 
          prevLoc.pageIndex === loc.pageIndex &&
          Math.abs(prevLoc.rect.x1 - loc.rect.x1) < 100 &&
          Math.abs(prevLoc.rect.y1 - loc.rect.y1) < 50
        );
      });
  
      // 신뢰도(우선순위) 순으로 정렬
      return filtered.sort((a, b) => b.confidence - a.confidence);
    }
  
    // 감지된 위치에 서명 필드 생성
    private async createSignatureFieldAtLocation(doc: any, location: DetectedSignatureLocation): Promise<string> {
      const { Core } = this.instance;
      
      const fieldName = `auto_signature_${location.pageIndex + 1}_${Date.now()}`;
      const page = await doc.getPage(location.pageIndex + 1);
      
      // 디지털 서명 필드 생성
      const sigField = await doc.createDigitalSignatureField(fieldName);
      
      // 서명 위젯 생성
      const rect = await Core.PDFNet.Rect.init(
        location.rect.x1,
        location.rect.y1,
        location.rect.x2,
        location.rect.y2
      );
      
      const widget = await Core.PDFNet.SignatureWidget.createWithDigitalSignatureField(
        doc, rect, sigField
      );
      
      // 위젯 스타일 설정
      await widget.setBackgroundColor(
        await Core.PDFNet.ColorPt.init(0.95, 0.95, 1.0), // 연한 파란색
        3 // RGB
      );
      
      await widget.setBorderColor(
        await Core.PDFNet.ColorPt.init(0.2, 0.4, 0.8), // 파란색 테두리
        3 // RGB
      );
  
      // 페이지에 위젯 추가
      await page.annotPushBack(widget);
      
      console.log(`✅ 자동 서명 필드 생성: ${fieldName} (패턴: ${location.pattern.name})`);
      return fieldName;
    }
  
    // 기본 서명 필드 생성 (패턴을 찾지 못한 경우)
    private async createDefaultSignatureField(doc: any): Promise<string> {
      const { Core } = this.instance;
      
      console.log("⚠️ 서명 패턴 미발견, 기본 위치에 서명 필드 생성");
      
      const pageCount = await doc.getPageCount();
      const lastPage = await doc.getPage(pageCount);
      const pageInfo = await lastPage.getPageInfo();
      const pageWidth = await pageInfo.getWidth();
      const pageHeight = await pageInfo.getHeight();
      
      const fieldName = `default_signature_${Date.now()}`;
      const sigField = await doc.createDigitalSignatureField(fieldName);
      
      // 마지막 페이지 하단 중앙에 배치
      const rect = await Core.PDFNet.Rect.init(
        pageWidth * 0.3,   // 페이지 너비 30% 지점
        pageHeight * 0.1,  // 페이지 하단 10% 지점
        pageWidth * 0.7,   // 페이지 너비 70% 지점
        pageHeight * 0.2   // 페이지 하단 20% 지점
      );
      
      const widget = await Core.PDFNet.SignatureWidget.createWithDigitalSignatureField(
        doc, rect, sigField
      );
      
      await widget.setBackgroundColor(
        await Core.PDFNet.ColorPt.init(1.0, 0.95, 0.95), // 연한 핑크색 (주의 표시)
        3
      );
      
      await widget.setBorderColor(
        await Core.PDFNet.ColorPt.init(0.8, 0.2, 0.2), // 빨간색 테두리
        3
      );
      
      await lastPage.annotPushBack(widget);
      
      return fieldName;
    }
  }
  
  // ✅ BasicContractSignViewer에 통합할 수 있는 함수
  export async function addAutoSignatureFieldsToDocument(instance: WebViewerInstance): Promise<string[]> {
    if (!instance) {
      console.warn("⚠️ WebViewer 인스턴스가 없습니다.");
      return [];
    }
  
    try {
      const detector = new AutoSignatureFieldDetector(instance);
      const createdFields = await detector.detectAndCreateSignatureFields();
      
      if (createdFields.length > 0) {
        console.log(`🎉 자동 서명 필드 생성 완료: ${createdFields.join(', ')}`);
      }
      
      return createdFields;
      
    } catch (error) {
      console.error("📛 자동 서명 필드 추가 실패:", error);
      return [];
    }
  }
  
  // ✅ 문서 로드 후 자동 호출되는 Hook
  export function useAutoSignatureFields(instance: WebViewerInstance | null) {
    const [signatureFields, setSignatureFields] = React.useState<string[]>([]);
    const [isProcessing, setIsProcessing] = React.useState(false);
  
    React.useEffect(() => {
      if (!instance) return;
  
      const { documentViewer } = instance.Core;
      
      const handleDocumentLoaded = async () => {
        try {
          setIsProcessing(true);
          console.log("📄 문서 로드 완료, 자동 서명 필드 생성 시작...");
          
          // 문서 로드 후 잠시 대기 (안정성을 위해)
          await new Promise(resolve => setTimeout(resolve, 1000));
          
          const fields = await addAutoSignatureFieldsToDocument(instance);
          setSignatureFields(fields);
          
        } catch (error) {
          console.error("📛 자동 서명 필드 처리 실패:", error);
        } finally {
          setIsProcessing(false);
        }
      };
  
      documentViewer.addEventListener('documentLoaded', handleDocumentLoaded);
  
      return () => {
        documentViewer.removeEventListener('documentLoaded', handleDocumentLoaded);
      };
    }, [instance]);
  
    return {
      signatureFields,
      isProcessing,
      hasSignatureFields: signatureFields.length > 0
    };
  }