"use client";

import * as React from "react";
import dynamic from "next/dynamic";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { GenericData } from "./export-excel-form";
import * as GC from "@mescius/spread-sheets";
import { toast } from "sonner";
import { updateFormDataInDB } from "@/lib/forms/services";
import { Loader, Save } from "lucide-react";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import '@mescius/spread-sheets/styles/gc.spread.sheets.excel2016colorful.css';

// SpreadSheets를 동적으로 import (SSR 비활성화)
const SpreadSheets = dynamic(
  () => import("@mescius/spread-sheets-react").then(mod => mod.SpreadSheets),
  { 
    ssr: false,
    loading: () => (
      <div className="flex items-center justify-center h-full">
        <Loader className="mr-2 h-4 w-4 animate-spin" />
        Loading SpreadSheets...
      </div>
    )
  }
);

// 라이센스 키 설정을 클라이언트에서만 실행
if (typeof window !== 'undefined' && process.env.NEXT_PUBLIC_SPREAD_LICENSE) {
  GC.Spread.Sheets.LicenseKey = process.env.NEXT_PUBLIC_SPREAD_LICENSE;
}

interface TemplateItem {
  TMPL_ID: string;
  NAME: string;
  TMPL_TYPE: string;
  SPR_LST_SETUP: {
    ACT_SHEET: string;
    HIDN_SHEETS: Array<string>;
    CONTENT?: string;
    DATA_SHEETS: Array<{
      SHEET_NAME: string;
      REG_TYPE_ID: string;
      MAP_CELL_ATT: Array<{
        ATT_ID: string;
        IN: string;
      }>;
    }>;
  };
  GRD_LST_SETUP: {
    REG_TYPE_ID: string;
    SPR_ITM_IDS: Array<string>;
    ATTS: Array<{}>;
  };
  SPR_ITM_LST_SETUP: {
    ACT_SHEET: string;
    HIDN_SHEETS: Array<string>;
    CONTENT?: string;
    DATA_SHEETS: Array<{
      SHEET_NAME: string;
      REG_TYPE_ID: string;
      MAP_CELL_ATT: Array<{
        ATT_ID: string;
        IN: string;
      }>;
    }>;
  };
}

interface TemplateViewDialogProps {
  isOpen: boolean;
  onClose: () => void;
  templateData: TemplateItem[] | any;
  selectedRow: GenericData;
  formCode: string;
  contractItemId: number;
  editableFieldsMap?: Map<string, string[]>; // 편집 가능 필드 정보
  onUpdateSuccess?: (updatedValues: Record<string, any>) => void;
}

