"use client"
import React, { useRef, useEffect, useState, useCallback } from "react";
import { Calendar } from "@/components/ui/calendar"
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from "@/components/ui/popover"
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuLabel,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { CalendarIcon, ChevronLeft, ChevronRight, Clock, Dog, HomeIcon, LockIcon, MoreHorizontal, Pause, Play, Rabbit, RefreshCwIcon, Turtle, UnlockIcon } from "lucide-react";
import { formatInTimeZone } from "date-fns-tz";
import { parse } from "date-fns"

import { useTimeline } from "@/hooks/use-timeline";
import { Timeline as TimelineEngine, ZoomMode, TimelineConfig } from "@/lib/timeline";
import { Separator } from "@/components/ui/separator";
import { useWS } from "./ws-context";
import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select";
import { useIsMobile } from "@/hooks/use-mobile";
import { Label } from "@/components/ui/label";


interface Uniforms {
    startTimestamp: number;  // Unix 时间戳开始
    endTimestamp: number;    // Unix 时间戳结束 
    currentTimestamp: number; // 当前时间戳
    radius: number;
    d: number;
    timelineStartX: number;  // 时间轴在屏幕上的开始X坐标
    timelineEndX: number;    // 时间轴在屏幕上的结束X坐标
    viewportSize: [number, number];
    zoomLevel: number;       // 当前缩放级别
    panOffset: number;       // 当前平移偏移
}

interface Instants {
    position: Float32Array;
    color: Float32Array;
}

interface VesicaDataPoint {
    timestamp: number; // Unix 时间戳
    color?: [number, number, number, number]; // RGBA 颜色，默认为白色
}

interface Props extends React.HTMLAttributes<HTMLDivElement> {
    boxSize?: [number, number];
    startDate?: Date;
    endDate?: Date;
    currentDate?: Date;
    onDateChange?: (date: Date) => void;
    onPlay?: () => void;
    onPause?: () => void;
    minZoom?: number;  // 最小缩放级别
    maxZoom?: number;  // 最大缩放级别
    initialZoom?: number;  // 初始缩放级别
    vesicaData?: VesicaDataPoint[]; // vesica 实例数据
    dateFormat?: (timestamp: number) => string; // 自定义时间格式化函数
    timelineConfig?: TimelineConfig; // 时间轴配置
    imageUrlGenerator?: (timestamp: number) => string; // 图像URL生成函数
}

