"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 playerInstanceRef = useRef(null);
    // State for the values
    window.chartRef = chartRef;
    window.playerRef = playerRef;
    window.playerInstanceRef = playerInstanceRef;
    // Slider states

    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,
        sliderValue,
        queryText,
    });

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

    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") {
                                  console.log(c_line);
                                    setStatusMessages((msgs) => [
                                        ...msgs,
                                        c_line,
                                    ]);
                                }
                            }
                        }

                        read();
                    });
                }
                read();
            })
            .catch((error) => {
                console.error("Error while streaming status:", error);
            });
    };
    // Function to resubmit fetch
    const handleResubmit = (doTestMode = false) => {
        console.log("startRange, endRange:", startRange, endRange);
        console.log("test mode:", doTestMode);
        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;
        }

        console.log("Using date range:", startRangeUse, endRangeUse);
        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({
            startRangeUse,
            endRangeUse,
            sliderValue,
            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
        );
        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"]
            );
        }
    }

    // Memoize the timeline click handler
    const handleTimelineClick = useCallback(
        (path, timeoffset) => {
            if (playerRef.current && playerInstanceRef.current) {
                playerInstanceRef.current.src({
                    src: "api/" + path,
                    type: "video/mp4",
                });
                playerInstanceRef.current.on("loadedmetadata", () => {
                    playerInstanceRef.current.currentTime(timeoffset);
                });
            }
        },
        [] // Empty dependency array since it only uses playerRef
    );

    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="section-box-horiz">
                <div className="flex-group">
                    <CustomDateRangePicker
                        startDate={startRange}
                        endDate={endRange}
                        setStartRange={setStartRange}
                        setEndRange={setEndRange}
                    />
                </div>
                <div className="flex-group">
                    <input
                        type="text"
                        placeholder="Enter query"
                        value={queryText}
                        onChange={(e) => setQueryText(e.target.value)}
                        style={{
                            marginLeft: "16px",
                            marginRight: "16px",
                            padding: "8px",
                            borderRadius: "4px",
                            border: "1px solid #343a40",
                            color: "#fff", // Text white
                            backgroundColor: "#23272f", // Optional: dark background for contrast
                        }}
                    />
                </div>
                <div className="flex-group">
                    <label
                        style={{
                            marginLeft: "8px",
                            marginRight: "8px",
                            color: "#fff",
                        }}
                    >
                        Threshold:
                    </label>
                </div>
                <div className="flex-group">
                    <input
                        type="range"
                        min={sliderMin}
                        max={sliderMax}
                        step={0.001}
                        value={sliderValue}
                        onChange={(e) => updateDataAndValue(e.target.value)}
                        style={{
                            width: "120px",
                            color: "#fff", // Text white
                            backgroundColor: "#23272f", // Optional: dark background for contrast
                        }}
                    />
                </div>
                <div className="flex-group">
                    <span style={{ marginLeft: "8px", color: "#fff" }}>
                        {sliderValue.toFixed(2)}
                    </span>
                </div>
                <div className="flex-group">
                    <button onClick={handleResubmit}>Resubmit</button>
                </div>
            </div>
            <div>
                <StatusesDisplayHUD statusMessages={statusMessages} />
            </div>

            <div className="timeline-container">
                <EmbedTimeline
                    chartRef={chartRef}
                    data_in={dataResults}
                    onTimelineClick={handleTimelineClick}
                />
            </div>
            <div className="section-box">
                <VideoPlayer
                    videoRef={playerRef}
                    playerInstanceRef={playerInstanceRef}
                    setMarkerTimeFunc={setMarkerValueNonReactive}
                />
            </div>
        </div>
    );
}

export default App;
