import React, { useRef } from "react";
import {
  PanResponder,
  Text,
  View,
} from "react-native";
import * as Haptics from "expo-haptics";
import { type CanvasTextLayer, getCanvasFontFamily } from "./types";

interface CanvasLayerItemProps {
  layer: CanvasTextLayer;
  isSelected: boolean;
  onSelect: (id: string) => void;
  onEdit: (layer: CanvasTextLayer) => void;
  onUpdatePosition: (id: string, x: number, y: number) => void;
  onDelete: (id: string) => void;
  onDragStart?: () => void;
  onDragMove?: (rawX: number, rawY: number, itemWidth: number, itemHeight: number) => { snappedX: number; snappedY: number };
  onDragEnd?: (finalX: number, finalY: number, itemWidth: number, itemHeight: number) => void;
  canvasWidth: number;
  canvasHeight: number;
}

export const CurvedTextNative: React.FC<{
  text: string;
  fontSize: number;
  color: string;
  fontFamily: string;
  fontWeight?: any;
  letterSpacing?: number;
  curveDegree: number;
  hasShadow?: boolean;
}> = ({
  text,
  fontSize,
  color,
  fontFamily,
  fontWeight = "800",
  letterSpacing = 0.5,
  curveDegree,
  hasShadow,
}) => {
  const isUp = curveDegree > 0;
  const absDegree = Math.abs(curveDegree);
  const radius = Math.max(40, 420 - absDegree * 3.5);
  const charWidth = fontSize * 0.52 + (letterSpacing || 0);
  const numChars = text.length;
  const arcLength = numChars * charWidth;
  const totalAngleRad = arcLength / radius;
  const stepRad = numChars > 1 ? totalAngleRad / (numChars - 1) : 0;
  const startAngleRad = -totalAngleRad / 2;

  const maxOffsetY = Math.abs(-radius * (Math.cos(totalAngleRad / 2) - 1));
  const containerHeight = fontSize + maxOffsetY + 12;
  const containerWidth = Math.max(numChars * charWidth, radius * 2 * Math.sin(totalAngleRad / 2)) + 16;

  return (
    <View style={{ width: containerWidth, height: containerHeight, alignItems: "center", justifyContent: "center" }}>
      {text.split("").map((ch, i) => {
        const angleRad = startAngleRad + i * stepRad;
        const angleDeg = angleRad * (180 / Math.PI);
        const charX = radius * Math.sin(angleRad);
        const charY = isUp
          ? -radius * (Math.cos(angleRad) - 1)
          : radius * (Math.cos(angleRad) - 1);
        const charRotate = isUp ? angleDeg : -angleDeg;

        return (
          <Text
            key={i}
            style={{
              position: "absolute",
              fontSize,
              color,
              fontFamily,
              fontWeight,
              letterSpacing,
              textShadowColor: hasShadow ? "rgba(0,0,0,0.8)" : "transparent",
              textShadowOffset: { width: 0, height: 1 },
              textShadowRadius: 3,
              transform: [
                { translateX: charX },
                { translateY: charY },
                { rotate: `${charRotate}deg` },
              ],
            }}
          >
            {ch === " " ? "\u00A0" : ch}
          </Text>
        );
      })}
    </View>
  );
};

