"use client";

import React from "react";
import { ComponentData, LayoutComponent } from "@/types/screen";
import { LayoutZone } from "@/types/layout";
import { DynamicComponentRenderer } from "../DynamicComponentRenderer";

export interface LayoutRendererProps {
  layout: LayoutComponent;
  allComponents: ComponentData[];
  isDesignMode?: boolean;
  isSelected?: boolean;
  onClick?: (e: React.MouseEvent) => void;
  onZoneClick?: (zoneId: string, e: React.MouseEvent) => void;
  onComponentDrop?: (zoneId: string, component: ComponentData, e: React.DragEvent) => void;
  onDragStart?: (e: React.DragEvent) => void;
  onDragEnd?: (e: React.DragEvent) => void;
  onUpdateLayout?: (updatedLayout: LayoutComponent) => void; // 레이아웃 업데이트 콜백
  children?: React.ReactNode;
  className?: string;
  style?: React.CSSProperties;
  // 추가된 props들 (레이아웃에서 사용되지 않지만 필터링 시 필요)
  formData?: Record<string, any>;
  onFormDataChange?: (fieldName: string, value: any) => void;
  isInteractive?: boolean;
  screenId?: number;
  tableName?: string;
  onRefresh?: () => void;
  onClose?: () => void;
  mode?: "view" | "edit";
  isInModal?: boolean;
  originalData?: Record<string, any>;
  [key: string]: any; // 기타 props 허용
}

export abstract class BaseLayoutRenderer extends React.Component<LayoutRendererProps> {
  abstract render(): React.ReactElement;

  /**
   * 레이아웃 존을 렌더링합니다.
   */
  protected renderZone(
    zone: LayoutZone,
    zoneChildren: ComponentData[] = [],
    additionalProps: Record<string, any> = {},
  ): React.ReactElement {
    const { isDesignMode, onZoneClick, onComponentDrop } = this.props;

    // 존 스타일 계산 - 항상 구역 경계 표시
    const zoneStyle: React.CSSProperties = {
      position: "relative",
      // 구역 경계 시각화 - 항상 표시
      border: "1px solid #e2e8f0",
      borderRadius: "6px",
      backgroundColor: "rgba(248, 250, 252, 0.5)",
      transition: "all 0.2s ease",
      ...this.getZoneStyle(zone),
      ...additionalProps.style,
    };

    // 디자인 모드일 때 더 강조된 스타일
    if (isDesignMode) {
      zoneStyle.border = "2px dashed #cbd5e1";
      zoneStyle.backgroundColor = "rgba(241, 245, 249, 0.8)";
    }

    // 호버 효과를 위한 추가 스타일
    const dropZoneStyle: React.CSSProperties = {
      minHeight: isDesignMode ? "60px" : "40px",
      borderRadius: "4px",
      display: "flex",
      flexDirection: "column",
      alignItems: zoneChildren.length === 0 ? "center" : "stretch",
      justifyContent: zoneChildren.length === 0 ? "center" : "flex-start",
      color: "#64748b",
      fontSize: "12px",
      transition: "all 0.2s ease",
      padding: "8px",
      position: "relative",
    };

    return (
      <div
        key={zone.id}
        className={`layout-zone ${isDesignMode ? "design-mode" : ""} ${additionalProps.className || ""}`}
        data-zone-id={zone.id}
        style={zoneStyle}
        onClick={(e) => {
          e.stopPropagation();
          onZoneClick?.(zone.id, e);
        }}
        onMouseEnter={(e) => {
          const element = e.currentTarget;
          element.style.borderColor = "#3b82f6";
          element.style.backgroundColor = "rgba(59, 130, 246, 0.02)";
          element.style.boxShadow = "0 1px 3px rgba(0, 0, 0, 0.1)";
        }}
        onMouseLeave={(e) => {
          const element = e.currentTarget;
          element.style.borderColor = isDesignMode ? "#cbd5e1" : "#e2e8f0";
          element.style.backgroundColor = isDesignMode ? "rgba(241, 245, 249, 0.8)" : "rgba(248, 250, 252, 0.5)";
          element.style.boxShadow = "none";
        }}
        onDrop={this.handleDrop(zone.id)}
        onDragOver={this.handleDragOver}
        onDragEnter={this.handleDragEnter}
        onDragLeave={this.handleDragLeave}
      >
        {/* 구역 라벨 - 항상 표시 */}
        <div
          className="zone-label"
          style={{
            position: "absolute",
            top: "-12px",
            left: "8px",
            backgroundColor: "#ffffff",
            border: "1px solid #e2e8f0",
            borderRadius: "12px",
            padding: "2px 8px",
            fontSize: "10px",
            fontWeight: "500",
            color: "#6b7280",
            zIndex: 10,
            boxShadow: "0 1px 2px rgba(0, 0, 0, 0.05)",
          }}
        >
          {zone.name || zone.id}
        </div>

        <div className="zone-content" style={dropZoneStyle}>
          {zoneChildren.length === 0 && isDesignMode ? (
            <div className="drop-placeholder">{zone.name}에 컴포넌트를 드롭하세요</div>
          ) : zoneChildren.length === 0 ? (
            <div
              className="empty-zone-indicator"
              style={{
                color: "#9ca3af",
                fontSize: "11px",
                textAlign: "center",
                fontStyle: "italic",
              }}
            >
              빈 구역
            </div>
          ) : (
            zoneChildren.map((child) => (
              <DynamicComponentRenderer
                key={child.id}
                component={child}
                allComponents={this.props.allComponents}
                isDesignMode={isDesignMode}
              />
            ))
          )}
        </div>
      </div>
    );
  }

