"use client";
import React, { useState, useEffect, useRef, useCallback } from "react";
import EmbedTimeline from "./components/EmbedTimeline";
import VideoPlayer from "./components/VideoPlayer";
// import ModernDateRangeSelector from './components/ModernDateRangeSelector';
import CompactDateRangePicker from "./components/CompactDateRangePicker";
import CustomDateRangePicker from "./components/DateRangePicker";
import "./App.css";
import StatusesDisplayHUD from "./components/StatusDisplay";

function App() {
    const original_data = useRef(null);
    const chartRef = useRef(null);
    const [dataResults, setDataResults] = useState(null);
    const [statusMessages, setStatusMessages] = useState([]);
    const [markerTime, setMarkerTime] = useState(0);
    const playerRef = useRef(null);
    const [drawerOpen, setDrawerOpen] = useState(false);
    const playerInstanceRef = useRef(null);
    // State for the values
    window.chartRef = chartRef;
    window.playerRef = playerRef;
    window.playerInstanceRef = playerInstanceRef;
    // Slider states

    const inputRef = useRef(null);

    const [sliderMin, setSliderMin] = useState(0.0);
    const [sliderMax, setSliderMax] = useState(1.0);
    // Date range states
    //

    const [startRange, setStartRange] = useState(
        new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000)
    );
    const [endRange, setEndRange] = useState(new Date());
    // const [endRange, setEndRange] = useState(new Date(new Date().getTime() - 6 * 24 * 60 * 60 * 1000));
    const [queryText, setQueryText] = useState("A clouded leopard and a human");
    const [sliderValue, setSliderValue] = useState(0);

    // State to track last submitted values
    const [lastSubmitted, setLastSubmitted] = useState({
        startRange,
        endRange,
        queryText,
    });

    // // Check if any value has changed
    // const queryChanged =
    //     startRange !== lastSubmitted.startRange ||
    //     endRange !== lastSubmitted.endRange ||
    //     queryText !== lastSubmitted.queryText;

    // Check if queryText is different from lastSubmitted.queryText
    const textChanged = queryText !== lastSubmitted.queryText;

    const startChanged =
        startRange.getTime() !== new Date(lastSubmitted.startRange).getTime();

    const endChanged =
        endRange.getTime() !== new Date(lastSubmitted.endRange).getTime();

    const queryChanged = textChanged || startChanged || endChanged;

    const streamComputeStatus = () => {
        fetch("api/return_status")
            .then((response) => {
                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let buffer = ""; // Accumulate partial text

                function read() {
                    reader.read().then(({ done, value }) => {
                        if (done) {
                            if (buffer) {
                            }
                            setStatusMessages([]);

                            return;
                        }
                        // Decode only the new chunk
                        buffer += decoder.decode(value, { stream: true });

                        // If your server sends lines, split and log only complete lines:
                        let lines = buffer.split("\n");
                        buffer = lines.pop(); // Save incomplete line for next chunk

                        for (const line of lines) {
                            if (line.trim()) {
                                let c_line = JSON.parse(line);

                                if (c_line["task"] !== "DONE_QUIT") {
                                    setStatusMessages((msgs) => [
                                        ...msgs,
                                        c_line,
                                    ]);
                                }
                            }
                        }

                        read();
                    });
                }
                read();
            })
            .catch((error) => {
                console.error("Error while streaming status:", error);
            });
    };
    // Function to resubmit fetch
    const handleResubmit = (doTestMode = false) => {
        let startRangeUse;
        let endRangeUse;
        if (doTestMode == true) {
            startRangeUse = new Date(
                new Date().getTime() - 2 * 24 * 60 * 60 * 1000
            );
            endRangeUse = new Date(
                new Date().getTime() - 1 * 24 * 60 * 60 * 1000
            );
        } else {
            startRangeUse = startRange;
            endRangeUse = endRange;
        }

        setStartRange(startRangeUse);
        setEndRange(endRangeUse);

        const params = new URLSearchParams();
        params.append("startRange", startRangeUse.toISOString());
        params.append("endRange", endRangeUse.toISOString());
        params.append("threshold", 0.0);
        params.append("query", queryText);
        setDataResults({ videos: [], breaks: [] });

        fetch("api/videos.json?" + params.toString())
            .then((res) => res.json())
            .then((data) => {
                streamComputeStatus();
                // Don't setDataResults here, since it's just {"status": ...}
                pollForResult(); // Start polling for the real result
            });

        setLastSubmitted({
            startRange: startRangeUse,
            endRange: endRangeUse,
            queryText,
        });
    };

    function updateDataAndValue(newValue) {
        const floatValue = parseFloat(newValue);
        setSliderValue(floatValue);
        var newData = JSON.parse(JSON.stringify(original_data.current));
        newData["videos"] = newData["videos"].filter(
            (vid) => vid["embed_scores"]["score"][1] >= floatValue
        );
        newData['threshold'] = floatValue;
        console.log(newData['threshold'])
        setDataResults(newData);
    }

    function setMarkerValueNonReactive(inputValue) {
        let chart = chartRef.current.getEchartsInstance();
        let options = chart.getOption();
        let mappers = options["mappers"];

        let vv = {
            xAxis: mappers["real_to_virtual"](new Date(inputValue)),
            lineStyle: { type: "solid", color: "#FF0000", width: 2 },
            label: {
                show: false,
                formatter: "Break",
                position: "bottom",
                color: "#888",
                fontSize: 10,
            },
        };

        let markLine = {
            symbol: ["none", "none"],
            data: [vv],
            lineStyle: { type: "dashed", color: "#FF0000", width: 2 },
            silent: true,
            animation: false,
        };

        // if ("markLine" in options["series"][1]) {
        if (false) {
            let vv_new = {
                xAxis: mappers["real_to_virtual"](new Date(inputValue)),
            };
            let markLine_new = {
                data: [vv_new],
            };

            chart.setOption(
                {
                    series: [{}, { markLine: { data: [vv_new] } }],
                },
                false,
                ["series.markLine"]
            );
        } else {
            chart.setOption(
                {
                    series: [{}, { markLine: markLine }],
                },
                false,
                ["series.markLine"]
            );
        }
    }
