import { useEffect, useRef } from 'react';
import { Text as KonvaText } from 'react-konva';
import { TextObject } from '../../types/canvas.types';
import Konva from 'konva';

// Helper function to get fontStyle string based on weight and italic
function getFontStyle(bold: boolean, italic: boolean, fontWeight?: 'normal' | 'bold' | 'black'): string {
  const weight = fontWeight === 'black' ? '900' : bold ? 'bold' : 'normal';
  const style = italic ? 'italic' : '';
  return `${weight} ${style}`.trim();
}

interface TextEditableProps {
  object: TextObject;
  isSelected: boolean;
  onSelect: (e?: Konva.KonvaEventObject<MouseEvent>) => void;
  onDragStart?: (e: Konva.KonvaEventObject<DragEvent>) => void;
  onDragMove?: (e: Konva.KonvaEventObject<DragEvent>) => void;
  onDragEnd?: (e: Konva.KonvaEventObject<DragEvent>) => void;
  onTransformEnd?: (e: Konva.KonvaEventObject<Event>) => void;
  onEditingChange: (id: string, isEditing: boolean, clickX?: number, clickY?: number) => void;
  onMouseEnter?: () => void;
  onMouseLeave?: () => void;
  shapeRef?: ((node: Konva.Text | null) => void) | React.RefObject<Konva.Text>;
}

export default function TextEditable({
  object,
  isSelected,
  onSelect,
  onDragStart,
  onDragMove,
  onDragEnd,
  onTransformEnd,
  onEditingChange,
  onMouseEnter,
  onMouseLeave,
  shapeRef
}: TextEditableProps) {
  const textNodeRef = useRef<Konva.Text | null>(null);

  // Auto-enter edit mode when text is first created (empty text)
  useEffect(() => {
    if (object.text === '' && isSelected && !object.isFixedSize && !object.isEditing) {
      // Delay to ensure Konva node is fully rendered
      const timer = setTimeout(() => {
        onEditingChange(object.id, true);
      }, 100);
      return () => clearTimeout(timer);
    }
  }, [object.text, isSelected, object.isFixedSize, object.isEditing, object.id, onEditingChange]);

  // Handle double-click to edit
  const handleDoubleClick = (e: Konva.KonvaEventObject<MouseEvent>) => {
    if (!object.isEditing) {
      const stage = e.target.getStage();
      const pointerPos = stage?.getPointerPosition();
      if (pointerPos) {
        // Get click position relative to the text object
        const clickX = pointerPos.x - object.x;
        const clickY = pointerPos.y - object.y;
        onEditingChange(object.id, true, clickX, clickY);
      } else {
        onEditingChange(object.id, true);
      }
    }
  };

  // Calculate font size to fit text in fixed box (Stage 2)
  const calculateFitFontSize = (): number => {
    if (!object.isFixedSize) return object.fontSize;
    if (!object.text) return object.fontSize;

    try {
      // Create temporary text to measure
      const tempText = new Konva.Text({
        text: object.text || 'M',
        fontSize: object.fontSize,
        fontFamily: object.fontFamily,
        fontStyle: getFontStyle(object.bold, object.italic, object.fontWeight),
        width: object.width,
        height: object.height
      });

      let fontSize = object.fontSize;
      const maxWidth = object.width;
      const maxHeight = object.height;

      // Scale down font if text doesn't fit
      while (fontSize > 10) {
        tempText.fontSize(fontSize);
        const size = tempText.measureSize(object.text || 'M');

        if (size.width <= maxWidth && size.height <= maxHeight) {
          break;
        }
        fontSize -= 1;
      }

      tempText.destroy();
      return fontSize;
    } catch (error) {
      console.error('Error calculating fit font size:', error);
      return object.fontSize;
    }
  };

  const displayFontSize = object.isFixedSize ? calculateFitFontSize() : object.fontSize;

  return (
    <KonvaText
      id={object.id}
      ref={(node) => {
        // Call the callback ref if it's a function
        if (typeof shapeRef === 'function') {
          shapeRef(node);
        } else if (shapeRef) {
          // Set the RefObject if it's an object
          (shapeRef as React.MutableRefObject<Konva.Text | null>).current = node;
        }
        // Also store internally for our own use
        textNodeRef.current = node;
      }}
      x={object.x}
      y={object.y}
      width={object.width}
      height={object.height}
      text={object.text}
      fontSize={displayFontSize}
      fontFamily={object.fontFamily}
      fill={object.fill}
      fontStyle={getFontStyle(object.bold, object.italic, object.fontWeight)}
      align={object.align || 'left'}
      verticalAlign="top"
      rotation={object.rotation}
      padding={0}
      lineHeight={1}
      draggable={true}
      onClick={(e) => onSelect(e)}
      onTap={(e) => onSelect(e)}
      onDblClick={handleDoubleClick}
      onDblTap={handleDoubleClick}
      onDragStart={onDragStart}
      onDragMove={onDragMove}
      onDragEnd={onDragEnd}
      onTransformEnd={onTransformEnd}
      onMouseEnter={onMouseEnter}
      onMouseLeave={onMouseLeave}
      opacity={object.isEditing ? 0 : 1}
      listening={!object.isEditing}
    />
  );
}