  /**
   * 존 스타일을 계산합니다.
   */
  protected getZoneStyle(zone: LayoutZone): React.CSSProperties {
    const style: React.CSSProperties = {};

    // 크기 설정
    if (typeof zone.size.width === "number") {
      style.width = `${zone.size.width}px`;
    } else {
      style.width = zone.size.width;
    }

    if (typeof zone.size.height === "number") {
      style.height = `${zone.size.height}px`;
    } else {
      style.height = zone.size.height;
    }

    // 최소/최대 크기
    if (zone.size.minWidth) style.minWidth = `${zone.size.minWidth}px`;
    if (zone.size.minHeight) style.minHeight = `${zone.size.minHeight}px`;
    if (zone.size.maxWidth) style.maxWidth = `${zone.size.maxWidth}px`;
    if (zone.size.maxHeight) style.maxHeight = `${zone.size.maxHeight}px`;

    // 커스텀 스타일 적용
    if (zone.style) {
      Object.assign(style, this.convertComponentStyleToCSS(zone.style));
    }

    return style;
  }

  /**
   * ComponentStyle을 CSS 스타일로 변환합니다.
   */
  protected convertComponentStyleToCSS(componentStyle: any): React.CSSProperties {
    const cssStyle: React.CSSProperties = {};

    // 여백
    if (componentStyle.margin) cssStyle.margin = componentStyle.margin;
    if (componentStyle.padding) cssStyle.padding = componentStyle.padding;

    // 테두리
    if (componentStyle.borderWidth) cssStyle.borderWidth = `${componentStyle.borderWidth}px`;
    if (componentStyle.borderColor) cssStyle.borderColor = componentStyle.borderColor;
    if (componentStyle.borderStyle) cssStyle.borderStyle = componentStyle.borderStyle;
    if (componentStyle.borderRadius) cssStyle.borderRadius = `${componentStyle.borderRadius}px`;

    // 배경
    if (componentStyle.backgroundColor) cssStyle.backgroundColor = componentStyle.backgroundColor;

    // 텍스트
    if (componentStyle.color) cssStyle.color = componentStyle.color;
    if (componentStyle.fontSize) cssStyle.fontSize = `${componentStyle.fontSize}px`;
    if (componentStyle.fontWeight) cssStyle.fontWeight = componentStyle.fontWeight;
    if (componentStyle.textAlign) cssStyle.textAlign = componentStyle.textAlign;

    return cssStyle;
  }

  /**
   * 레이아웃 컨테이너 스타일을 계산합니다.
   */
  protected getLayoutContainerStyle(): React.CSSProperties {
    const { layout, style: propStyle } = this.props;

    const style: React.CSSProperties = {
      width: layout.size.width,
      height: layout.size.height,
      position: "relative",
      overflow: "hidden",
      ...propStyle,
    };

    // 레이아웃 커스텀 스타일 적용
    if (layout.style) {
      Object.assign(style, this.convertComponentStyleToCSS(layout.style));
    }

    return style;
  }

  /**
   * 존별 자식 컴포넌트들을 분류합니다.
   */
  protected getZoneChildren(zoneId: string): ComponentData[] {
    return this.props.allComponents.filter(
      (component) => component.parentId === this.props.layout.id && (component as any).zoneId === zoneId,
    );
  }

  /**
   * 드래그 드롭 핸들러
   */
  private handleDrop = (zoneId: string) => (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();

    // 드롭존 하이라이트 제거
    this.removeDragHighlight(e.currentTarget as HTMLElement);

    try {
      const componentData = e.dataTransfer.getData("application/json");
      if (componentData) {
        const component = JSON.parse(componentData);
        this.props.onComponentDrop?.(zoneId, component, e);
      }
    } catch (error) {
      console.error("드롭 데이터 파싱 오류:", error);
    }
  };

  private handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();

    // 드롭존 하이라이트 추가
    this.addDragHighlight(e.currentTarget as HTMLElement);
  };

  private handleDragEnter = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
  };

  private handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();

    // 실제로 존을 벗어났는지 확인
    const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
    const x = e.clientX;
    const y = e.clientY;

    if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {
      this.removeDragHighlight(e.currentTarget as HTMLElement);
    }
  };

  /**
   * 드래그 하이라이트 추가
   */
  private addDragHighlight(element: HTMLElement) {
    element.classList.add("drag-over");
    element.style.borderColor = "#3b82f6";
    element.style.backgroundColor = "rgba(59, 130, 246, 0.05)";
  }

  /**
   * 드래그 하이라이트 제거
   */
  private removeDragHighlight(element: HTMLElement) {
    element.classList.remove("drag-over");
    element.style.borderColor = "";
    element.style.backgroundColor = "";
  }
}
