import React, { useState, useRef, useEffect } from 'react';
import { RiSendPlaneFill } from 'react-icons/ri';
import { useNavigate } from 'react-router-dom';
import './Home.css';
import { TbSparkles } from "react-icons/tb";
import { LuBookAudio } from "react-icons/lu";
import { FaArrowRight, FaPlay, FaVolumeUp, FaChevronDown, FaLightbulb, FaSkull, FaCheckCircle, FaPause, FaLock } from "react-icons/fa";
import { TiFlowMerge } from "react-icons/ti";
import { RiVoiceprintFill } from "react-icons/ri";
import { BsSoundwave } from "react-icons/bs";
import { BiPodcast } from "react-icons/bi";

const Home = () => {
    const [prompt, setPrompt] = useState('');
    const [isDropdownOpen, setIsDropdownOpen] = useState(false);
    const [isBelieverDropdownOpen, setIsBelieverDropdownOpen] = useState(false);
    const [isSkepticDropdownOpen, setIsSkepticDropdownOpen] = useState(false);
    const [selectedWorkflow, setSelectedWorkflow] = useState('Basic Podcast');
    const [selectedBelieverVoice, setSelectedBelieverVoice] = useState({ id: 'alloy', name: 'Alloy' });
    const [selectedSkepticVoice, setSelectedSkepticVoice] = useState({ id: 'echo', name: 'Echo' });
    const [researchSteps, setResearchSteps] = useState([]);
    const [believerResponses, setBelieverResponses] = useState([]);
    const [skepticResponses, setSkepticResponses] = useState([]);
    const [isGenerating, setIsGenerating] = useState(false);
    const [isSuccess, setIsSuccess] = useState(false);
    const [successMessage, setSuccessMessage] = useState('');
    const [audioUrl, setAudioUrl] = useState('');
    const [isPlaying, setIsPlaying] = useState(false);
    const [currentTime, setCurrentTime] = useState(0);
    const [duration, setDuration] = useState(0);
    const [isUnlocking, setIsUnlocking] = useState(false);
    const audioRef = useRef(null);
    const navigate = useNavigate();
    const workflowDropdownRef = useRef(null);
    const believerDropdownRef = useRef(null);
    const skepticDropdownRef = useRef(null);
    const insightsRef = useRef(null);

    const workflows = [
        { id: '1', name: 'Basic Podcast' },
        { id: '2', name: 'Interview Style' },
        { id: '3', name: 'News Digest' }
    ];

    const voices = [
        { id: 'alloy', name: 'Alloy' },
        { id: 'echo', name: 'Echo' },
        { id: 'fable', name: 'Fable' },
        { id: 'onyx', name: 'Onyx' },
        { id: 'nova', name: 'Nova' },
        { id: 'shimmer', name: 'Shimmer' },
        { id: 'ash', name: 'Ash' },
        { id: 'sage', name: 'Sage' },
        { id: 'coral', name: 'Coral' }
    ];

    useEffect(() => {
        const handleClickOutside = (event) => {
            if (workflowDropdownRef.current && !workflowDropdownRef.current.contains(event.target)) {
                setIsDropdownOpen(false);
            }
            if (believerDropdownRef.current && !believerDropdownRef.current.contains(event.target)) {
                setIsBelieverDropdownOpen(false);
            }
            if (skepticDropdownRef.current && !skepticDropdownRef.current.contains(event.target)) {
                setIsSkepticDropdownOpen(false);
            }
        };

        document.addEventListener('mousedown', handleClickOutside);
        return () => {
            document.removeEventListener('mousedown', handleClickOutside);
        };
    }, []);

    useEffect(() => {
        const audio = audioRef.current;
        if (audio) {
            const updateTime = () => {
                setCurrentTime(audio.currentTime);
            };

            const updateDuration = () => {
                if (!isNaN(audio.duration) && audio.duration > 0) {
                    // Validate duration before setting it
                    if (audio.duration > 86400) {
                        console.error('Invalid duration detected:', audio.duration);
                        // Don't update state with invalid duration
                        return;
                    }
                    console.log('Duration updated:', audio.duration);
                    setDuration(audio.duration);
                }
            };

            // Add event listeners
            audio.addEventListener('timeupdate', updateTime);
            audio.addEventListener('loadedmetadata', updateDuration);
            audio.addEventListener('durationchange', updateDuration);
            audio.addEventListener('canplay', updateDuration); // Additional event to catch duration
            audio.addEventListener('ended', () => setIsPlaying(false));
            audio.addEventListener('error', (e) => {
                console.error('Audio error in event listener:', e);
                setIsPlaying(false);
            });

            return () => {
                // Remove event listeners
                audio.removeEventListener('timeupdate', updateTime);
                audio.removeEventListener('loadedmetadata', updateDuration);
                audio.removeEventListener('durationchange', updateDuration);
                audio.removeEventListener('canplay', updateDuration);
                audio.removeEventListener('ended', () => setIsPlaying(false));
                audio.removeEventListener('error', (e) => {
                    console.error('Audio error:', e);
                    setIsPlaying(false);
                });
            };
        }
    }, [audioUrl]);

    useEffect(() => {
        if (audioUrl) {
            setIsUnlocking(true);
            // Remove the unlocking class after animation completes
            const timer = setTimeout(() => {
                setIsUnlocking(false);
            }, 500);
            return () => clearTimeout(timer);
        }
    }, [audioUrl]);

    // Add a separate effect to check duration when audioUrl changes
    useEffect(() => {
        if (audioUrl && audioRef.current) {
            console.log('Audio URL changed, checking duration...');

            // Reset current time and check duration
            setCurrentTime(0);

            // Create a function to check duration periodically
            const checkDuration = () => {
                if (audioRef.current && !isNaN(audioRef.current.duration) && audioRef.current.duration > 0) {
                    // Validate the duration
                    if (audioRef.current.duration > 86400) {
                        console.error('Invalid duration detected in check:', audioRef.current.duration);
                        return false;
                    }
                    console.log('Duration found after URL change:', audioRef.current.duration);
                    setDuration(audioRef.current.duration);
                    return true;
                }
                return false;
            };

            // Try immediately
            if (!checkDuration()) {
                // If not successful, try again after a short delay
                const timerId = setTimeout(async () => {
                    if (!checkDuration()) {
                        // If still not successful, try manual calculation
                        console.log('Duration not available, attempting manual calculation');
                        try {
                            const calculatedDuration = await calculateMP3Duration(audioUrl);
                            console.log('Manually calculated duration:', calculatedDuration);
                            setDuration(calculatedDuration);
                        } catch (error) {
                            console.error('Manual duration calculation failed:', error);
                            // Set a default duration as fallback
                            setDuration(300); // Default to 5 minutes
                        }
                    }
                }, 1000);

                return () => clearTimeout(timerId);
            }
        }
    }, [audioUrl]);

    const checkForExistingPodcast = async () => {
        try {
            const token = localStorage.getItem('token');
            if (!token) return;

            // Fetch the most recent podcast using the new endpoint
            const response = await fetch('http://localhost:8000/podcasts/latest', {
                headers: {
                    'Authorization': `Bearer ${token}`
                }
            });

            if (response.ok) {
                const data = await response.json();

                // Check if we got a podcast (not just a message)
                if (data && data.audio_url) {
                    // Set the audio URL directly from the response
                    setAudioUrl(data.audio_url);
                    setSuccessMessage('Latest podcast loaded');
                    setIsSuccess(true);
                    console.log('Latest podcast loaded:', data.topic);
                } else if (data && data.audio_path) {
                    // Fallback to constructing URL from audio_path if audio_url is not present
                    setAudioUrl(`http://localhost:8000${data.audio_path}`);
                    setSuccessMessage('Latest podcast loaded');
                    setIsSuccess(true);
                    console.log('Latest podcast loaded (using path):', data.topic);
                } else {
                    console.log('No podcasts found or no audio URL available');
                }
            } else {
                console.error('Error fetching latest podcast:', await response.text());
            }
        } catch (error) {
            console.error('Error checking for existing podcast:', error);
        }
    };

    useEffect(() => {
        console.log('Component mounted, checking for existing podcasts...');
        checkForExistingPodcast();
    }, []);

    const togglePlay = () => {
        if (audioRef.current) {
            if (isPlaying) {
                audioRef.current.pause();
                setIsPlaying(false);
            } else {
                const playPromise = audioRef.current.play();

                if (playPromise !== undefined) {
                    playPromise
                        .then(() => {
                            setIsPlaying(true);
                        })
                        .catch(error => {
                            console.error('Error playing audio:', error);
                            setSuccessMessage('Error playing audio. Please try again.');
                        });
                }
            }
        }
    };

    const handleSeek = (e) => {
        if (!audioRef.current || !audioUrl) return;

        // Check if duration is valid
        if (isNaN(audioRef.current.duration) || audioRef.current.duration <= 0) {
            console.warn('Cannot seek: Invalid audio duration');
            return;
        }

        const progressBar = e.currentTarget;
        const rect = progressBar.getBoundingClientRect();
        const clickPosition = (e.clientX - rect.left) / rect.width;

        // Ensure clickPosition is between 0 and 1
        const normalizedPosition = Math.max(0, Math.min(1, clickPosition));
        const newTime = normalizedPosition * audioRef.current.duration;

        console.log(`Seeking to ${formatTime(newTime)} (${normalizedPosition * 100}%)`);

        // Update audio time
        audioRef.current.currentTime = newTime;
        setCurrentTime(newTime);
    };

    const formatTime = (time) => {
        // Handle invalid time values
        if (isNaN(time) || time === null || time === undefined || time < 0) {
            return '0:00';
        }

        // Cap extremely large values (likely errors)
        if (time > 86400) { // More than 24 hours
            console.warn('Extremely large duration detected:', time);
            time = 0; // Reset to 0 for display purposes
        }

        const hours = Math.floor(time / 3600);
        const minutes = Math.floor((time % 3600) / 60);
        const seconds = Math.floor(time % 60);

        if (hours > 0) {
            return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
        }
        return `${minutes}:${seconds.toString().padStart(2, '0')}`;
    };

    const handleWorkflowSelect = (workflow) => {
        setSelectedWorkflow(workflow.name);
        setIsDropdownOpen(false);
    };

    const handleBelieverVoiceSelect = (voice) => {
        setSelectedBelieverVoice(voice);
        setIsBelieverDropdownOpen(false);
    };

    const handleSkepticVoiceSelect = (voice) => {
        setSelectedSkepticVoice(voice);
        setIsSkepticDropdownOpen(false);
    };

    const handleSubmit = async (e) => {
        e.preventDefault();
        setIsGenerating(true);
        setResearchSteps([]);
        setBelieverResponses([]);
        setSkepticResponses([]);
        setIsSuccess(false);
        setSuccessMessage('');
        setAudioUrl('');

        try {
            const token = localStorage.getItem('token');
            if (!token) {
                console.error('No token found');
                return;
            }

            const response = await fetch('http://localhost:8000/generate-podcast/stream', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify({
                    topic: prompt,
                    believer_voice_id: selectedBelieverVoice.id,
                    skeptic_voice_id: selectedSkepticVoice.id
                })
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const reader = response.body.getReader();
            const decoder = new TextDecoder();

            while (true) {
                const { value, done } = await reader.read();
                if (done) break;

                const chunk = decoder.decode(value);
                const lines = chunk.split('\n').filter(line => line.trim());

                for (const line of lines) {
                    try {
                        const data = JSON.parse(line);
                        switch (data.type) {
                            case 'intermediate':
                                setResearchSteps(prev => [...prev, data.content]);
                                break;
                            case 'final':
                                setResearchSteps(prev => [...prev, 'Research completed!']);
                                break;
                            case 'believer':
                                if (data.turn) {
                                    setBelieverResponses(prev => {
                                        const newResponses = [...prev];
                                        newResponses[data.turn - 1] = (newResponses[data.turn - 1] || '') + data.content;
                                        return newResponses;
                                    });
                                }
                                break;
                            case 'skeptic':
                                if (data.turn) {
                                    setSkepticResponses(prev => {
                                        const newResponses = [...prev];
                                        newResponses[data.turn - 1] = (newResponses[data.turn - 1] || '') + data.content;
                                        return newResponses;
                                    });
                                }
                                break;
                            case 'success':
                                setIsSuccess(true);
                                setSuccessMessage(data.content || 'Podcast created successfully!');
                                if (data.podcast_url) {
                                    setAudioUrl(`http://localhost:8000${data.podcast_url}`);
                                }
                                break;
                            case 'error':
                                console.error('Error:', data.content);
                                break;
                        }
                        // Auto-scroll to the bottom of insights
                        if (insightsRef.current) {
                            insightsRef.current.scrollTop = insightsRef.current.scrollHeight;
                        }
                    } catch (e) {
                        console.error('Error parsing JSON:', e);
                    }
                }
            }
        } catch (error) {
            console.error('Error:', error);
        } finally {
            setIsGenerating(false);
        }
    };

    // Add a function to manually calculate duration for MP3 files
    const calculateMP3Duration = async (url) => {
        try {
            console.log('Attempting to manually calculate MP3 duration for:', url);

            // Create a temporary audio element
            const tempAudio = new Audio();

            // Create a promise to handle the duration calculation
            const durationPromise = new Promise((resolve, reject) => {
                // Set up event listeners
                tempAudio.addEventListener('loadedmetadata', () => {
                    if (!isNaN(tempAudio.duration) && tempAudio.duration > 0 && tempAudio.duration < 86400) {
                        console.log('Successfully calculated duration:', tempAudio.duration);
                        resolve(tempAudio.duration);
                    } else {
                        // If duration is invalid, use a default value
                        console.warn('Invalid duration from calculation, using default');
                        resolve(300); // Default to 5 minutes (300 seconds)
                    }
                });

                tempAudio.addEventListener('error', (e) => {
                    console.error('Error calculating duration:', e);
                    reject(e);
                });

                // Set a timeout in case the metadata never loads
                setTimeout(() => {
                    console.warn('Duration calculation timed out, using default');
                    resolve(300); // Default to 5 minutes
                }, 5000);
            });

            // Start loading the audio
            tempAudio.src = url;
            tempAudio.load();

            // Wait for the duration to be calculated
            const calculatedDuration = await durationPromise;
            return calculatedDuration;

        } catch (error) {
            console.error('Error in duration calculation:', error);
            return 300; // Default to 5 minutes on error
        }
    };

    return (
        <div className="home-container">
            <div className='home-hero'>
                <div className="home-hero-content">
                    <h1>Welcome to PodCraft</h1>
                </div>
            </div>
            <div className="top-row">
                <div className="column left-column">
                    <div className="content-card">
                        <h3>Generated insights <TbSparkles /></h3>
                        <div className="insights-container" ref={insightsRef}>
                            {researchSteps.length === 0 && !believerResponses.length && !skepticResponses.length ? (
                                <div className="placeholder-content">
                                    <span className="info-icon"><TbSparkles /></span>
                                    <p>Insights from the AI agents will appear here</p>
                                </div>
                            ) : (
                                <div className="insights-content">
                                    {researchSteps.length > 0 && (
                                        <div className="research-section">
                                            <h4>Research Progress</h4>
                                            <div className="research-steps">
                                                {researchSteps.map((step, index) => (
                                                    <div key={index} className="research-step">
                                                        <span className="step-number">{index + 1}</span>
                                                        <p>{step}</p>
                                                    </div>
                                                ))}
                                            </div>
                                        </div>
                                    )}
                                    {(skepticResponses.length > 0 || believerResponses.length > 0) && (
                                        <div className="debate-section">
                                            {skepticResponses.map((response, index) => (
                                                <React.Fragment key={`turn-${index + 1}`}>
                                                    {response && (
                                                        <div className="agent-response skeptic">
                                                            <div className="agent-header">
                                                                <FaSkull className="agent-icon" />
                                                                <h4>{selectedSkepticVoice.name}'s Turn {index + 1}</h4>
                                                            </div>
                                                            <p>{response}</p>
                                                        </div>
                                                    )}
                                                    {believerResponses[index] && (
                                                        <div className="agent-response believer">
                                                            <div className="agent-header">
                                                                <FaLightbulb className="agent-icon" />
                                                                <h4>{selectedBelieverVoice.name}'s Turn {index + 1}</h4>
                                                            </div>
                                                            <p>{believerResponses[index]}</p>
                                                        </div>
                                                    )}
                                                </React.Fragment>
                                            ))}
                                        </div>
                                    )}
                                </div>
                            )}
                            {isSuccess && (
                                <div className="success-message">
                                    <FaCheckCircle className="success-icon" />
                                    <p>{successMessage}</p>
                                </div>
                            )}
                        </div>
                        {isGenerating && (
                            <div className="generating-indicator">
                                <div className="loading-dots">
                                    <span></span>
                                    <span></span>
                                    <span></span>
                                </div>
                                <p className="generating-text">
                                    {!believerResponses.length ? "Researching topic..." :
                                        !skepticResponses.length ? "Generating believer's perspective..." :
                                            skepticResponses.length > 0 && !isSuccess ? "Creating podcast with TTS..." :
                                                ""}
                                </p>
                            </div>
                        )}
                    </div>
                </div>
                <div className="column right-column">
                    <div className="content-card">
                        <h3>Configure your podcast <LuBookAudio /></h3>
                        <div className="audio-content">
                            <div className="audio-row">
                                <div className="row-header">
                                    <div className="row-title">
                                        <TiFlowMerge className="row-icon" />
                                        <h4>Choose Workflow Template</h4>
                                    </div>
                                </div>
                                <div className="custom-dropdown" ref={workflowDropdownRef}>
                                    <div
                                        className={`dropdown-header ${isDropdownOpen ? 'open' : ''}`}
                                        onClick={() => setIsDropdownOpen(!isDropdownOpen)}
                                    >
                                        <span>{selectedWorkflow || 'Select Workflow'}</span>
                                        <FaChevronDown className={`chevron ${isDropdownOpen ? 'open' : ''}`} />
                                    </div>
                                    {isDropdownOpen && (
                                        <div className="dropdown-options">
                                            {workflows.map((workflow) => (
                                                <div
                                                    key={workflow.id}
                                                    className="dropdown-option"
                                                    onClick={() => handleWorkflowSelect(workflow)}
                                                >
                                                    {workflow.name}
                                                </div>
                                            ))}
                                        </div>
                                    )}
                                </div>
                            </div>
                            <div className="audio-row">
                                <div className="row-header">
                                    <div className="row-title">
                                        <RiVoiceprintFill className="row-icon" />
                                        <h4>Select Voice Style</h4>
                                    </div>
                                </div>
                                <div className="voice-dropdowns">
                                    <div className="voice-dropdown-container">
                                        <div className="voice-type">
                                            <FaLightbulb className="voice-icon believer" />
                                            <span>Believer Voice</span>
                                        </div>
                                        <div className="custom-dropdown" ref={believerDropdownRef}>
                                            <div
                                                className={`dropdown-header ${isBelieverDropdownOpen ? 'open' : ''}`}
                                                onClick={() => setIsBelieverDropdownOpen(!isBelieverDropdownOpen)}
                                            >
                                                <span>{selectedBelieverVoice ? selectedBelieverVoice.name : 'Select Voice'}</span>
                                                <FaChevronDown className={`chevron ${isBelieverDropdownOpen ? 'open' : ''}`} />
                                            </div>
                                            {isBelieverDropdownOpen && (
                                                <div className="dropdown-options">
                                                    {voices.map((voice) => (
                                                        <div
                                                            key={voice.id}
                                                            className={`dropdown-option ${selectedSkepticVoice?.id === voice.id ? 'disabled' : ''}`}
                                                            onClick={() => selectedSkepticVoice?.id !== voice.id && handleBelieverVoiceSelect(voice)}
                                                        >
                                                            <div className="voice-option-content">
                                                                <span>{voice.name}</span>
                                                                <small>{voice.id}</small>
                                                            </div>
                                                        </div>
                                                    ))}
                                                </div>
                                            )}
                                        </div>
                                    </div>
                                    <div className="voice-dropdown-container">
                                        <div className="voice-type">
                                            <FaSkull className="voice-icon skeptic" />
                                            <span>Skeptic Voice</span>
                                        </div>
                                        <div className="custom-dropdown" ref={skepticDropdownRef}>
                                            <div
                                                className={`dropdown-header ${isSkepticDropdownOpen ? 'open' : ''}`}
                                                onClick={() => setIsSkepticDropdownOpen(!isSkepticDropdownOpen)}
                                            >
                                                <span>{selectedSkepticVoice ? selectedSkepticVoice.name : 'Select Voice'}</span>
                                                <FaChevronDown className={`chevron ${isSkepticDropdownOpen ? 'open' : ''}`} />
                                            </div>
                                            {isSkepticDropdownOpen && (
                                                <div className="dropdown-options">
                                                    {voices.map((voice) => (
                                                        <div
                                                            key={voice.id}
                                                            className={`dropdown-option ${selectedBelieverVoice?.id === voice.id ? 'disabled' : ''}`}
                                                            onClick={() => selectedBelieverVoice?.id !== voice.id && handleSkepticVoiceSelect(voice)}
                                                        >
                                                            <div className="voice-option-content">
                                                                <span>{voice.name}</span>
                                                                <small>{voice.id}</small>
                                                            </div>
                                                        </div>
                                                    ))}
                                                </div>
                                            )}
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div className="audio-row">
                                <div className="row-header">
                                    <div className="row-title">
                                        <BiPodcast className="row-icon" />
                                        <h4>Preview Audio</h4>
                                    </div>
                                </div>
                                <div className={`player-controls ${!audioUrl ? 'locked' : isUnlocking ? 'unlocking' : ''}`}>
                                    {!audioUrl && <FaLock className="lock-icon" />}
                                    <button
                                        className="play-btn"
                                        onClick={togglePlay}
                                        disabled={!audioUrl}
                                        aria-label={isPlaying ? "Pause" : "Play"}
                                    >
                                        {isPlaying ? <FaPause /> : <FaPlay />}
                                    </button>
                                    <div
                                        className="player-progress"
                                        onClick={audioUrl ? handleSeek : undefined}
                                        style={{ cursor: audioUrl ? 'pointer' : 'not-allowed' }}
                                    >
                                        <div className="progress-bar">
                                            <div
                                                className="progress"
                                                style={{
                                                    width: `${duration > 0 ? (currentTime / duration) * 100 : 0}%`
                                                }}
                                            />
                                        </div>
                                    </div>
                                    <div className="time-stamps">
                                        <span>{formatTime(currentTime)}/{formatTime(duration)}</span>
                                    </div>
                                </div>
                                <audio
                                    ref={audioRef}
                                    src={audioUrl || undefined}
                                    preload="metadata"
                                    onError={(e) => {
                                        console.error('Audio element error event:', e);
                                        console.error('Audio error details:', e.target.error);
                                        setSuccessMessage('Error loading audio. Please try again.');
                                        setIsSuccess(false);
                                    }}
                                    onLoadedMetadata={(e) => {
                                        console.log('Audio metadata loaded successfully');
                                        console.log('Audio duration from event:', e.target.duration);
                                        if (audioRef.current && !isNaN(audioRef.current.duration)) {
                                            setDuration(audioRef.current.duration);
                                        }
                                    }}
                                    onDurationChange={(e) => {
                                        console.log('Duration changed:', e.target.duration);
                                        if (!isNaN(e.target.duration) && e.target.duration > 0) {
                                            // Validate duration before setting it
                                            if (e.target.duration > 86400) {
                                                console.error('Invalid duration detected in event:', e.target.duration);
                                                return;
                                            }
                                            setDuration(e.target.duration);
                                        }
                                    }}
                                />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div className="bottom-row">
                <div className="prompt-container">
                    <form onSubmit={handleSubmit} className="prompt-form">
                        <input
                            type="text"
                            value={prompt}
                            onChange={(e) => setPrompt(e.target.value)}
                            placeholder="Enter your prompt to generate a podcast..."
                            className="prompt-input"
                            disabled={isGenerating}
                        />
                        <button
                            type="submit"
                            className="prompt-submit"
                            disabled={isGenerating || !prompt.trim()}
                        >
                            <RiSendPlaneFill />
                        </button>
                    </form>
                </div>
            </div>
            <div className="workflows-redirect">
                <button onClick={() => navigate('/workflows')} className="workflows-button">
                    Create in workflows <FaArrowRight />
                </button>
            </div>
        </div>
    );
};

export default Home; 