"use client";

import * as React from "react";
import { Button } from "@/components/ui/button";
import { toast } from "sonner";
import { 
  Save, 
  RefreshCw, 
  Type, 
  FileText, 
  AlertCircle, 
  Copy, 
  Download, 
  Settings,
  ChevronDown,
  ChevronUp 
} from "lucide-react";
import type { WebViewerInstance } from "@pdftron/webviewer";
import { Badge } from "@/components/ui/badge";
import { 
  Tooltip, 
  TooltipContent, 
  TooltipProvider, 
  TooltipTrigger 
} from "@/components/ui/tooltip";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { 
  getProjectDocTemplateById, 
  updateProjectDocTemplate,
  type DocTemplateVariable 
} from "@/lib/project-doc-templates/service";
import type { ProjectDocTemplate } from "@/db/schema/project-doc-templates";
import { BasicContractTemplateViewer } from "@/lib/basic-contract/template/basic-contract-template-viewer";
import { v4 as uuidv4 } from 'uuid';
import { Progress } from "@/components/ui/progress";

interface ProjectDocTemplateEditorProps {
  templateId: string | number;
  filePath: string;
  fileName: string;
  refreshAction?: () => Promise<void>;
  mode?: "view" | "edit";
}

// 변수별 한글 설명 매핑은 기존과 동일
const VARIABLE_DESCRIPTION_MAP: Record<string, string> = {
  "document_number": "문서번호",
  "project_code": "프로젝트 코드",
  "project_name": "프로젝트명",
  "created_date": "작성일",
  "author_name": "작성자",
  "department": "부서명",
  "company_name": "회사명",
  "company_address": "회사주소",
  "representative_name": "대표자명",
  "signature_date": "서명날짜",
  "today_date": "오늘날짜",
  "tax_id": "사업자등록번호",
  "phone_number": "전화번호",
  "email": "이메일",
};

const VARIABLE_PATTERN = /\{\{([^}]+)\}\}/g;