export const Timeline: React.FC<Props> = React.memo(({
    startDate,
    endDate,
    currentDate,
    onDateChange,
    onPlay,
    onPause,
    boxSize = [4, 8],
    minZoom = 0.5,
    maxZoom = 8,
    initialZoom = 1,
    vesicaData,
    dateFormat,
    timelineConfig,
    imageUrlGenerator,
    ...props
}) => {
    const { isPlaying, togglePlay, setTime, setTimelineTime, setWsStatus } = useTimeline({})
    const [lock, setLock] = useState(false)
    const canvasRef = useRef<HTMLCanvasElement>(null);
    const ticksCanvasRef = useRef<HTMLCanvasElement>(null);
    const timelineEngineRef = useRef<TimelineEngine | null>(null);
    const [timeStep, setTimeStep] = useState(360000);
    const [viewportInfo, setViewportInfo] = useState({
        centerTime: 0,
        timeRange: 0,
        visibleRange: [0, 0] as [number, number],
        currentLevel: null as any
    });
    const [open, setOpen] = useState(false)
    const [time, setDateTime] = useState(new Date())
    const [speed, setSpeed] = useState(1)

    // WebGL纹理管理
    const glRef = useRef<WebGL2RenderingContext | null>(null)
    const textureRef = useRef<WebGLTexture | null>(null)
    const [textureSize, setTextureSize] = useState<[number, number] | null>(null)
    const lastFrameRef = useRef<ImageBitmap | null>(null)

    const { data } = useWS()
    const isMobile = useIsMobile(1024) // Use lg breakpoint (1024px)

    useEffect(() => {
        if (data) {
            if (data.statusUpdates) {
                if (!lock && data.statusUpdates.newestDt) {
                    const newDt = parse(data.statusUpdates.newestDt + 'Z', 'yyyyMMddHHmmssX', new Date())
                    setTime(newDt)
                    setTimelineTime(newDt)

                    if (timelineEngineRef.current) {
                        timelineEngineRef.current.replaceTimeMarkByTimestamp(newDt.getTime())
                    }
                }
            } else {
            }
        }
    }, [data, lock])


    // 初始化WebGL纹理
    useEffect(() => {
        if (!canvasRef.current) return

        const gl = canvasRef.current.getContext('webgl2')
        if (!gl) {
            console.warn('WebGL2 not supported')
            return
        }

        glRef.current = gl

        // 创建纹理
        const texture = gl.createTexture()
        if (!texture) {
            console.error('Failed to create texture')
            return
        }

        textureRef.current = texture
        gl.bindTexture(gl.TEXTURE_2D, texture)

        // 设置纹理参数
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)

        return () => {
            if (textureRef.current) {
                gl.deleteTexture(textureRef.current)
                textureRef.current = null
            }
        }
    }, [])

    // 处理图像帧更新
    const updateTextureWithFrame = useCallback((imageBitmap: ImageBitmap) => {
        if (!glRef.current || !textureRef.current) return

        const gl = glRef.current
        gl.bindTexture(gl.TEXTURE_2D, textureRef.current)

        // 首次分配纹理存储
        if (!textureSize || textureSize[0] !== imageBitmap.width || textureSize[1] !== imageBitmap.height) {
            gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, imageBitmap.width, imageBitmap.height)
            setTextureSize([imageBitmap.width, imageBitmap.height])
        }

        // 使用texSubImage2D更新纹理数据（零拷贝）
        gl.texSubImage2D(
            gl.TEXTURE_2D,
            0, // level
            0, 0, // xoffset, yoffset  
            gl.RGBA,
            gl.UNSIGNED_BYTE,
            imageBitmap
        )

        // 释放之前的帧
        if (lastFrameRef.current) {
            lastFrameRef.current.close()
        }
        lastFrameRef.current = imageBitmap
    }, [textureSize])

    // 定时器效果 - 当播放时每隔指定时间执行操作
    useEffect(() => {
        let intervalId: NodeJS.Timeout | null = null;

        if (isPlaying && speed > 0) {
            intervalId = setInterval(() => {
                // 执行时间前进操作
                if (timelineEngineRef.current) {
                    timelineEngineRef.current.playAndEnsureMarkInView(timeStep)

                }
            }, 600 / speed);
        }

        return () => {
            if (intervalId) {
                clearInterval(intervalId);
            }
        };
    }, [isPlaying, timeStep, speed, imageUrlGenerator, updateTextureWithFrame]);

    useEffect(() => {
        if (!ticksCanvasRef.current) return;

        const canvas = ticksCanvasRef.current;

        // 计算初始时间范围
        const now = Date.now();
        const defaultStartTime = startDate ? startDate.getTime() : now - 24 * 60 * 60 * 1000; // 默认24小时前
        const defaultEndTime = endDate ? endDate.getTime() : now + 24 * 60 * 60 * 1000; // 默认24小时后
        const defaultCenterTime = currentDate ? currentDate.getTime() : now;

        // 合并配置
        const config: TimelineConfig = {
            initialCenterTime: defaultCenterTime,
            highlightWeekends: false,
            zoomMode: ZoomMode.MousePosition,
            zoomSensitivity: 0.001,
            colors: {
                background: 'transparent', // 使用透明背景，让父容器背景显示
                grid: '#333333',
                majorTick: '#cccccc',
                minorTick: '#cccccc',
                primaryLabel: '#b4b4b4',
                secondaryLabel: '#b4b4b4',
                currentTime: '#ff0000'
            },
            sizes: {
                majorTickHeight: 8,
                minorTickHeight: 4,
                labelOffset: 3,
                primaryFontSize: 10,
                secondaryFontSize: 10
            },
            discreteZoomLevels: [
                604123.3009862272,
                383869.5109421124,
                167314.88060646105,
                64314.3439546868,
                24625.670894409748,
                4964.7447283082365,
            ],
            initialZoomLevel: 4964.7447283082365,
            onDateChange: async (date: Date) => {
                const datestr = formatInTimeZone(date, 'UTC', 'yyyyMMddHHmmss')
                const url_base = process.env.NEXT_PUBLIC_GRAPHQL_BACKEND_URL?.replace('/graphql', '') || 'http://localhost:3050'
                const response = await fetch(`${url_base}/api/v1/data/nearest?datetime=${datestr}&area=cn`)

                setTimelineTime(date)
                if (response.ok) {
                    const data = await response.json()
                    const nearestDatetime = data.nearest_data_time
                    const nearestDate = new Date(Date.parse(nearestDatetime))
                    setTime(nearestDate)
                } else {
                    console.error('Failed to fetch data:', response.status)
                }
            },
            ...timelineConfig
        };

        try {
            timelineEngineRef.current = new TimelineEngine(canvas, config);
            const updateViewportInfo = () => {
                if (timelineEngineRef.current) {
                    const info = timelineEngineRef.current.getViewportInfo();
                    setViewportInfo(info);

                    if (onDateChange) {
                        onDateChange(new Date(info.centerTime));
                    }
                }
            };

            const interval = setInterval(updateViewportInfo, 100);

            return () => {
                clearInterval(interval);
                if (timelineEngineRef.current) {
                    timelineEngineRef.current.destroy();
                    timelineEngineRef.current = null;
                }
            };
        } catch (error) {
            console.error('Failed to initialize timeline engine:', error);
        }
    }, [startDate, endDate, currentDate, initialZoom, timelineConfig, onDateChange, imageUrlGenerator, timeStep]);

    // 处理画布大小变化
    useEffect(() => {
        const handleResize = () => {
            if (timelineEngineRef.current && ticksCanvasRef.current) {
                timelineEngineRef.current.render();
            }
        };

        window.addEventListener('resize', handleResize);
        return () => window.removeEventListener('resize', handleResize);
    }, []);

    const handleHome = useCallback(() => {
        if (timelineEngineRef.current) {
            timelineEngineRef.current.goToTime(new Date().getTime())
        }
    }, []);

    // 控制按钮功能
    const handlePrevious = useCallback(() => {
        if (timelineEngineRef.current) {
            timelineEngineRef.current.playBackwardAndEnsureMarkInView(timeStep)
        }
    }, [timeStep, imageUrlGenerator, updateTextureWithFrame]);

    const handleNext = useCallback(() => {
        if (timelineEngineRef.current) {
            timelineEngineRef.current.playAndEnsureMarkInView(timeStep)
        }
    }, [timeStep, imageUrlGenerator, updateTextureWithFrame]);

    const handleRefresh = useCallback(async () => {
        if (timelineEngineRef.current) {

            const date = new Date()
            const datestr = formatInTimeZone(date, 'UTC', 'yyyyMMddHHmmss')
            const url_base = process.env.NEXT_PUBLIC_GRAPHQL_BACKEND_URL || 'http://localhost:3050'
            // const url_base = "http://45.152.65.37:3050"
            const response = await fetch(`${url_base}/api/v1/data/nearest?datetime=${datestr}&area=cn`)
            if (response.ok) {
                const data = await response.json()
                const nearestDatetime = data.nearest_data_time
                const nearestDate = new Date(Date.parse(nearestDatetime))
                setTime(nearestDate)
                timelineEngineRef.current.replaceTimeMarkByTimestamp(nearestDate.getTime())
                timelineEngineRef.current.ensureMarkInView()
            } else {
                console.error('Failed to fetch data:', response.status)
            }

        }
    }, []);

    return (
        <div className={
            cn(props.className, "w-full flex flex-col lg:flex-row lg:h-10")}>
            {/* Controls row - always visible, responsive layout */}
            <div className={cn("flex flex-row items-center px-3 gap-2 bg-black/30 h-10 lg:h-full min-w-0", isMobile ? "justify-center" : "")}>
                {/* Primary controls - always visible */}
                <div className="flex flex-row items-center gap-2 flex-shrink-0">
                    {isMobile && (
                        <DropdownMenu>
                            <DropdownMenuTrigger asChild>
                                <Button
                                    variant="secondary"
                                    size="icon"
                                    className="size-5"
                                    title="更多选项"
                                >
                                    <MoreHorizontal size={10} />
                                </Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent align="end">
                                <DropdownMenuLabel>播放控制</DropdownMenuLabel>
                                <DropdownMenuItem onClick={() => setSpeed(1)}>
                                    播放速度: 1x {speed === 1 && "✓"}
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={() => setSpeed(2)}>
                                    播放速度: 2x {speed === 2 && "✓"}
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={() => setSpeed(3)}>
                                    播放速度: 3x {speed === 3 && "✓"}
                                </DropdownMenuItem>
                                <DropdownMenuSeparator />
                                <DropdownMenuLabel>时间间隔</DropdownMenuLabel>
                                <DropdownMenuItem onClick={() => setTimeStep(60000)}>
                                    1分钟 {timeStep === 60000 && "✓"}
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={() => setTimeStep(360000)}>
                                    6分钟 {timeStep === 360000 && "✓"}
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={() => setTimeStep(3600000)}>
                                    1小时 {timeStep === 3600000 && "✓"}
                                </DropdownMenuItem>
                                <DropdownMenuSeparator />
                                <DropdownMenuItem onClick={() => setLock(!lock)}>
                                    {lock ? <UnlockIcon size={14} className="mr-2" /> : <LockIcon size={14} className="mr-2" />}
                                    {lock ? "解锁时间" : "锁定时间"}
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={handleRefresh}>
                                    <RefreshCwIcon size={14} className="mr-2" />
                                    刷新数据
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={() => setOpen(true)}>
                                    <CalendarIcon size={14} className="mr-2" />
                                    设置时间
                                </DropdownMenuItem>
                            </DropdownMenuContent>
                        </DropdownMenu>
                    )}
                    <Button
                        variant="secondary"
                        size="icon"
                        className="size-5"
                        onClick={handlePrevious}
                        title="上一个时间段"
                    >
                        <ChevronLeft size={10} />
                    </Button>

                    <Button
                        variant={isPlaying ? "default" : "secondary"}
                        size="icon"
                        className="size-5"
                        onClick={() => {
                            togglePlay()
                            setLock(true)
                        }}
                        title={isPlaying ? "暂停" : "播放"}
                    >
                        {isPlaying ? <Pause size={10} /> : <Play size={10} />}
                    </Button>

                    <Button
                        variant="secondary"
                        size="icon"
                        className="size-5"
                        onClick={handleNext}
                        title="下一个时间段"
                    >
                        <ChevronRight size={10} />
                    </Button>

                    <Button
                        variant="secondary"
                        size="icon"
                        className="size-5"
                        onClick={handleHome}
                        title="回到当前时间"
                    >
                        <HomeIcon size={10} />
                    </Button>
                </div>

                {!isMobile && (
                    <div className="hidden sm:flex flex-row items-center gap-2 ml-2">
                        <select
                            defaultValue="1"
                            className="w-12 h-6 text-xs bg-background border border-input rounded px-2 focus:outline-none focus:ring-2 focus:ring-ring"
                            onChange={(e) => {
                                const value = e.target.value;
                                setSpeed(parseInt(value));
                            }}
                            style={{ fontSize: '10px' }}
                        >
                            <option value="1">1x</option>
                            <option value="2">2x</option>
                            <option value="3">3x</option>
                        </select>

                        <Separator orientation="vertical" className="h-4" />

                        <select
                            defaultValue="360000"
                            className="w-16 md:w-20 h-6 text-xs bg-background border border-input rounded px-2 focus:outline-none focus:ring-2 focus:ring-ring"
                            onChange={(e) => {
                                const value = e.target.value;
                                setTimeStep(parseInt(value));
                            }}
                            style={{ fontSize: '10px' }}
                        >
                            <option value="60000">1分钟</option>
                            <option value="360000">6分钟</option>
                            <option value="600000">10分钟</option>
                            <option value="1800000">30分钟</option>
                            <option value="3600000">1小时</option>
                            <option value="7200000">2小时</option>
                            <option value="86400000">1天</option>
                        </select>
                    </div>
                )}

                {!isMobile && (
                    <div className="hidden md:flex flex-row items-center gap-2 ml-2">
                        <Button
                            variant={lock ? "default" : "secondary"}
                            size="icon"
                            className="size-5"
                            onClick={() => setLock(!lock)}
                            title="锁定时间"
                        >
                            {lock ? <LockIcon size={10} /> : <UnlockIcon size={10} />}
                        </Button>

                        <Button
                            variant="secondary"
                            size="icon"
                            className="size-5"
                            onClick={() => {
                                handleRefresh()
                            }}
                            title="刷新"
                        >
                            <RefreshCwIcon size={10} />
                        </Button>

                        <Popover open={open} onOpenChange={setOpen}>
                            <PopoverTrigger asChild>
                                <Button
                                    variant="secondary"
                                    size="icon"
                                    className="size-5"
                                    title="设置时间"
                                >
                                    <CalendarIcon size={10} />
                                </Button>
                            </PopoverTrigger>
                            <PopoverContent className="w-auto overflow-hidden p-0" align="end">
                                <div className="relative">
                                    <Calendar
                                        mode="single"
                                        captionLayout="dropdown"
                                        onSelect={(date) => {
                                            setOpen(false)
                                        }}
                                    />
                                    <div className="absolute inset-0 bg-white/20 backdrop-blur-sm flex items-center justify-center">

                                    </div>
                                </div>
                            </PopoverContent>
                        </Popover>
                    </div>
                )}


            </div>

            <div className={cn("relative bg-gray-800/20 h-10 lg:h-full lg:flex-1")}>
                <canvas ref={canvasRef} className="w-full h-full absolute inset-0" />
                <canvas
                    ref={ticksCanvasRef}
                    className="w-full h-full absolute inset-0 select-none"
                    style={{ touchAction: 'manipulation' }}
                />
            </div>
        </div>
    );
});