"use client";

import * as React from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { GenericData } from "./export-excel-form";
import { SpreadSheets, Worksheet, Column } from "@mescius/spread-sheets-react";
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";

interface TemplateItem {
  TMPL_ID: string;
  NAME: string;
  TMPL_TYPE: string;
  SPR_LST_SETUP: {
    ACT_SHEET: string;
    HIDN_SHEETS: Array<string>;
    CONTENT?: string; // SpreadSheets JSON
    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; // SpreadSheets JSON
    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;
  /** 업데이트 성공 시 호출될 콜백 */
  onUpdateSuccess?: (updatedValues: Record<string, any>) => void;
}

export function TemplateViewDialog({
  isOpen,
  onClose,
  templateData,
  selectedRow,
  formCode,
  contractItemId,
  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>("");

  // 템플릿 데이터를 배열로 정규화하고 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];
    }
    
    // CONTENT가 있는 템플릿만 필터링
    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]);

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

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

    try {
      setCurrentSpread(spread);
      setHasChanges(false); // 템플릿 로드 시 변경사항 초기화

      // CONTENT 찾기 (SPR_LST_SETUP 또는 SPR_ITM_LST_SETUP 중 하나)
      let contentJson = null;
      if (selectedTemplate.SPR_LST_SETUP?.CONTENT) {
        contentJson = selectedTemplate.SPR_LST_SETUP.CONTENT;
        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;
        console.log('Using SPR_ITM_LST_SETUP.CONTENT for template:', selectedTemplate.NAME);
      }

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

        // fromJSON으로 템플릿 구조 로드
        spread.fromJSON(jsonData);
      } else {
        console.warn('No CONTENT found in template:', selectedTemplate.NAME);
        return;
      }

      // 값 변경 이벤트 리스너 추가 (간단한 변경사항 감지만)
      const activeSheet = spread.getActiveSheet();
      
      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);
      });

    } catch (error) {
      console.error('Error initializing spread:', error);
      toast.error('Failed to load template');
    }
  }, [selectedTemplate]);

  // 템플릿 변경 핸들러
  const handleTemplateChange = (templateId: string) => {
    setSelectedTemplateId(templateId);
    setHasChanges(false); // 템플릿 변경 시 변경사항 초기화
    
    // SpreadSheets 재초기화는 useCallback 의존성에 의해 자동으로 처리됨
    if (currentSpread) {
      // 강제로 재초기화
      setTimeout(() => {
        initSpread(currentSpread);
      }, 100);
    }
  };

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

    try {
      setIsPending(true);

      // SpreadSheets에서 현재 데이터를 JSON으로 추출
      const spreadJson = currentSpread.toJSON();
      console.log('Current spread data:', spreadJson);

      // 실제 데이터 추출 방법은 SpreadSheets 구조에 따라 달라질 수 있음
      // 여기서는 기본적인 예시만 제공
      const activeSheet = currentSpread.getActiveSheet();
      
      // 간단한 예시: 특정 범위의 데이터를 추출하여 selectedRow 형태로 변환
      // 실제 구현에서는 템플릿의 구조에 맞춰 데이터를 추출해야 함
      const dataToSave = {
        ...selectedRow, // 기본값으로 원본 데이터 사용
        // 여기에 SpreadSheets에서 변경된 값들을 추가
        // 예: TAG_DESC: activeSheet.getValue(특정행, 특정열)
      };

      // 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]);

  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 />
            <span className="text-xs text-muted-foreground">
              Template content will be loaded directly. Manual data entry may be required.
            </span>
          </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 ? (
            <SpreadSheets 
              key={selectedTemplateId} // 템플릿 변경 시 컴포넌트 재생성
              workbookInitialized={initSpread}
              hostStyle={hostStyle}
            />
          ) : (
            <div className="flex items-center justify-center h-full text-muted-foreground">
              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>
  );
}