export const CanvasLayerItem: React.FC<CanvasLayerItemProps> = ({
  layer,
  isSelected,
  onSelect,
  onEdit,
  onUpdatePosition,
  onDelete,
  onDragStart,
  onDragMove,
  onDragEnd,
  canvasWidth,
  canvasHeight,
}) => {
  const layerRef = useRef(layer);
  layerRef.current = layer;

  const canvasWidthRef = useRef(canvasWidth);
  canvasWidthRef.current = canvasWidth;

  const canvasHeightRef = useRef(canvasHeight);
  canvasHeightRef.current = canvasHeight;

  const panStartRef = useRef({ x: layer.x, y: layer.y });
  const layoutSizeRef = useRef({ width: 70, height: 26 });
  const currentPosRef = useRef({ x: layer.x, y: layer.y });
  const lastTapRef = useRef<number>(0);
  const isDraggingRef = useRef(false);

  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onStartShouldSetPanResponderCapture: () => true,
      onMoveShouldSetPanResponder: (_evt, gestureState) =>
        Math.abs(gestureState.dx) > 1 || Math.abs(gestureState.dy) > 1,
      onMoveShouldSetPanResponderCapture: (_evt, gestureState) =>
        Math.abs(gestureState.dx) > 1 || Math.abs(gestureState.dy) > 1,
      onPanResponderTerminationRequest: () => false,

      onPanResponderGrant: () => {
        const now = Date.now();
        const DOUBLE_TAP_DELAY = 300;
        const curLayer = layerRef.current;
        if (now - lastTapRef.current < DOUBLE_TAP_DELAY) {
          try {
            Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
          } catch {}
          onEdit(curLayer);
        } else {
          onSelect(curLayer.id);
        }
        lastTapRef.current = now;

        panStartRef.current = { x: curLayer.x, y: curLayer.y };
        currentPosRef.current = { x: curLayer.x, y: curLayer.y };
        isDraggingRef.current = false;
        onDragStart?.();
      },

      onPanResponderMove: (_evt, gestureState) => {
        if (!isDraggingRef.current && (Math.abs(gestureState.dx) > 2 || Math.abs(gestureState.dy) > 2)) {
          isDraggingRef.current = true;
        }

        const curLayer = layerRef.current;
        const itemW = layoutSizeRef.current.width;
        const itemH = layoutSizeRef.current.height;
        const cWidth = canvasWidthRef.current;
        const cHeight = canvasHeightRef.current;

        const maxX = Math.max(0, cWidth - itemW);
        const maxY = Math.max(0, cHeight - itemH);
        const rawX = Math.max(0, Math.min(maxX, panStartRef.current.x + gestureState.dx));
        const rawY = Math.max(0, Math.min(maxY, panStartRef.current.y + gestureState.dy));

        if (onDragMove) {
          const { snappedX, snappedY } = onDragMove(rawX, rawY, itemW, itemH);
          currentPosRef.current = { x: snappedX, y: snappedY };
          onUpdatePosition(curLayer.id, snappedX, snappedY);
        } else {
          const sx = Math.round(rawX);
          const sy = Math.round(rawY);
          currentPosRef.current = { x: sx, y: sy };
          onUpdatePosition(curLayer.id, sx, sy);
        }
      },

      onPanResponderRelease: () => {
        const itemW = layoutSizeRef.current.width;
        const itemH = layoutSizeRef.current.height;
        onDragEnd?.(currentPosRef.current.x, currentPosRef.current.y, itemW, itemH);
      },

      onPanResponderTerminate: () => {
        const itemW = layoutSizeRef.current.width;
        const itemH = layoutSizeRef.current.height;
        onDragEnd?.(currentPosRef.current.x, currentPosRef.current.y, itemW, itemH);
      },
    })
  ).current;

  // Instagram Badge arka plan stili
  const renderBackgroundStyle = () => {
    switch (layer.bgStyle) {
      case "solid":
        return {
          backgroundColor: layer.bgBoxColor || "rgba(18, 18, 21, 0.92)",
          paddingHorizontal: 12,
          paddingVertical: 5,
          borderRadius: 8,
        };
      case "soft":
        return {
          backgroundColor: "rgba(255, 255, 255, 0.18)",
          paddingHorizontal: 12,
          paddingVertical: 5,
          borderRadius: 8,
          borderWidth: 1,
          borderColor: "rgba(255, 255, 255, 0.25)",
        };
      case "outline":
        return {
          backgroundColor: "transparent",
          paddingHorizontal: 10,
          paddingVertical: 4,
          borderRadius: 8,
          borderWidth: 1.5,
          borderColor: layer.color || "#D4AF37",
        };
      case "none":
      default:
        return {
          backgroundColor: "transparent",
          paddingHorizontal: 4,
          paddingVertical: 2,
        };
    }
  };

  return (
    <View
      {...panResponder.panHandlers}
      accessible={true}
      accessibilityRole="button"
      accessibilityLabel={`Metin: ${layer.text}`}
      accessibilityHint="Metni düzenlemek için çift dokunun, taşımak için sürükleyin"
      accessibilityState={{ selected: isSelected }}
      onLayout={(e) => {
        const { width, height } = e.nativeEvent.layout;
        layoutSizeRef.current = { width, height };
      }}
      style={{
        position: "absolute",
        left: layer.x,
        top: layer.y,
        transform: [{ rotate: `${layer.rotation || 0}deg` }],
        zIndex: isSelected ? 90 : 20,
      }}
    >
      <View
        style={{
          borderWidth: isSelected ? 1.5 : 0,
          borderColor: isSelected ? "#D4AF37" : "transparent",
          borderStyle: isSelected ? "dashed" : "solid",
          borderRadius: 10,
          padding: 2,
        }}
      >
        <View style={renderBackgroundStyle()}>
          {layer.curveDegree && layer.curveDegree !== 0 ? (
            <CurvedTextNative
              text={layer.text}
              fontSize={layer.fontSize}
              color={layer.color}
              fontFamily={getCanvasFontFamily(layer.fontId)}
              fontWeight={layer.fontWeight || "bold"}
              letterSpacing={layer.letterSpacing ?? 0.5}
              curveDegree={layer.curveDegree}
              hasShadow={layer.hasShadow}
            />
          ) : (
            <Text
              style={{
                fontSize: layer.fontSize,
                color: layer.color,
                fontFamily: getCanvasFontFamily(layer.fontId),
                fontWeight: layer.fontWeight || "bold",
                textAlign: layer.textAlign || "center",
                letterSpacing: layer.letterSpacing ?? 0.5,
                textShadowColor: layer.hasShadow ? "rgba(0,0,0,0.8)" : "transparent",
                textShadowOffset: { width: 0, height: 1 },
                textShadowRadius: 3,
              }}
            >
              {layer.text}
            </Text>
          )}
        </View>
      </View>
    </View>
  );
};