export function TemplateViewDialog({
  isOpen,
  onClose,
  templateData,
  selectedRow,
  formCode,
  contractItemId,
  editableFieldsMap = new Map(),
  onUpdateSuccess
}: TemplateViewDialogProps) {
  const [hostStyle, setHostStyle] = React.useState({
    width: '100%',
    height: '100%'
  });

  const [isPending, setIsPending] = React.useState(false);
  const [hasChanges, setHasChanges] = React.useState(false);
  const [currentSpread, setCurrentSpread] = React.useState<any>(null);
  const [selectedTemplateId, setSelectedTemplateId] = React.useState<string>("");
  const [cellMappings, setCellMappings] = React.useState<Array<{attId: string, cellAddress: string, isEditable: boolean}>>([]);
  const [isClient, setIsClient] = React.useState(false);

  // 클라이언트 사이드에서만 렌더링되도록 보장
  React.useEffect(() => {
    setIsClient(true);
  }, []);

  // 템플릿 데이터를 배열로 정규화하고 CONTENT가 있는 것만 필터링
  const normalizedTemplates = React.useMemo((): TemplateItem[] => {
    if (!templateData) return [];
    
    let templates: TemplateItem[];
    if (Array.isArray(templateData)) {
      templates = templateData as TemplateItem[];
    } else {
      templates = [templateData as TemplateItem];
    }
    
    return templates.filter(template => {
      const sprContent = template.SPR_LST_SETUP?.CONTENT;
      const sprItmContent = template.SPR_ITM_LST_SETUP?.CONTENT;
      return sprContent || sprItmContent;
    });
  }, [templateData]);

  // 선택된 템플릿 가져오기
  const selectedTemplate = React.useMemo(() => {
    if (!selectedTemplateId) return normalizedTemplates[0];
    return normalizedTemplates.find(t => t.TMPL_ID === selectedTemplateId) || normalizedTemplates[0];
  }, [normalizedTemplates, selectedTemplateId]);

  // 현재 TAG의 편집 가능한 필드 목록 가져오기
  const editableFields = React.useMemo(() => {
    if (!selectedRow?.TAG_NO || !editableFieldsMap.has(selectedRow.TAG_NO)) {
      return [];
    }
    return editableFieldsMap.get(selectedRow.TAG_NO) || [];
  }, [selectedRow?.TAG_NO, editableFieldsMap]);

  // 필드가 편집 가능한지 판별하는 함수
  const isFieldEditable = React.useCallback((attId: string) => {
    // TAG_NO와 TAG_DESC는 기본적으로 편집 가능
    if (attId === "TAG_NO" || attId === "TAG_DESC") {
      return true;
    }
    
    // editableFieldsMap이 있으면 해당 리스트에 있는지 확인
    if (selectedRow?.TAG_NO && editableFieldsMap.has(selectedRow.TAG_NO)) {
      return editableFields.includes(attId);
    }
    
    return false;
  }, [selectedRow?.TAG_NO, editableFieldsMap, editableFields]);

  // 셀 주소를 행과 열로 변환하는 함수 (예: "M1" -> {row: 0, col: 12})
  const parseCellAddress = (address: string): {row: number, col: number} | null => {
    if (!address || address.trim() === "") return null;
    
    const match = address.match(/^([A-Z]+)(\d+)$/);
    if (!match) return null;
    
    const [, colStr, rowStr] = match;
    
    // 열 문자를 숫자로 변환 (A=0, B=1, ..., Z=25, AA=26, ...)
    let col = 0;
    for (let i = 0; i < colStr.length; i++) {
      col = col * 26 + (colStr.charCodeAt(i) - 65 + 1);
    }
    col -= 1; // 0-based index로 변환
    
    const row = parseInt(rowStr) - 1; // 0-based index로 변환
    
    return { row, col };
  };

  // 템플릿 변경 시 기본 선택
  React.useEffect(() => {
    if (normalizedTemplates.length > 0 && !selectedTemplateId) {
      setSelectedTemplateId(normalizedTemplates[0].TMPL_ID);
    }
  }, [normalizedTemplates, selectedTemplateId]);

  const initSpread = React.useCallback((spread: any) => {
    if (!spread || !selectedTemplate || !selectedRow) return;

    try {
      setCurrentSpread(spread);
      setHasChanges(false);

      // CONTENT 찾기
      let contentJson = null;
      let dataSheets = null;
      
      if (selectedTemplate.SPR_LST_SETUP?.CONTENT) {
        contentJson = selectedTemplate.SPR_LST_SETUP.CONTENT;
        dataSheets = selectedTemplate.SPR_LST_SETUP.DATA_SHEETS;
        console.log('Using SPR_LST_SETUP.CONTENT for template:', selectedTemplate.NAME);
      } else if (selectedTemplate.SPR_ITM_LST_SETUP?.CONTENT) {
        contentJson = selectedTemplate.SPR_ITM_LST_SETUP.CONTENT;
        dataSheets = selectedTemplate.SPR_ITM_LST_SETUP.DATA_SHEETS;
        console.log('Using SPR_ITM_LST_SETUP.CONTENT for template:', selectedTemplate.NAME);
      }

      if (!contentJson) {
        console.warn('No CONTENT found in template:', selectedTemplate.NAME);
        return;
      }

      console.log('Loading template content for:', selectedTemplate.NAME);
      
      const jsonData = typeof contentJson === 'string' 
        ? JSON.parse(contentJson) 
        : contentJson;

      // 렌더링 일시 중단 (성능 향상)
      spread.suspendPaint();

      try {
        // fromJSON으로 템플릿 구조 로드
        spread.fromJSON(jsonData);

        // 활성 시트 가져오기
        const activeSheet = spread.getActiveSheet();
        
        // 시트 보호 먼저 해제
        activeSheet.options.isProtected = false;

        // MAP_CELL_ATT 정보를 사용해서 셀에 데이터 매핑과 스타일을 한번에 처리
        if (dataSheets && dataSheets.length > 0) {
          const mappings: Array<{attId: string, cellAddress: string, isEditable: boolean}> = [];
          
          dataSheets.forEach(dataSheet => {
            if (dataSheet.MAP_CELL_ATT) {
              dataSheet.MAP_CELL_ATT.forEach(mapping => {
                const { ATT_ID, IN } = mapping;
                
                // 셀 주소가 비어있지 않은 경우만 처리
                if (IN && IN.trim() !== "") {
                  const cellPos = parseCellAddress(IN);
                  if (cellPos) {
                    const isEditable = isFieldEditable(ATT_ID);
                    mappings.push({
                      attId: ATT_ID,
                      cellAddress: IN,
                      isEditable: isEditable
                    });
                    
                    // 셀 객체 가져오기
                    const cell = activeSheet.getCell(cellPos.row, cellPos.col);
                    
                    // selectedRow에서 해당 값 가져와서 셀에 설정
                    const value = selectedRow[ATT_ID];
                    if (value !== undefined && value !== null) {
                      cell.value(value);
                    }
                    
                    // 편집 권한 설정
                    cell.locked(!isEditable);
                    
                    // 즉시 스타일 적용 (기존 스타일 보존하면서)
                    const existingStyle = activeSheet.getStyle(cellPos.row, cellPos.col);
                    if (existingStyle) {
                      // 기존 스타일 복사
                      const newStyle = Object.assign(new GC.Spread.Sheets.Style(), existingStyle);
                      
                      // 편집 권한에 따라 배경색만 변경
                      if (isEditable) {
                        newStyle.backColor = "#f0fdf4"; // 연한 녹색
                      } else {
                        newStyle.backColor = "#f9fafb"; // 연한 회색
                        newStyle.foreColor = "#6b7280"; // 회색 글자
                      }
                      
                      // 스타일 적용
                      activeSheet.setStyle(cellPos.row, cellPos.col, newStyle);
                    } else {
                      // 기존 스타일이 없는 경우 새로운 스타일 생성
                      const newStyle = new GC.Spread.Sheets.Style();
                      if (isEditable) {
                        newStyle.backColor = "#f0fdf4";
                      } else {
                        newStyle.backColor = "#f9fafb";
                        newStyle.foreColor = "#6b7280";
                      }
                      activeSheet.setStyle(cellPos.row, cellPos.col, newStyle);
                    }
                    
                    console.log(`Mapped ${ATT_ID} (${value}) to cell ${IN} - ${isEditable ? 'Editable' : 'Read-only'}`);
                  }
                }
              });
            }
          });
          
          setCellMappings(mappings);
          
          // 시트 보호 설정
          activeSheet.options.isProtected = true;
          activeSheet.options.protectionOptions = {
            allowSelectLockedCells: true,
            allowSelectUnlockedCells: true,
            allowSort: false,
            allowFilter: false,
            allowEditObjects: false,
            allowResizeRows: false,
            allowResizeColumns: false
          };

          // 이벤트 리스너 추가
          activeSheet.bind(GC.Spread.Sheets.Events.CellChanged, (event: any, info: any) => {
            console.log('Cell changed:', info);
            setHasChanges(true);
          });

          activeSheet.bind(GC.Spread.Sheets.Events.ValueChanged, (event: any, info: any) => {
            console.log('Value changed:', info);
            setHasChanges(true);
          });

          // 편집 시작 시 읽기 전용 셀 확인
          activeSheet.bind(GC.Spread.Sheets.Events.EditStarting, (event: any, info: any) => {
            const mapping = mappings.find(m => {
              const cellPos = parseCellAddress(m.cellAddress);
              return cellPos && cellPos.row === info.row && cellPos.col === info.col;
            });
            
            if (mapping && !mapping.isEditable) {
              toast.warning(`${mapping.attId} field is read-only`);
              info.cancel = true;
            }
          });
        }
      } finally {
        // 렌더링 재개 (모든 변경사항이 한번에 화면에 표시됨)
        spread.resumePaint();
      }

    } catch (error) {
      console.error('Error initializing spread:', error);
      toast.error('Failed to load template');
      // 에러 발생 시에도 렌더링 재개
      if (spread && spread.resumePaint) {
        spread.resumePaint();
      }
    }
  }, [selectedTemplate, selectedRow, isFieldEditable]);

  // 템플릿 변경 핸들러
  const handleTemplateChange = (templateId: string) => {
    setSelectedTemplateId(templateId);
    setHasChanges(false);
    
    if (currentSpread) {
      setTimeout(() => {
        initSpread(currentSpread);
      }, 100);
    }
  };

  // 변경사항 저장 함수
  const handleSaveChanges = React.useCallback(async () => {
    if (!currentSpread || !hasChanges || !selectedRow) {
      toast.info("No changes to save");
      return;
    }

    try {
      setIsPending(true);

      const activeSheet = currentSpread.getActiveSheet();
      const dataToSave = { ...selectedRow };

      // cellMappings를 사용해서 편집 가능한 셀의 값만 추출
      cellMappings.forEach(mapping => {
        if (mapping.isEditable) {
          const cellPos = parseCellAddress(mapping.cellAddress);
          if (cellPos) {
            const cellValue = activeSheet.getValue(cellPos.row, cellPos.col);
            dataToSave[mapping.attId] = cellValue;
          }
        }
      });

      // TAG_NO는 절대 변경되지 않도록 원본 값으로 강제 설정
      dataToSave.TAG_NO = selectedRow.TAG_NO;

      console.log('Data to save (TAG_NO preserved):', dataToSave);

      const { success, message } = await updateFormDataInDB(
        formCode,
        contractItemId,
        dataToSave
      );

      if (!success) {
        toast.error(message);
        return;
      }

      toast.success("Changes saved successfully!");

      const updatedData = {
        ...selectedRow,
        ...dataToSave,
      };

      onUpdateSuccess?.(updatedData);
      setHasChanges(false);

    } catch (error) {
      console.error("Error saving changes:", error);
      toast.error("An unexpected error occurred while saving");
    } finally {
      setIsPending(false);
    }
  }, [currentSpread, hasChanges, formCode, contractItemId, selectedRow, onUpdateSuccess, cellMappings]);

  if (!isOpen) return null;

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent 
        className="w-[80%] max-w-none h-[80vh] flex flex-col" 
        style={{maxWidth:"80vw"}}
      >
        <DialogHeader className="flex-shrink-0">
          <DialogTitle>SEDP Template - {formCode}</DialogTitle>
          <DialogDescription>
            {selectedRow && `Selected TAG_NO: ${selectedRow.TAG_NO || 'N/A'}`}
            {hasChanges && (
              <span className="ml-2 text-orange-600 font-medium">
                • Unsaved changes
              </span>
            )}
            <br />
            <div className="flex items-center gap-4 mt-2">
              <span className="text-xs text-muted-foreground">
                <span className="inline-block w-3 h-3 bg-green-100 border border-green-400 mr-1"></span>
                Editable fields
              </span>
              <span className="text-xs text-muted-foreground">
                <span className="inline-block w-3 h-3 bg-gray-100 border border-gray-300 mr-1"></span>
                Read-only fields
              </span>
              {cellMappings.length > 0 && (
                <span className="text-xs text-blue-600">
                  {cellMappings.filter(m => m.isEditable).length} of {cellMappings.length} fields editable
                </span>
              )}
            </div>
          </DialogDescription>
        </DialogHeader>

        {/* 템플릿 선택 UI */}
        {normalizedTemplates.length > 1 && (
          <div className="flex-shrink-0 px-4 py-2 border-b">
            <div className="flex items-center gap-2">
              <label className="text-sm font-medium">Template:</label>
              <Select value={selectedTemplateId} onValueChange={handleTemplateChange}>
                <SelectTrigger className="w-64">
                  <SelectValue placeholder="Select a template" />
                </SelectTrigger>
                <SelectContent>
                  {normalizedTemplates.map((template) => (
                    <SelectItem key={template.TMPL_ID} value={template.TMPL_ID}>
                      <div className="flex flex-col">
                        <span>{template.NAME || `Template ${template.TMPL_ID.slice(0, 8)}`}</span>
                        <span className="text-xs text-muted-foreground">{template.TMPL_TYPE}</span>
                      </div>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <span className="text-xs text-muted-foreground">
                ({normalizedTemplates.length} templates available)
              </span>
            </div>
          </div>
        )}
        
        {/* SpreadSheets 컴포넌트 영역 */}
        <div className="flex-1 overflow-hidden">
          {selectedTemplate && isClient ? (
            <SpreadSheets 
              key={selectedTemplateId}
              workbookInitialized={initSpread}
              hostStyle={hostStyle}
            />
          ) : (
            <div className="flex items-center justify-center h-full text-muted-foreground">
              {!isClient ? (
                <>
                  <Loader className="mr-2 h-4 w-4 animate-spin" />
                  Loading...
                </>
              ) : (
                "No template available"
              )}
            </div>
          )}
        </div>

        <DialogFooter className="flex-shrink-0">
          <Button variant="outline" onClick={onClose}>
            Close
          </Button>
          
          {hasChanges && (
            <Button 
              variant="default" 
              onClick={handleSaveChanges}
              disabled={isPending}
            >
              {isPending ? (
                <>
                  <Loader className="mr-2 h-4 w-4 animate-spin" />
                  Saving...
                </>
              ) : (
                <>
                  <Save className="mr-2 h-4 w-4" />
                  Save Changes
                </>
              )}
            </Button>
          )}
          
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}