const handleTimelineClick = useCallback(
    (path, timeoffset) => {
        if (playerRef.current && playerInstanceRef.current) {
            const player = playerInstanceRef.current;
            
            console.log("Setting video source:", "api/" + path);
            console.log("Target time offset:", timeoffset);
            
            // Clear any existing source first
            player.reset();
            
            player.src({
                src: "api/" + path,
                type: "video/mp4",
            });
            
            player.load();
            
            // Add multiple event listeners for debugging
            player.one("loadedmetadata", () => {
                console.log("Video metadata loaded");
                console.log("Video duration:", player.duration());
                player.currentTime(timeoffset);
                
                // Try to play after setting time
                const playPromise = player.play();
                if (playPromise !== undefined) {
                    playPromise.then(() => {
                        console.log("Video started playing");
                    }).catch(error => {
                        console.error("Error playing video:", error);
                    });
                }
            });
            
            player.one("error", (e) => {
                console.error("Video error:", e);
                console.error("Player error:", player.error());
            });
            
            player.one("loadstart", () => {
                console.log("Load started");
            });
            
            player.one("canplay", () => {
                console.log("Video can start playing");
            });
        } else {
            console.error("Player ref not available");
        }
    },
    []
);

    useEffect(() => {
        const params = new URLSearchParams(window.location.search);

        handleResubmit(params.get("test_mode") === "true");
    }, []);

    // useEffect(() => {
    //   if (startRange && endRange) {
    //     handleResubmit();
    //   }
    // }, [startRange, endRange]);

    function pollForResult() {
        const poll = () => {
            fetch("api/videos_result.json")
                .then((res) => res.json())
                .then((data) => {
                    if (data.status === "processing") {
                        setTimeout(poll, 250); // Try again in 1 second
                    } else {
                        const max_value = Math.max(
                            ...data["videos"].map(
                                (vid) => vid["embed_scores"]["score"][1]
                            )
                        );
                        setSliderMax(max_value);

                        original_data.current = data;
                        setDataResults(data);
                    }
                });
        };
        poll();
    }

    return (
        <div className="app-container">
            <div className="controls-section">
                <div className="control-group">
                    <CustomDateRangePicker
                        startDate={startRange}
                        endDate={endRange}
                        setStartRange={setStartRange}
                        setEndRange={setEndRange}
                    />
                </div>
                <div className="control-group">
                    <input
                        type="text"
                        placeholder="Enter query"
                        value={queryText}
                        onChange={(e) => setQueryText(e.target.value)}
                        onKeyDown={(e) => {
                            if (e.key === "Enter") handleResubmit();
                        }}
                        style={{
                        //     padding: "8px",
                        //     borderRadius: "4px",
                        //     border: "1px solid #343a40",
                        //     color: "#fff",
                        //     backgroundColor: "#23272f",
                        //     width: "100%",
                        //     minWidth: 0,
                        //     boxSizing: "border-box",
                            fontSize: "1.1em",
                        //     transition: "width 0.2s",
                        }}
                        ref={inputRef}
                        size={Math.max(queryText.length, 25)}
                    />
                </div>
                <div
                    className="control-group"
                    style={{ visibility: queryChanged ? "hidden" : "visible" }}
                >
                    <label style={{ color: "#fff" }}>Threshold:</label>
                </div>
                <div
                    className="control-group"
                    style={{
                        display: "inline-block",
                        verticalAlign: "middle",
                        margin: "0 8px",
                        width: "120px",
                        visibility: queryChanged ? "hidden" : "visible",
                    }}
                >
                    <input
                        type="range"
                        min={sliderMin}
                        max={sliderMax}
                        step={0.001}
                        value={sliderValue}
                        onChange={(e) => updateDataAndValue(e.target.value)}
                        style={{
                            width: "100%",
                            color: "#fff",
                            backgroundColor: "#23272f",
                            minWidth: 0,
                        }}
                    />
                </div>
                <div
                    className="control-group"
                    style={{ visibility: queryChanged ? "hidden" : "visible" }}
                >
                    <span style={{ color: "#fff" }}>{sliderValue.toFixed(2)}</span>
                </div>
                <div
                    className="control-group"
                    style={{ visibility: queryChanged ? "visible" : "hidden" }}
                >
                    <button
                        onClick={handleResubmit}
                        style={{
                            width: "100%",
                            padding: "12px 0",
                            fontSize: "1.1em",
                            marginTop: "8px",
                        }}
                    >
                        Resubmit
                    </button>
                </div>
            </div>

            <div className="status-section">
                <StatusesDisplayHUD statusMessages={statusMessages} />
            </div>

            <div className="timeline-section">
                <EmbedTimeline
                    chartRef={chartRef}
                    data_in={dataResults}
                    onTimelineClick={handleTimelineClick}
                />
            </div>
            
            <div className="video-section vjs-16-9 vjs-fluid">
                <VideoPlayer
                    videoRef={playerRef}
                    playerInstanceRef={playerInstanceRef}
                    setMarkerTimeFunc={setMarkerValueNonReactive}
                />
            </div>
        </div>
    );
}

export default App;
