import { Button } from '@/components/ui/button';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import useAdminVideoTimelineStore from '@/stores/AdminVideoTimelineStore';
import { ZoomInIcon, ZoomOutIcon } from 'lucide-react';
import React, { useEffect, useRef, useState } from 'react';

const VideoTimelineViewer = () => {
    const [videoUuid, setVideoUuid] = useState('c4fd0601-cac7-483b-907e-0ae4c108d3b1');
    const [zoomLevel, setZoomLevel] = useState(100); // Default zoom level (100%)
    const { getVideoTimelines, videoTimelines, isLoadingVideoTimelines } = useAdminVideoTimelineStore();
    const timelineContainerRef = useRef(null);

    // Define a dark theme for tooltips
    const tooltipStyle = {
        content: 'p-2 bg-gray-800 border border-gray-700 rounded shadow-md z-50 text-white',
        text: 'text-white',
        highlight: 'text-white font-semibold',
    };

    // Define an array of 20 distinct Tailwind background colors
    const colorPresets = [
        'bg-blue-500', // Blue
        'bg-green-500', // Green
        'bg-purple-500', // Purple
        'bg-red-500', // Red
        'bg-yellow-500', // Yellow
        'bg-pink-500', // Pink
        'bg-indigo-500', // Indigo
        'bg-teal-500', // Teal
        'bg-orange-500', // Orange
        'bg-cyan-500', // Cyan
        'bg-lime-500', // Lime
        'bg-emerald-500', // Emerald
        'bg-sky-500', // Sky blue
        'bg-violet-500', // Violet
        'bg-fuchsia-500', // Fuchsia
        'bg-rose-500', // Rose
        'bg-amber-500', // Amber
        'bg-blue-600', // Darker blue
        'bg-green-600', // Darker green
        'bg-purple-600', // Darker purple
    ];

    // Use a ref to persist the color map between renders
    const colorMapRef = useRef(new Map());

    // Get color based on element type
    const getElementColor = (type) => {
        // If we've already assigned a color to this type, use it
        if (colorMapRef.current.has(type)) {
            return colorMapRef.current.get(type);
        }

        // Otherwise, assign the next color in the sequence
        const currentCount = colorMapRef.current.size;
        const colorIndex = currentCount % colorPresets.length;
        const newColor = colorPresets[colorIndex];

        // Store the mapping for future use
        colorMapRef.current.set(type, newColor);

        return newColor;
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        if (videoUuid.trim()) {
            getVideoTimelines(videoUuid);
        }
    };

    const handleZoomIn = () => {
        // Use different increments based on current zoom level
        if (zoomLevel < 50) {
            setZoomLevel((prev) => Math.min(prev + 5, 300)); // Smaller steps at low zoom
        } else {
            setZoomLevel((prev) => Math.min(prev + 25, 300)); // Larger steps at normal zoom
        }
    };

    const handleZoomOut = () => {
        // Use different decrements based on current zoom level
        if (zoomLevel <= 50) {
            setZoomLevel((prev) => Math.max(prev - 5, 5)); // Smaller steps at low zoom, min 5%
        } else {
            setZoomLevel((prev) => Math.max(prev - 25, 5)); // Larger steps at normal zoom, min 5%
        }
    };

    // Calculate the maximum duration for scaling
    const getMaxDuration = () => {
        if (!videoTimelines.length) return 7; // Default value

        let maxEnd = 0;
        videoTimelines.forEach((element) => {
            const elementEnd = element.time + element.duration;
            if (elementEnd > maxEnd) {
                maxEnd = elementEnd;
            }
        });

        return maxEnd;
    };

    // Get unique tracks for vertical positioning
    const getTracks = () => {
        if (!videoTimelines.length) return [];

        const tracks = [...new Set(videoTimelines.map((element) => element.track))];
        return tracks.sort((a, b) => b - a); // Sort in descending order
    };

    // Get track information for tooltips
    const getTrackInfo = (trackNum) => {
        const trackElements = videoTimelines.filter((element) => element.track === trackNum);

        if (trackElements.length === 0) {
            return { count: 0, duration: 0, startTime: 0, endTime: 0 };
        }

        let totalDuration = 0;
        let minStartTime = Infinity;
        let maxEndTime = 0;

        trackElements.forEach((element) => {
            totalDuration += element.duration;
            if (element.time < minStartTime) minStartTime = element.time;
            const endTime = element.time + element.duration;
            if (endTime > maxEndTime) maxEndTime = endTime;
        });

        return {
            count: trackElements.length,
            duration: totalDuration,
            startTime: minStartTime,
            endTime: maxEndTime,
            elements: trackElements,
        };
    };

    // Keep track of previous zoom level to calculate proper scrolling
    const prevZoomRef = useRef(zoomLevel);

    // Scroll timeline to position when zoom changes
    useEffect(() => {
        if (timelineContainerRef.current && videoTimelines.length > 0) {
            const container = timelineContainerRef.current;
            const prevZoom = prevZoomRef.current;

            // Calculate the center point of the current view
            const viewportWidth = container.clientWidth;
            const scrollLeft = container.scrollLeft;
            const centerPoint = scrollLeft + viewportWidth / 2;

            // Calculate what percentage of the timeline this center point represents
            const timelineWidth = container.firstChild.offsetWidth;
            const centerPercentage = centerPoint / ((timelineWidth * prevZoom) / zoomLevel);

            // Calculate the new scroll position to keep that same percentage in the center
            const newTimelineWidth = timelineWidth;
            const newCenterPoint = centerPercentage * newTimelineWidth;
            const newScrollPosition = newCenterPoint - viewportWidth / 2;

            // Update the scroll position
            requestAnimationFrame(() => {
                container.scrollLeft = Math.max(0, newScrollPosition);
            });

            // Save current zoom for next comparison
            prevZoomRef.current = zoomLevel;
        }
    }, [zoomLevel, videoTimelines.length]);

    // Get label based on external reference
    const getElementLabel = (element) => {
        if (element.external_reference) {
            return element.external_reference.replace(/_/g, ' ');
        }
        return element.type;
    };

    // Calculate time scale factor based on zoom level
    const getTimeScaleFactor = () => {
        // At 100%, scale factor is 1
        // Below 100%, scale shrinks proportionally
        // Above 100%, scale grows proportionally
        return zoomLevel / 100;
    };

    const maxDuration = getMaxDuration();
    const tracks = getTracks();
    const trackHeight = 40; // Height of each track row
    const timelineHeight = tracks.length * trackHeight;

    return (
        <Card className="mx-auto w-full shadow-lg">
            <CardHeader>
                <CardTitle className="text-xl font-semibold">Video UUID</CardTitle>
            </CardHeader>
            <CardContent>
                <form onSubmit={handleSubmit} className="flex flex-col space-y-2 sm:flex-row sm:space-y-0 sm:space-x-2">
                    <Input
                        type="text"
                        placeholder="Enter video UUID..."
                        value={videoUuid}
                        onChange={(e) => setVideoUuid(e.target.value)}
                        className="flex-1"
                    />
                    <Button type="submit" disabled={isLoadingVideoTimelines} className="w-full sm:w-auto">
                        {isLoadingVideoTimelines ? 'Loading...' : 'Submit'}
                    </Button>
                </form>
            </CardContent>

            <Separator className="my-2" />

            <CardContent className="pb-6">
                <div className="mt-4">
                    <h3 className="mb-2 font-medium">Timeline Preview</h3>

                    {/* Zoom controls */}
                    <div className="mb-2 flex items-center justify-between">
                        <div className="flex items-center space-x-2">
                            <Button
                                size="sm"
                                variant="outline"
                                className="h-8 w-8 p-0"
                                onClick={handleZoomOut}
                                disabled={zoomLevel <= 5}
                                title="Zoom out"
                            >
                                <ZoomOutIcon className="h-4 w-4" />
                            </Button>
                            <span className="text-xs">{zoomLevel}%</span>
                            <Button
                                size="sm"
                                variant="outline"
                                className="h-8 w-8 p-0"
                                onClick={handleZoomIn}
                                disabled={zoomLevel >= 300}
                                title="Zoom in"
                            >
                                <ZoomInIcon className="h-4 w-4" />
                            </Button>
                        </div>
                        <div className="text-xs text-gray-500">
                            <span>Adjust zoom to change timeline scale</span>
                        </div>
                    </div>

                    {/* Timeline container with horizontal scroll for small screens */}
                    <div className="overflow-x-auto" ref={timelineContainerRef}>
                        <div
                            className="min-w-[640px]"
                            style={
                                {
                                    // We don't scale the container width with zoom anymore
                                    // Instead we scale the individual elements inside
                                }
                            }
                        >
                            {/* Timeline header - time markers with tick marks */}
                            <div className="flex h-8 border-b border-gray-200 text-xs text-gray-500">
                                <div className="w-16 flex-shrink-0 pr-2 font-medium sm:w-20">Track</div>
                                <div className="relative flex-1">
                                    {/* Vertical guideline marks at each second */}
                                    {Array.from({ length: Math.ceil(maxDuration) + 1 }).map((_, i) => {
                                        const scaleFactor = zoomLevel / 100;
                                        const baseWidth = 100; // Base width in pixels at 100% zoom
                                        const position = i * baseWidth * scaleFactor;

                                        return (
                                            <React.Fragment key={i}>
                                                <div
                                                    className="absolute h-full border-l border-gray-200"
                                                    style={{
                                                        left: `${position}px`,
                                                        height: `${timelineHeight + 20}px`,
                                                        top: '16px',
                                                        zIndex: 0,
                                                    }}
                                                />
                                                <div
                                                    className="absolute -mx-1 text-start"
                                                    style={{
                                                        left: `${position}px`,
                                                        width: `${baseWidth * scaleFactor}px`,
                                                    }}
                                                >
                                                    {i}s
                                                </div>
                                            </React.Fragment>
                                        );
                                    })}
                                </div>
                            </div>

                            <div
                                className="relative"
                                style={{
                                    height: `${timelineHeight}px`,
                                    paddingLeft: '0px', // Remove any padding that might affect alignment
                                }}
                            >
                                {/* Track rows */}
                                {tracks.map((trackNum, index) => {
                                    const trackInfo = getTrackInfo(trackNum);

                                    return (
                                        <div
                                            key={trackNum}
                                            className="absolute flex w-full items-center border-b border-gray-100"
                                            style={{
                                                top: `${index * trackHeight}px`,
                                                height: `${trackHeight}px`,
                                                zIndex: 1, // Ensure track labels are above elements
                                            }}
                                        >
                                            <TooltipProvider>
                                                <Tooltip>
                                                    <TooltipTrigger asChild>
                                                        <button className="w-16 flex-shrink-0 cursor-help bg-white pr-2 text-left text-xs font-medium transition-colors hover:bg-gray-50 sm:w-20">
                                                            Track {trackNum}
                                                        </button>
                                                    </TooltipTrigger>
                                                    <TooltipContent
                                                        side="right"
                                                        sideOffset={5}
                                                        className="z-50 rounded border border-gray-700 bg-gray-800 p-3 text-white shadow-md"
                                                    >
                                                        <div className="space-y-1 text-sm">
                                                            <p className="font-semibold">Track {trackNum}</p>
                                                            <p>Elements: {trackInfo.count}</p>
                                                            <p>Total duration: {trackInfo.duration.toFixed(2)}s</p>
                                                            {trackInfo.count > 0 && (
                                                                <>
                                                                    <p>Start time: {trackInfo.startTime.toFixed(2)}s</p>
                                                                    <p>End time: {trackInfo.endTime.toFixed(2)}s</p>
                                                                </>
                                                            )}
                                                        </div>
                                                    </TooltipContent>
                                                </Tooltip>
                                            </TooltipProvider>
                                        </div>
                                    );
                                })}

                                {/* Timeline elements */}
                                {videoTimelines.map((element) => {
                                    const trackIndex = tracks.indexOf(element.track);
                                    const scaleFactor = zoomLevel / 100;
                                    const baseWidth = 100; // Base width of 1 second at 100% zoom

                                    // Position from the exact timeline start (after the track label)
                                    const trackLabelWidth = 64; // 16rem = 64px on small screens, 80px on larger
                                    const exactStartPosition = element.time * baseWidth * scaleFactor;
                                    const startPosition = trackLabelWidth + exactStartPosition;
                                    const elementWidth = element.duration * baseWidth * scaleFactor;

                                    return (
                                        <TooltipProvider key={element.id}>
                                            <Tooltip>
                                                <TooltipTrigger asChild>
                                                    <div
                                                        className={`absolute ml-4 cursor-pointer rounded px-1 text-xs text-white ${getElementColor(element.external_reference)} flex items-center hover:opacity-90`}
                                                        style={{
                                                            top: `${trackIndex * trackHeight + 5}px`,
                                                            left: `${startPosition}px`,
                                                            width: `${Math.max(2, elementWidth - 1)}px`, // Subtract 1px to create spacing, min 2px
                                                            height: `${trackHeight - 10}px`,
                                                            overflow: 'hidden',
                                                            whiteSpace: 'nowrap',
                                                            textOverflow: 'ellipsis',
                                                            minWidth: zoomLevel < 20 ? '2px' : zoomLevel < 50 ? '10px' : '30px', // Adaptive minimum width
                                                            marginRight: '1px', // Add 1px space between elements
                                                            zIndex: 2, // Ensure elements are above track rows
                                                        }}
                                                    >
                                                        {getElementLabel(element)}
                                                    </div>
                                                </TooltipTrigger>
                                                <TooltipContent
                                                    side="top"
                                                    sideOffset={5}
                                                    className="z-50 rounded border border-gray-700 bg-gray-800 p-2 text-white shadow-md"
                                                >
                                                    <div className="space-y-1 text-sm">
                                                        <p className="font-semibold">{getElementLabel(element)}</p>
                                                        <p>Type: {element.type}</p>
                                                        <p>Track: {element.track}</p>
                                                        <p>Start: {element.time.toFixed(2)}s</p>
                                                        <p>Duration: {element.duration.toFixed(2)}s</p>
                                                        <p>End: {(element.time + element.duration).toFixed(2)}s</p>
                                                        {element.id && <p>ID: {element.id}</p>}
                                                    </div>
                                                </TooltipContent>
                                            </Tooltip>
                                        </TooltipProvider>
                                    );
                                })}
                            </div>
                        </div>
                    </div>
                </div>

                {/* Element details section */}
                <div className="mt-4">
                    <h3 className="mb-2 font-medium">Element Details</h3>
                    <div className="overflow-auto rounded border border-gray-200" style={{ maxHeight: '40vh' }}>
                        <table className="min-w-full divide-y divide-gray-200">
                            <thead className="sticky top-0 bg-gray-50">
                                <tr>
                                    <th className="px-2 py-2 text-left text-xs font-medium text-gray-500 sm:px-4">ID</th>
                                    <th className="px-2 py-2 text-left text-xs font-medium text-gray-500 sm:px-4">Type</th>
                                    <th className="px-2 py-2 text-left text-xs font-medium text-gray-500 sm:px-4">Reference</th>
                                    <th className="px-2 py-2 text-left text-xs font-medium text-gray-500 sm:px-4">Time</th>
                                    <th className="px-2 py-2 text-left text-xs font-medium text-gray-500 sm:px-4">Duration</th>
                                    <th className="px-2 py-2 text-left text-xs font-medium text-gray-500 sm:px-4">Track</th>
                                </tr>
                            </thead>
                            <tbody className="divide-y divide-gray-200 bg-white">
                                {videoTimelines.map((element) => (
                                    <tr key={element.id} className="hover:bg-gray-50">
                                        <td className="px-2 py-2 text-xs whitespace-nowrap sm:px-4">{element.id}</td>
                                        <td className="px-2 py-2 text-xs whitespace-nowrap sm:px-4">{element.type}</td>
                                        <td className="px-2 py-2 text-xs whitespace-nowrap sm:px-4">
                                            <span
                                                className={`inline-block h-3 w-3 rounded-full ${getElementColor(element.external_reference)}`}
                                            ></span>{' '}
                                            {element.external_reference}
                                        </td>
                                        <td className="px-2 py-2 text-xs whitespace-nowrap sm:px-4">{element.time}s</td>
                                        <td className="px-2 py-2 text-xs whitespace-nowrap sm:px-4">{element.duration}s</td>
                                        <td className="px-2 py-2 text-xs whitespace-nowrap sm:px-4">{element.track}</td>
                                    </tr>
                                ))}
                                {videoTimelines.length === 0 && (
                                    <tr>
                                        <td colSpan="6" className="py-4 text-center text-sm text-gray-500">
                                            No timeline data available
                                        </td>
                                    </tr>
                                )}
                            </tbody>
                        </table>
                    </div>
                </div>
            </CardContent>

            <CardFooter className="flex flex-col gap-2 py-2 sm:flex-row sm:justify-between">
                <div className="flex flex-wrap gap-2 text-xs text-gray-500">
                    {/* Dynamically generate color legend based on types that appear in the data */}
                    {Array.from(colorMapRef.current.entries()).map(([type, color]) => (
                        <div key={type} className="flex items-center">
                            <span className={`mr-1 inline-block h-3 w-3 rounded-full ${color}`}></span>
                            {type}
                        </div>
                    ))}
                    {colorMapRef.current.size === 0 && (
                        <>
                            <div className="flex items-center">
                                <span className="mr-1 inline-block h-3 w-3 rounded-full bg-blue-500"></span>
                                No elements
                            </div>
                        </>
                    )}
                </div>
                <div className="flex items-center gap-2">
                    <p className="text-xs text-gray-400">Total elements: {videoTimelines.length}</p>
                    <div className="text-xs text-gray-400">|</div>
                    <p className="text-xs text-gray-400">Zoom: {zoomLevel}%</p>
                </div>
            </CardFooter>
        </Card>
    );
};

export default VideoTimelineViewer;
