import React, { useContext, useEffect, useRef, useState } from 'react';
import { adjustCanvasScale, map, drawBackground } from '../function/canvasDefault';
import { getPitch, IPitchDetectionConfig } from '../function/getPitch';
import { Slider } from 'antd';
import { Col, Row } from 'antd';
interface Config {
    SRATE: number;
    fxmin: number;
    fxlow: number;
    fxhigh: number;
    fxmax: number;
}
interface COLORS {
    realVoiceColor: string;
    targetVoiceColor: string,
    closeVoiceColor: string,
}
interface ConstantProps {
    size: number[];
    config: Config;
    COLORS: COLORS;
    isPlaying: boolean;
    showNotesPar: boolean;
    setPlaying: ()=>void;
    setPlayingPause: ()=>void;
    isRetry: boolean;
    ballPosition: number;
    
}
const style: React.CSSProperties = {
    display: 'relative',
    height: 300,
};


const Constant: React.FC<ConstantProps> = ({ballPosition, isRetry,setPlayingPause, setPlaying, COLORS, config, isPlaying, size, showNotesPar }) => {
    const { SRATE, fxmin, fxlow, fxhigh, fxmax } = config;
    const { realVoiceColor, targetVoiceColor, closeVoiceColor } = COLORS;
    const [pitchValue, setPitchValue] = useState<number | null>(null);
    const [ballY, setBallY] = useState<number>(size[0]);
    const [ballYCurr, setBallYCurr] = useState<number>(size[0]);
    const canvasRef = useRef<HTMLCanvasElement>(null);
    const rectWidth = 5;
    const divisor = 10;
    // const divisor = useState<number>(10);
    const cornerRadius = 1;
    const desiredLength = Math.floor(size[1] / divisor);
    const desiredLengthBallNum = Math.floor(size[1] / divisor * ballPosition);
    const [desiredLengthBall,setDesiredLengthBall] = useState<number>(desiredLengthBallNum);
    // const newJsonHistory = jsonHistory.concat(Array(desiredLength - jsonHistory.length).fill(NaN));
    // const newBallHistory = ballHistory.concat(Array(desiredLength - ballHistory.length).fill(NaN));
    const isPlayingRef = useRef(isPlaying);
    // const [customHistory, setCustomHistory] = useState<number[]>(new Array(desiredLength).fill(NaN));
    // const [colorChanges, setColorChanges] = useState<boolean[]>(new Array(desiredLength).fill(true));
    // const [ballHistory, setBallHistory] = useState<number[]>(new Array(desiredLengthBall).fill(NaN));
    const initialCustomHistory = new Array(desiredLength).fill(NaN);
    const initialColorChanges = new Array(desiredLength).fill(true);
    const initialBallHistory = new Array(desiredLengthBall).fill(NaN);

    const [customHistory, setCustomHistory] = useState<number[]>(initialCustomHistory);
    const [colorChanges, setColorChanges] = useState<boolean[]>(initialColorChanges);
    const [ballHistory, setBallHistory] = useState<number[]>(initialBallHistory);
    const resetStates = () => {
        setCustomHistory([...initialCustomHistory]);
        setColorChanges([...initialColorChanges]);
        setBallHistory([...initialBallHistory]);
      };

    isPlayingRef.current = isPlaying;
    const [showNotes, setShowNotes] = useState(false);
    const [inputValue, setInputValue] = useState(1);
    const [canvasHeight, setCanvasHeight] = useState(0);
    function updateBallY(value: number | null): void {
        if (value === null) {
            value = 0;
        }
        if (value <= 1) {
            setBallY(size[0]+10);
            setBallYCurr(size[0]);
        } else {
            // console.log(value);
            setBallY(map(value, fxmin, fxmax, size[0], -1));
            setBallYCurr(map(value, fxmin, fxmax, size[0], -1));
        }
    }
    const onChange = (newValue: number) => {
        setInputValue(newValue);
    };
    const updateCanvasHeight = () => {
        if (canvasRef.current) {
            const rect = canvasRef.current.getBoundingClientRect();
            setCanvasHeight(rect.height);
        }
    };
    useEffect(() => {
        setDesiredLengthBall( Math.floor(size[1] / divisor * ballPosition));
    },[ballPosition])

    useEffect(() => {
        const timer = setTimeout(() => {
            resetStates();
        }, 100); 
        return () => clearTimeout(timer);
        
    },[desiredLengthBall])



    // retry
    useEffect(()=>{
        setPlaying();
        resetStates();
    },[isRetry])

    // Rendering balls and customization
    useEffect(() => {
        if ((isPlayingRef.current)) {
            const canvas = canvasRef.current;
            if (canvas) {
                const ctx = canvas.getContext('2d');
                if (ctx) {
                    // Clear the canvas
                    ctx.clearRect(0, 0, canvas.width, canvas.height);

                    // Draw the background
                    drawBackground(canvasRef, fxmax, fxmin, showNotes);

                    // Draw the ball's historical positions
                    for (var i = 0; i < ballHistory.length; i++) {
                        ctx.beginPath();
                        ctx.arc(i * divisor, ballHistory[i], 5, 0, 2 * Math.PI);
                        ctx.fillStyle = realVoiceColor;
                        ctx.fill();
                        ctx.closePath();
                    }

                    //Plot current value
                    updateBallY(pitchValue);
                    ctx.beginPath();
                    ctx.arc(size[1] * ballPosition, ballYCurr, 10, 0, 2 * Math.PI);
                    ctx.fillStyle = "black";
                    ctx.fill();
                    ctx.closePath();

                    // Draw json data

                    for (let i = 0; i < customHistory.length; i++) {
                        ctx.beginPath();
                        const mappedJsonValue = map(customHistory[i], fxmin, fxmax, size[0], 0);
                        if (colorChanges[i]) {
                            ctx.fillStyle = closeVoiceColor;
                        } else {
                            ctx.fillStyle = targetVoiceColor;
                        }

                        ctx.fillRect(canvas.width - i * divisor, mappedJsonValue, rectWidth, rectWidth);
                        ctx.fill();
                        ctx.closePath();
                    }
                    ctx.stroke();
                }
            }
        }
    }, [customHistory, ballY, isPlaying]);

    // // Update custom history when input value changes
    // useEffect(() => {
    //     const intervalId = setInterval(() => {
    //         if (isPlaying) {
    //             let updatedHistory = [...customHistory];
    //             updatedHistory.pop();  // Remove the first element
    //             updatedHistory.unshift(inputValue);  // Add the new inputValue at the end
    //             setCustomHistory(updatedHistory);

    //             let updatedColor = [...colorChanges];
    //             const mappedJsonValue = map(customHistory[Math.floor(customHistory.length - desiredLengthBall)], fxmin, fxmax, size[0], 0);
    //             // console.log(customHistory);
    //             // console.log(ballY);
    //             // console.log(desiredLengthBall); // 70
    //             // console.log(customHistory.length); // 280
    //             const difference = Math.abs(mappedJsonValue - ballY);
    //             if (difference <= 30 && !isNaN(difference)) {
    //                 updatedColor[size[1] / 5 - desiredLengthBall] = true;
    //             } else {
    //                 updatedColor[size[1] / 5 - desiredLengthBall] = false;
    //             }
    //             updatedColor.pop();
    //             updatedColor.unshift(false);
    //             setColorChanges(updatedColor);

    //             let temHistory = [...ballHistory];
    //             temHistory.shift();
    //             temHistory.push(ballY);
    //             setBallHistory(temHistory);

    //         }
    //     }, 25);

    //     return () => clearInterval(intervalId);
    // }, [customHistory, inputValue, isPlaying, ballY]);

        // Update custom history when input value changes
        useEffect(() => {
                if (isPlaying) {
                    let updatedHistory = [...customHistory];
                    updatedHistory.pop();  // Remove the first element
                    updatedHistory.unshift(inputValue);  // Add the new inputValue at the end
                    setCustomHistory(updatedHistory);
    
                    let updatedColor = [...colorChanges];
                    const mappedJsonValue = map(customHistory[Math.floor(customHistory.length - desiredLengthBall)], fxmin, fxmax, size[0], 0);
           
                    const difference = Math.abs(mappedJsonValue - ballY);
                    if (difference <= 30 && !isNaN(difference)) {
                        updatedColor[Math.floor(size[1] / divisor - desiredLengthBall)] = true;
                    } else {
                        updatedColor[Math.floor(size[1] / divisor - desiredLengthBall)] = false;
                    }
                    updatedColor.pop();
                    updatedColor.unshift(false);
                    setColorChanges(updatedColor);
    
                    let temHistory = [...ballHistory];
                    temHistory.shift();
                    temHistory.push(ballY);
                    setBallHistory(temHistory);
    
                }
        }, [isPlaying, pitchValue]);

    // first
    useEffect(() => {
        setPlayingPause();
        drawBackground(canvasRef, fxmax, fxmin, showNotes);
        console.log(showNotesPar);
        let cleanup: () => void;
        // Set the Canvas height when mounting the component for the first time
        updateCanvasHeight();

        // Set up resize event listener
        window.addEventListener('resize', updateCanvasHeight);
        (async () => {
            cleanup = await getPitch(config, setPitchValue);
        })();

        return () => {
            cleanup && cleanup();
            window.removeEventListener('resize', updateCanvasHeight);
        };
    }, []);

    useEffect(() => {
        updateBallY(pitchValue);
    }, [pitchValue]);


    useEffect(() => {
        if (canvasRef.current) {
            const rect = canvasRef.current.getBoundingClientRect();
            setCanvasHeight(rect.height);
        }
    }, []);

    const toggleShowNotes = () => {
        setShowNotes(!showNotes);
        const canvas = canvasRef.current;
        if (canvas && canvas.getContext) {
            const ctx = canvas.getContext('2d');
            if (ctx) {
                ctx.clearRect(0, 0, canvas.width/24, canvas.height);
                drawBackground(canvasRef, fxmax, fxmin, !showNotes);
            }
        }
    }

    useEffect(() => {
        drawBackground(canvasRef, fxmax, fxmin, showNotes); // Make sure the background is redrawn on state change
    }, [showNotes]);

    useEffect(() => {
        console.log(showNotesPar);
        setShowNotes(showNotesPar);
        const canvas = canvasRef.current;
        if (canvas && canvas.getContext) {
            const ctx = canvas.getContext('2d');
            if (ctx) {
                ctx.clearRect(0, 0, canvas.width/24, canvas.height);
                drawBackground(canvasRef, fxmax, fxmin, !showNotes);
            }
        }
    }, [showNotesPar]);

    return (
        <Row style={{ maxHeight: "27vw", maxWidth: "100vw" }}>
            {/* <div className="color-block"> */}
            <Col span={1}>

            </Col>
            <Col span={22}>

                <canvas ref={canvasRef} onClick={toggleShowNotes} id="pitchCanvas" width={size[1]} height={size[0]} style={{ border: '1px solid #000' }}></canvas>
            </Col>
            <Col span={1}>
                <div>
                    <Slider
                        vertical
                        //   tooltip={{open:true}}
                        min={config.fxmin}
                        max={config.fxmax}
                        style={{ marginTop: 0, height: canvasHeight }}
                        onChange={onChange}
                        defaultValue={30} />
                </div>
            </Col>
        </Row>



    );
}

export default Constant;
