import { Button } from '@/components/ui/button';
import { useMitt } from '@/plugins/MittContext';
import useVideoEditorStore from '@/stores/VideoEditorStore';
import { Type } from 'lucide-react';
import { useEffect, useRef } from 'react';
import { Group, Image, Layer, Line, Stage, Text, Transformer } from 'react-konva';
import { Html } from 'react-konva-utils';

// Import our custom hooks and utilities
import { useElementSelection } from './video-preview/video-preview-element-selection';
import { useElementTransform } from './video-preview/video-preview-element-transform';
import { getImageSource, getTextFontStyle } from './video-preview/video-preview-utils';

const VideoPreview = ({
    // Dimensions
    dimensions,

    // Timeline state
    currentTime,
    totalDuration,
    isPlaying,
    status,

    // Export state
    isExporting,
    exportProgress,
    exportStatus,

    // Data
    timelineElements,
    activeElements,
    videoElements,
    loadedVideos,
    videoStates,
    ffmpegCommand,

    // Event handlers
    handlePlay,
    handlePause,
    handleReset,
    handleSeek,
    copyFFmpegCommand,
    exportVideo,
    onElementUpdate, // New prop for updating element properties
    onOpenTextSidebar, // New prop for opening text sidebar

    // Refs
    layerRef,
}) => {
    const emitter = useMitt();
    const { selectedTextElement } = useVideoEditorStore();

    // Refs for elements and transformer
    const transformerRef = useRef(null);
    const stageRef = useRef(null);
    const elementRefs = useRef({});

    // Use our custom hooks
    const {
        selectedElementId,
        setSelectedElementId,
        handleElementSelect,
        handleStageClick: baseHandleStageClick,
    } = useElementSelection(emitter, timelineElements);

    const { guideLines, handleDragMove, handleDragEnd, createDragBoundFunc, handleTransform, clearGuideLines } = useElementTransform(
        timelineElements,
        dimensions,
        onElementUpdate,
        elementRefs,
    );

    // Enhanced stage click handler that also clears guide lines
    const handleStageClick = (e) => {
        baseHandleStageClick(e);
        if (e.target === e.target.getStage()) {
            clearGuideLines();
        }
    };

    // Update transformer when selection changes
    useEffect(() => {
        if (transformerRef.current) {
            const selectedNode = selectedElementId ? elementRefs.current[selectedElementId] : null;

            if (selectedNode) {
                transformerRef.current.nodes([selectedNode]);
                transformerRef.current.getLayer().batchDraw();
            } else {
                transformerRef.current.nodes([]);
            }
        }
    }, [selectedElementId, activeElements]);

    return (
        <div className="relative">
            <Stage width={dimensions.width} height={dimensions.height} ref={stageRef} onClick={handleStageClick} onTap={handleStageClick}>
                <Layer ref={layerRef}>
                    {activeElements.map((element) => {
                        const isSelected = selectedElementId === element.id;

                        if (element.type === 'video') {
                            const imageSource = getImageSource(element, videoStates, isPlaying);

                            if (!imageSource) {
                                return null;
                            }

                            return (
                                <Image
                                    key={element.id}
                                    ref={(node) => {
                                        if (node) {
                                            elementRefs.current[element.id] = node;
                                        }
                                    }}
                                    image={imageSource}
                                    // Use center position for x,y when offset is set
                                    x={element.x + element.width / 2}
                                    y={element.y + element.height / 2}
                                    width={element.width}
                                    height={element.height}
                                    // Set offset to center for proper rotation
                                    offsetX={element.width / 2}
                                    offsetY={element.height / 2}
                                    rotation={element.rotation || 0}
                                    draggable
                                    dragBoundFunc={createDragBoundFunc(element.id)}
                                    onClick={() => handleElementSelect(element.id)}
                                    onTap={() => handleElementSelect(element.id)}
                                    onDragMove={(e) => handleDragMove(element.id, e)}
                                    onDragEnd={(e) => handleDragEnd(element.id, e)}
                                    onTransform={() => handleTransform(element.id)}
                                    // Visual feedback for selection
                                    stroke={isSelected ? '#0066ff' : undefined}
                                    strokeWidth={isSelected ? 2 : 0}
                                    strokeScaleEnabled={false}
                                />
                            );
                        } else if (element.type === 'text') {
                            return (
                                <Group key={element.id}>
                                    <Text
                                        ref={(node) => {
                                            if (node) {
                                                elementRefs.current[element.id] = node;
                                            }
                                        }}
                                        text={element.text}
                                        x={element.x}
                                        y={element.y}
                                        fontSize={element.fontSize}
                                        fontStyle={getTextFontStyle(element)}
                                        fontFamily={element.fontFamily || 'Arial'}
                                        fill={element.fill || '#ffffff'}
                                        stroke={element.strokeWidth > 0 ? element.stroke || '#000000' : undefined}
                                        strokeWidth={element.strokeWidth * 3 || 0}
                                        fillAfterStrokeEnabled={true}
                                        strokeScaleEnabled={false}
                                        rotation={element.rotation || 0}
                                        // Center the text horizontally
                                        align="center"
                                        verticalAlign="middle"
                                        // Let text have natural width and height for multiline support
                                        wrap="word"
                                        // Always scale 1 - size changes go through fontSize
                                        scaleX={1}
                                        scaleY={1}
                                        draggable
                                        dragBoundFunc={createDragBoundFunc(element.id)}
                                        onClick={() => handleElementSelect(element.id)}
                                        onTap={() => handleElementSelect(element.id)}
                                        onDragMove={(e) => handleDragMove(element.id, e)}
                                        onDragEnd={(e) => handleDragEnd(element.id, e)}
                                        onTransform={() => handleTransform(element.id)}
                                        // Apply fixedWidth and offsetX if they exist
                                        width={element.fixedWidth}
                                        offsetX={element.offsetX}
                                        // Visual feedback for selection
                                    />

                                    {/* Edit button - only show when this text element is selected */}
                                    {isSelected && (
                                        <Html
                                            groupProps={{
                                                x: element.x - (element.offsetX || 0),
                                                y: element.y - 50,
                                            }}
                                            divProps={{
                                                style: {
                                                    zIndex: 10,
                                                },
                                            }}
                                        >
                                            <Button
                                                size="icon"
                                                className="h-12 w-12 rounded-full border shadow-sm"
                                                onClick={() => {
                                                    handleElementSelect(element.id);
                                                    onOpenTextSidebar();
                                                }}
                                            >
                                                <Type className="h-8 w-8" />
                                            </Button>
                                        </Html>
                                    )}
                                </Group>
                            );
                        } else if (element.type === 'image' && element.imageElement && element.isImageReady) {
                            return (
                                <Image
                                    key={element.id}
                                    ref={(node) => {
                                        if (node) {
                                            elementRefs.current[element.id] = node;
                                        }
                                    }}
                                    image={element.imageElement}
                                    // Use center position for x,y when offset is set
                                    x={element.x + element.width / 2}
                                    y={element.y + element.height / 2}
                                    width={element.width}
                                    height={element.height}
                                    // Set offset to center for proper rotation
                                    offsetX={element.width / 2}
                                    offsetY={element.height / 2}
                                    rotation={element.rotation || 0}
                                    draggable
                                    dragBoundFunc={createDragBoundFunc(element.id)}
                                    onClick={() => handleElementSelect(element.id)}
                                    onTap={() => handleElementSelect(element.id)}
                                    onDragMove={(e) => handleDragMove(element.id, e)}
                                    onDragEnd={(e) => handleDragEnd(element.id, e)}
                                    onTransform={() => handleTransform(element.id)}
                                    // Visual feedback for selection
                                    stroke={isSelected ? '#0066ff' : undefined}
                                    strokeWidth={isSelected ? 2 : 0}
                                    strokeScaleEnabled={false}
                                />
                            );
                        }
                        return null;
                    })}

                    {/* Guide Lines Layer */}
                    {guideLines.showVertical && (
                        <Line
                            points={[guideLines.vertical, 0, guideLines.vertical, dimensions.height]}
                            stroke="#0066ff"
                            strokeWidth={1}
                            dash={[4, 4]}
                            opacity={0.8}
                            listening={false}
                        />
                    )}
                    {guideLines.showHorizontal && (
                        <Line
                            points={[0, guideLines.horizontal, dimensions.width, guideLines.horizontal]}
                            stroke="#0066ff"
                            strokeWidth={1}
                            dash={[4, 4]}
                            opacity={0.8}
                            listening={false}
                        />
                    )}

                    {/* Transformer for selected element */}
                    <Transformer
                        ref={transformerRef}
                        boundBoxFunc={(oldBox, newBox) => {
                            // Limit resize to prevent elements from becoming too small
                            if (newBox.width < 20 || newBox.height < 20) {
                                return oldBox;
                            }
                            return newBox;
                        }}
                        // Transformer styling - Figma-like appearance
                        borderStroke="#0066ff"
                        borderStrokeWidth={2}
                        anchorStroke="#0066ff"
                        anchorFill="white"
                        anchorSize={14}
                        anchorCornerRadius={2}
                        // Enable only corner anchors for aspect ratio
                        enabledAnchors={['top-left', 'top-right', 'bottom-right', 'bottom-left']}
                        // Rotation handle
                        rotateAnchorOffset={30}
                        // Built-in Konva rotation snapping
                        rotationSnaps={[0, 90, 180, 270]}
                        rotationSnapTolerance={8}
                        // Clear guide lines when transform ends
                        onTransformEnd={clearGuideLines}
                        // Style the rotation anchor to be circular
                        anchorStyleFunc={(anchor) => {
                            if (anchor.hasName('.rotater')) {
                                // Make it circular by setting corner radius to half the width
                                anchor.cornerRadius(anchor.width() / 2);
                                anchor.fill('#0066ff');
                                anchor.stroke('white');
                                anchor.strokeWidth(1);
                            }
                        }}
                    />
                </Layer>
            </Stage>
        </div>
    );
};

export default VideoPreview;
