import { Button } from '@/components/ui/button';
import { useMitt } from '@/plugins/MittContext';
import useVideoEditorStore from '@/stores/VideoEditorStore';
import { Type } from 'lucide-react';
import { useEffect, useRef, useState } 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 } from './video-preview/video-preview-utils';

// Import centralized font management
import { getFontStyle, loadTimelineFonts, WATERMARK_CONFIG } from '@/modules/editor/fonts';

const VideoPreview = ({
    watermarked,
    // 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({});

    // Font loading state
    const [fontsLoaded, setFontsLoaded] = useState(false);
    const [fontLoadingAttempted, setFontLoadingAttempted] = useState(false);

    // Load fonts when timeline elements change
    useEffect(() => {
        const loadFonts = async () => {
            if (timelineElements.length > 0 && !fontLoadingAttempted) {
                setFontLoadingAttempted(true);
                try {
                    await loadTimelineFonts(timelineElements);
                    setFontsLoaded(true);
                    console.log('✅ Fonts loaded in preview');

                    // Force redraw after fonts load to recalculate text dimensions
                    setTimeout(() => {
                        if (layerRef.current) {
                            layerRef.current.batchDraw();
                        }
                    }, 100);
                } catch (error) {
                    console.warn('⚠️ Font loading failed:', error);
                    setFontsLoaded(true); // Continue anyway with fallback fonts
                }
            }
        };

        loadFonts();
    }, [timelineElements, fontLoadingAttempted]);

    // Force text remeasurement when fonts load
    useEffect(() => {
        if (fontsLoaded && layerRef.current) {
            // Find all text nodes and force them to recalculate
            const textNodes = layerRef.current.find('Text');
            textNodes.forEach((textNode) => {
                // Force Konva to recalculate text dimensions
                textNode._setTextData();
                textNode.cache();
                textNode.clearCache();
            });
            layerRef.current.batchDraw();
        }
    }, [fontsLoaded]);

    // 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();
        }
    };

    // Pre-select first text node on load
    useEffect(() => {
        if (activeElements.length > 0 && !selectedElementId) {
            const firstTextElement = activeElements.find((element) => element.type === 'text');
            if (firstTextElement) {
                setSelectedElementId(firstTextElement.id);
            }
        }
    }, [activeElements, selectedElementId, setSelectedElementId]);

    // 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 overflow-hidden rounded-3xl">
            <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}-${fontsLoaded}`}>
                                    <Text
                                        ref={(node) => {
                                            if (node) {
                                                elementRefs.current[element.id] = node;

                                                // Force text measurement after font loading
                                                if (fontsLoaded) {
                                                    setTimeout(() => {
                                                        node._setTextData();

                                                        // Debug log preview text properties
                                                        console.log(`🔍 Preview Text ${element.id} Properties:`);
                                                        console.log('  text:', element.text);
                                                        console.log('  x:', element.x);
                                                        console.log('  y:', element.y);
                                                        console.log('  fontSize:', element.fontSize);
                                                        console.log('  fontFamily:', element.fontFamily);
                                                        console.log('  width (fixedWidth):', element.fixedWidth);
                                                        console.log('  offsetX:', element.offsetX);
                                                        console.log('  node.width():', node.width());
                                                        console.log('  node.height():', node.height());
                                                        console.log('  node.textWidth:', node.textWidth);
                                                        console.log('  node.textHeight:', node.textHeight);

                                                        if (layerRef.current) {
                                                            layerRef.current.batchDraw();
                                                        }
                                                    }, 0);
                                                }
                                            }
                                        }}
                                        text={element.text}
                                        x={element.x}
                                        y={element.y}
                                        fontSize={element.fontSize}
                                        fontStyle={getFontStyle(element)} // Use centralized function
                                        fontFamily={element.fontFamily || 'Montserrat'}
                                        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) - 10,
                                                y: element.y - 70,
                                            }}
                                            divProps={{
                                                style: {
                                                    zIndex: 10,
                                                },
                                            }}
                                        >
                                            <Button
                                                variant="secondary"
                                                id="open-text-editor"
                                                className="h-16 w-16 rounded-full shadow-xl"
                                                onClick={() => {
                                                    handleElementSelect(element.id);
                                                    onOpenTextSidebar();
                                                }}
                                            >
                                                <Type className="size-6" />
                                            </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;
                    })}

                    {/* Watermark - only show when watermarked is true */}
                    {watermarked && (
                        <Text
                            key={`watermark-${fontsLoaded}`}
                            text="memefa.st"
                            x={dimensions.width / 2}
                            y={dimensions.height / 2 + dimensions.height * 0.2}
                            fontSize={WATERMARK_CONFIG.fontSize}
                            fontFamily={WATERMARK_CONFIG.fontFamily}
                            fill={WATERMARK_CONFIG.fill}
                            stroke={WATERMARK_CONFIG.stroke}
                            strokeWidth={WATERMARK_CONFIG.strokeWidth}
                            opacity={WATERMARK_CONFIG.opacity}
                            align="center"
                            verticalAlign="middle"
                            offsetX={90} // Approximate half-width to center the text
                            offsetY={5} // Approximate half-height to center the text
                            draggable={false}
                            listening={false} // Prevents any mouse interactions
                        />
                    )}

                    {/* 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;