export function ProjectDocTemplateEditor({
  templateId,
  filePath,
  fileName,
  refreshAction,
  mode = "edit",
}: ProjectDocTemplateEditorProps) {
  const [instance, setInstance] = React.useState<WebViewerInstance | null>(null);
  const [isSaving, setIsSaving] = React.useState(false);
  const [documentVariables, setDocumentVariables] = React.useState<string[]>([]);
  const [templateInfo, setTemplateInfo] = React.useState<ProjectDocTemplate | null>(null);
  const [predefinedVariables, setPredefinedVariables] = React.useState<DocTemplateVariable[]>([]);
  const [isVariablePanelOpen, setIsVariablePanelOpen] = React.useState(false); // 변수 패널 접기/펴기 상태
  const [uploadProgress, setUploadProgress] = React.useState(0);
  const [showProgress, setShowProgress] = React.useState(false);

  // 템플릿 정보 로드
  React.useEffect(() => {
    const loadTemplateInfo = async () => {
      try {
        const data = await getProjectDocTemplateById(Number(templateId));
        setTemplateInfo(data as ProjectDocTemplate);
        setPredefinedVariables(data.variables || []);
        
        console.log("📋 템플릿 정보:", data);
        console.log("📝 정의된 변수들:", data.variables);
      } catch (error) {
        console.error("템플릿 정보 로드 오류:", error);
        toast.error("템플릿 정보를 불러오는데 실패했습니다.");
      }
    };

    if (templateId) {
      loadTemplateInfo();
    }
  }, [templateId]);

  // 문서에서 변수 추출 - 기존과 동일
  const extractVariablesFromDocument = async () => {
    if (!instance) return;

    try {
      const { documentViewer } = instance.Core;
      const doc = documentViewer.getDocument();
      
      if (!doc) return;

      const textContent = await doc.getDocumentCompletePromise().then(async () => {
        const pageCount = doc.getPageCount();
        let fullText = "";
        
        for (let i = 1; i <= pageCount; i++) {
          try {
            const pageText = await doc.loadPageText(i);
            fullText += pageText + " ";
          } catch (error) {
            console.warn(`페이지 ${i} 텍스트 추출 실패:`, error);
          }
        }
        
        return fullText;
      });

      const matches = textContent.match(VARIABLE_PATTERN);
      const variables = matches 
        ? [...new Set(matches.map(match => match.replace(/[{}]/g, '')))]
        : [];

      setDocumentVariables(variables);
      
      if (variables.length > 0) {
        console.log("🔍 문서에서 발견된 변수들:", variables);
        
        const undefinedVars = variables.filter(
          v => !predefinedVariables.find(pv => pv.name === v)
        );
        
        if (undefinedVars.length > 0) {
          toast.warning(
            `정의되지 않은 변수가 발견되었습니다: ${undefinedVars.join(", ")}`,
            { duration: 5000 }
          );
        }
      }
      
    } catch (error) {
      console.error("변수 추출 중 오류:", error);
    }
  };

  // 청크 업로드 함수
  const CHUNK_SIZE = 1 * 1024 * 1024; // 1MB

  const uploadFileInChunks = async (file: Blob, fileName: string, fileId: string) => {
    const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
    setShowProgress(true);
    setUploadProgress(0);

    for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
      const start = chunkIndex * CHUNK_SIZE;
      const end = Math.min(start + CHUNK_SIZE, file.size);
      const chunk = file.slice(start, end);

      const formData = new FormData();
      formData.append('chunk', chunk);
      formData.append('filename', fileName);
      formData.append('chunkIndex', chunkIndex.toString());
      formData.append('totalChunks', totalChunks.toString());
      formData.append('fileId', fileId);

      const response = await fetch('/api/upload/project-doc-template/chunk', {
        method: 'POST',
        body: formData,
      });

      if (!response.ok) {
        throw new Error(`청크 업로드 실패: ${response.statusText}`);
      }

      const progress = Math.round(((chunkIndex + 1) / totalChunks) * 100);
      setUploadProgress(progress);

      const result = await response.json();
      if (chunkIndex === totalChunks - 1) {
        return result;
      }
    }
  };

  // 문서 저장 - 개선된 버전
  const handleSave = async () => {
    if (!instance || mode === "view") {
      toast.error(mode === "view" ? "읽기 전용 모드입니다." : "뷰어가 준비되지 않았습니다.");
      return;
    }

    setIsSaving(true);
    try {
      const { documentViewer } = instance.Core;
      const doc = documentViewer.getDocument();

      if (!doc) {
        throw new Error("문서를 찾을 수 없습니다.");
      }

      // Word 문서 데이터 추출
      const data = await doc.getFileData({
        downloadType: "office",
        includeAnnotations: true
      });

      // Blob 생성
      const fileBlob = new Blob([data], { 
        type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' 
      });

      // 파일 업로드 (청크 방식)
      const fileId = `template_${templateId}_${Date.now()}`;
      const uploadResult = await uploadFileInChunks(fileBlob, fileName, fileId);

      if (!uploadResult?.success) {
        throw new Error("파일 업로드에 실패했습니다.");
      }

      // 서버에 파일 경로 업데이트
      const updateResult = await updateProjectDocTemplate(Number(templateId), {
        filePath: uploadResult.filePath,
        fileName: uploadResult.fileName,
        fileSize: uploadResult.fileSize,
        variables: documentVariables.length > 0 ? 
          documentVariables.map(varName => {
            const existing = predefinedVariables.find(v => v.name === varName);
            return existing || {
              name: varName,
              displayName: VARIABLE_DESCRIPTION_MAP[varName] || varName,
              type: "text" as const,
              required: false,
              description: ""
            };
          }) : predefinedVariables
      });

      if (!updateResult.success) {
        throw new Error(updateResult.error || "템플릿 업데이트에 실패했습니다.");
      }

      toast.success("템플릿이 성공적으로 저장되었습니다.");
      
      // 변수 재추출
      await extractVariablesFromDocument();
      
      // 페이지 새로고침
      if (refreshAction) {
        await refreshAction();
      }

    } catch (error) {
      console.error("저장 오류:", error);
      toast.error(error instanceof Error ? error.message : "저장 중 오류가 발생했습니다.");
    } finally {
      setIsSaving(false);
      setShowProgress(false);
      setUploadProgress(0);
    }
  };

  // 나머지 함수들은 기존과 동일
  React.useEffect(() => {
    if (instance) {
      const { documentViewer } = instance.Core;
      
      const onDocumentLoaded = () => {
        setTimeout(() => extractVariablesFromDocument(), 1000);
      };

      documentViewer.addEventListener("documentLoaded", onDocumentLoaded);
      
      return () => {
        documentViewer.removeEventListener("documentLoaded", onDocumentLoaded);
      };
    }
  }, [instance, predefinedVariables]);

  const insertVariable = async (variable: DocTemplateVariable) => {
    if (!instance) {
      toast.error("뷰어가 준비되지 않았습니다.");
      return;
    }
  
    const textToInsert = `{{${variable.name}}}`; // variable.name으로 수정
    
    try {
      // textarea를 보이는 위치에 잠시 생성
      const tempTextArea = document.createElement('textarea');
      tempTextArea.value = textToInsert;
      tempTextArea.style.position = 'fixed';
      tempTextArea.style.top = '20px';
      tempTextArea.style.left = '20px';
      tempTextArea.style.width = '200px';
      tempTextArea.style.height = '30px';
      tempTextArea.style.fontSize = '12px';
      tempTextArea.style.zIndex = '10000';
      tempTextArea.style.opacity = '0.01'; // 거의 투명하게
      
      document.body.appendChild(tempTextArea);
      
      // 포커스와 선택을 확실하게
      tempTextArea.focus();
      tempTextArea.select();
      tempTextArea.setSelectionRange(0, tempTextArea.value.length); // 전체 선택 보장
      
      let successful = false;
      try {
        successful = document.execCommand('copy');
        console.log('복사 시도 결과:', successful, '복사된 텍스트:', textToInsert);
      } catch (err) {
        console.error('execCommand 실패:', err);
      }
      
      // 잠시 후 제거 (즉시 제거하면 복사가 안될 수 있음)
      setTimeout(() => {
        document.body.removeChild(tempTextArea);
      }, 100);
      
      if (successful) {
        toast.success(
          <div>
            <p className="font-medium">{variable.displayName} 변수가 복사되었습니다.</p>
            <code className="bg-gray-100 px-1 rounded text-xs">{textToInsert}</code>
            <p className="text-sm text-muted-foreground mt-1">
              문서에서 원하는 위치에 Ctrl+V로 붙여넣기 하세요.
            </p>
          </div>,
          { duration: 3000 }
        );
        
        // 복사 확인용 - 개발 중에만 사용
        if (process.env.NODE_ENV === 'development') {
          navigator.clipboard.readText().then(text => {
            console.log('클립보드 내용:', text);
          }).catch(err => {
            console.log('클립보드 읽기 실패:', err);
          });
        }
      } else {
        // 복사 실패 시 대안 제공
        const fallbackInput = document.createElement('input');
        fallbackInput.value = textToInsert;
        fallbackInput.style.position = 'fixed';
        fallbackInput.style.top = '50%';
        fallbackInput.style.left = '50%';
        fallbackInput.style.transform = 'translate(-50%, -50%)';
        fallbackInput.style.zIndex = '10001';
        fallbackInput.style.padding = '8px';
        fallbackInput.style.border = '2px solid #3b82f6';
        fallbackInput.style.borderRadius = '4px';
        fallbackInput.style.backgroundColor = 'white';
        
        document.body.appendChild(fallbackInput);
        fallbackInput.select();
        
        toast.error(
          <div>
            <p className="font-medium">자동 복사 실패</p>
            <p className="text-sm">표시된 텍스트를 Ctrl+C로 복사하세요.</p>
          </div>,
          {
            duration: 5000,
            onDismiss: () => {
              if (document.body.contains(fallbackInput)) {
                document.body.removeChild(fallbackInput);
              }
            }
          }
        );
      }
      
    } catch (error) {
      console.error("변수 삽입 오류:", error);
      toast.error("변수 삽입 중 오류가 발생했습니다.");
    }
  };

  const handleDownload = async () => {
    try {
      const response = await fetch(filePath);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.style.display = 'none';
      a.href = url;
      a.download = fileName;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      toast.success("파일이 다운로드되었습니다.");
    } catch (error) {
      console.error("다운로드 오류:", error);
      toast.error("파일 다운로드 중 오류가 발생했습니다.");
    }
  };

  const handleRefresh = () => {
    window.location.reload();
  };

  const isReadOnly = mode === "view";

  return (
    <div className="h-full flex flex-col">
      {/* 상단 도구 모음 */}
      <div className="border-b bg-gray-50 p-3">
        <div className="flex items-center justify-between">
          <div className="flex items-center space-x-2">
            {!isReadOnly && (
              <Button
                variant="outline"
                size="sm"
                onClick={handleSave}
                disabled={isSaving || !instance}
              >
                {isSaving ? (
                  <>
                    <RefreshCw className="mr-2 h-4 w-4 animate-spin" />
                    저장 중...
                  </>
                ) : (
                  <>
                    <Save className="mr-2 h-4 w-4" />
                    저장
                  </>
                )}
              </Button>
            )}
            
            <Button
              variant="outline"
              size="sm"
              onClick={handleDownload}
            >
              <Download className="mr-2 h-4 w-4" />
              다운로드
            </Button>
            
            <Button
              variant="outline"
              size="sm"
              onClick={handleRefresh}
            >
              <RefreshCw className="mr-2 h-4 w-4" />
              새로고침
            </Button>
          </div>

          <div className="flex items-center space-x-2">
            {templateInfo?.projectCode && (
              <Badge variant="outline">
                <FileText className="mr-1 h-3 w-3" />
                {templateInfo.projectCode}
              </Badge>
            )}
            <Badge variant="secondary">
              {fileName}
            </Badge>
            {documentVariables.length > 0 && (
              <Badge variant="secondary">
                <Type className="mr-1 h-3 w-3" />
                변수 {documentVariables.length}개
              </Badge>
            )}
          </div>
        </div>


        {/* 변수 도구 - Collapsible로 변경 */}
        {(predefinedVariables.length > 0 || documentVariables.length > 0) && (
          <Collapsible 
            open={isVariablePanelOpen} 
            onOpenChange={setIsVariablePanelOpen}
            className="mt-3"
          >
            <Card>
              <CardHeader className="pb-3">
                <div className="flex items-center justify-between">
                  <CardTitle className="text-sm flex items-center">
                    <Type className="mr-2 h-4 w-4 text-blue-500" />
                    템플릿 변수 관리
                    {documentVariables.length > 0 && (
                      <Badge variant="secondary" className="ml-2">
                        {documentVariables.length}개
                      </Badge>
                    )}
                  </CardTitle>
                  <CollapsibleTrigger asChild>
                    <Button variant="ghost" size="sm">
                      {isVariablePanelOpen ? (
                        <>
                          <ChevronUp className="h-4 w-4 mr-1" />
                          접기
                        </>
                      ) : (
                        <>
                          <ChevronDown className="h-4 w-4 mr-1" />
                          펼치기
                        </>
                      )}
                    </Button>
                  </CollapsibleTrigger>
                </div>
              </CardHeader>
              
              <CollapsibleContent>
                <CardContent className="space-y-3">
                  {/* 정의된 변수들 */}
                  {predefinedVariables.length > 0 && (
                    <div>
                      <p className="text-xs text-muted-foreground mb-2">정의된 템플릿 변수 (클릭하여 복사):</p>
                      <TooltipProvider>
                        <div className="flex flex-wrap gap-1">
                          {predefinedVariables.map((variable, index) => (
                            <Tooltip key={index}>
                              <TooltipTrigger asChild>
                                <Button
                                  variant="ghost"
                                  size="sm"
                                  className="h-7 px-2 text-xs hover:bg-blue-50"
                                  onClick={() => !isReadOnly && insertVariable(variable)}
                                  disabled={isReadOnly}
                                >
                                  <span className="font-mono">
                                    {`{{${variable.name}}}`}
                                  </span>
                                  {variable.required && (
                                    <span className="ml-1 text-red-500">*</span>
                                  )}
                                </Button>
                              </TooltipTrigger>
                              <TooltipContent>
                                <div className="space-y-1">
                                  <p className="font-medium">{variable.displayName}</p>
                                  {variable.description && (
                                    <p className="text-xs">{variable.description}</p>
                                  )}
                                  {variable.defaultValue && (
                                    <p className="text-xs">기본값: {variable.defaultValue}</p>
                                  )}
                                  <p className="text-xs text-muted-foreground">
                                    타입: {variable.type} {variable.required && "(필수)"}
                                  </p>
                                </div>
                              </TooltipContent>
                            </Tooltip>
                          ))}
                        </div>
                      </TooltipProvider>
                    </div>
                  )}

                  {/* 문서에서 발견된 변수들 */}
                  {documentVariables.length > 0 && (
                    <div>
                      <p className="text-xs text-muted-foreground mb-2">문서에서 발견된 변수:</p>
                      <div className="flex flex-wrap gap-1">
                        {documentVariables.map((variable, index) => {
                          const isDefined = predefinedVariables.find(v => v.name === variable);
                          return (
                            <Badge 
                              key={index} 
                              variant={isDefined ? "secondary" : "destructive"}
                              className="text-xs"
                            >
                              {`{{${variable}}}`}
                              {!isDefined && (
                                <AlertCircle className="ml-1 h-3 w-3" />
                              )}
                            </Badge>
                          );
                        })}
                      </div>
                    </div>
                  )}

                  {/* 변수 사용 안내 */}
                  <div className="mt-3 p-2 bg-blue-50 rounded-lg">
                    <div className="flex items-start">
                      <AlertCircle className="h-4 w-4 text-blue-600 mt-0.5 mr-2 flex-shrink-0" />
                      <div className="text-xs text-blue-900 space-y-1">
                        <p className="font-medium">변수 사용 안내</p>
                        <ul className="list-disc list-inside space-y-0.5">
                          <li>{'{{변수명}}'} 형식으로 문서에 변수를 삽입하세요.</li>
                          <li>필수 변수(*)는 반드시 값이 입력되어야 합니다.</li>
                          <li>한글 입력 제한 시 외부 에디터에서 작성 후 붙여넣기 하세요.</li>
                        </ul>
                      </div>
                    </div>
                  </div>
                </CardContent>
              </CollapsibleContent>
            </Card>
          </Collapsible>
        )}

        {/* 업로드 진행률 */}
        {showProgress && (
          <div className="mt-3 p-3 bg-white rounded border">
            <div className="space-y-2">
              <div className="flex justify-between text-sm">
                <span>저장 진행률</span>
                <span>{uploadProgress}%</span>
              </div>
              <Progress value={uploadProgress} />
            </div>
          </div>
        )}
      </div>

      {/* 뷰어 영역 */}
      <div className="flex-1 relative overflow-hidden">
        <div className="absolute inset-0">
          <BasicContractTemplateViewer
            templateId={templateId}
            filePath={filePath}
            instance={instance}
            setInstance={setInstance}
          />
        </div>
      </div>
    </div>
  );
}