import React, { useState, useEffect, useRef, useCallback } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate, Link, useNavigate } from 'react-router-dom';
import { useReactMediaRecorder } from "react-media-recorder";
import './App.css'; // Your existing App.css
import chatbotLogo from './assets/chatbot.png'; // Import the logo

// Mock user object for demonstration. In your real app, this comes from Firebase.
const mockUser = {
  isLoggedIn: true,
};

// =================================================================================
// Chat Components (ChatPage and ChatInput)
// =================================================================================

const ChatInput = ({ onSendMessage, isLoading, setInputText, inputText }) => {
  const { status, startRecording, stopRecording, mediaBlobUrl } = useReactMediaRecorder({
    audio: true,
    mimeType: "audio/webm", // Explicitly set mimetype
  });

  const [isTranscribing, setIsTranscribing] = useState(false);
  const isRecording = status === "recording";

  // This effect handles the recorded audio blob
  useEffect(() => {
    // When a blob URL is available and recording has stopped
    if (mediaBlobUrl && status === 'stopped') {
      const transcribeAudio = async () => {
        setIsTranscribing(true);
        try {
          // Fetch the audio blob from its URL
          const audioBlob = await fetch(mediaBlobUrl).then((res) => res.blob());

          // Create a FormData object to send the file
          const formData = new FormData();
          formData.append("audio_file", audioBlob, "recording.webm");

          // Send the audio to the backend transcription endpoint
          const response = await fetch("/api/transcribe-audio", {
            method: "POST",
            body: formData,
          });

          if (!response.ok) {
            throw new Error("Transcription failed");
          }

          const result = await response.json();
          setInputText(result.transcription); // Set the input field with the transcribed text
        } catch (error) {
          console.error("Error transcribing audio:", error);
          alert("Could not transcribe audio. Please try again.");
        } finally {
          setIsTranscribing(false);
        }
      };
      transcribeAudio();
    }
  }, [mediaBlobUrl, status, setInputText]);

  const handleTextChange = (e) => {
    setInputText(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    if (inputText.trim()) {
      onSendMessage(inputText);
      setInputText('');
    }
  };

  const getPlaceholderText = () => {
    if (isRecording) return "Recording...";
    if (isTranscribing) return "Transcribing...";
    return "Type or hold the mic to talk...";
  };

  return (
    <div className="chat-input-area">
      <form onSubmit={handleSubmit} className="chat-form">
        <input
          type="text"
          value={inputText}
          onChange={handleTextChange}
          placeholder={getPlaceholderText()}
          disabled={isLoading || isRecording || isTranscribing}
        />
        <div className="button-container">
          {/* Voice Input Button */}
          <button
            type="button"
            className={`voice-button ${isRecording ? 'recording' : ''}`}
            onMouseDown={startRecording}
            onMouseUp={stopRecording}
            onTouchStart={startRecording}
            onTouchEnd={stopRecording}
            disabled={isLoading || isTranscribing}
          >
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
              <path d="M8.25 4.5a3.75 3.75 0 1 1 7.5 0v8.25a3.75 3.75 0 1 1-7.5 0V4.5Z" />
              <path d="M6 10.5a.75.75 0 0 1 .75.75v1.5a5.25 5.25 0 1 0 10.5 0v-1.5a.75.75 0 0 1 1.5 0v1.5a6.75 6.75 0 1 1-13.5 0v-1.5A.75.75 0 0 1 6 10.5Z" />
            </svg>
          </button>

          {/* Text Send Button */}
          <button
            type="submit"
            className="send-button"
            disabled={isLoading || !inputText.trim()}
          >
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
              <path d="M3.478 2.404a.75.75 0 0 0-.926.941l2.432 7.905H13.5a.75.75 0 0 1 0 1.5H4.984l-2.432 7.905a.75.75 0 0 0 .926.94 60.519 60.519 0 0 0 18.445-8.986.75.75 0 0 0 0-1.218A60.517 60.517 0 0 0 3.478 2.404Z" />
            </svg>
          </button>
        </div>
      </form>
    </div>
  );
};

const ChatPage = () => {
  const [chatHistory, setChatHistory] = useState([]);
  const [isSending, setIsSending] = useState(false);
  const [inputText, setInputText] = useState(""); // State for the input field
  const chatEndRef = useRef(null);

  useEffect(() => {
    chatEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [chatHistory]);

  const handleSendMessage = useCallback(async (prompt) => {
    if (!prompt.trim() || isSending) return;

    const userMessage = { role: 'user', message: prompt };
    // Add user message and a temporary placeholder for the bot's response
    setChatHistory(prev => [...prev, userMessage, { role: 'assistant', message: '...' }]);
    setIsSending(true);

    try {
        const response = await fetch('/api/ask', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ text: prompt }),
        });

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

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

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

            const chunk = decoder.decode(value, { stream: true });
            const events = chunk.split('\n\n');

            for (const event of events) {
                if (event.startsWith('data:')) {
                    const dataStr = event.substring(5).trim();
                     if (dataStr) {
                        try {
                           const dataObj = JSON.parse(dataStr);
                            if (dataObj.token) {
                                fullResponse += dataObj.token;
                                // Update the last message in history with the streaming content
                                setChatHistory(prev => {
                                    const newHistory = [...prev];
                                    newHistory[newHistory.length - 1] = { role: 'assistant', message: fullResponse + '▌' };
                                    return newHistory;
                                });
                            }
                        } catch (e) {
                            console.error("Error parsing stream data:", e);
                        }
                    }
                }
            }
        }
        
        // Final update to remove the cursor
        setChatHistory(prev => {
            const newHistory = [...prev];
            newHistory[newHistory.length - 1] = { role: 'assistant', message: fullResponse };
            return newHistory;
        });

    } catch (error) {
        console.error("Error fetching AI response:", error);
        setChatHistory(prev => {
             const newHistory = [...prev];
             newHistory[newHistory.length - 1] = { role: 'assistant', message: "Sorry, I couldn't get a response. Please try again." };
             return newHistory;
        });
    } finally {
        setIsSending(false);
    }
  }, [isSending]);

  return (
    <div className="chat-main">
      <div className="chat-messages">
        {chatHistory.length === 0 ? (
          <div className="empty-chat-placeholder">
            <h1>Dobby is here to help!</h1>
            <p>Start the conversation by typing or using your voice.</p>
          </div>
        ) : (
          chatHistory.map((chat, index) => (
            <div key={index} className={`message-wrapper ${chat.role}`}>
              <div className="chat-avatar">
                {chat.role === 'assistant' ? (
                  <img src={chatbotLogo} alt="Dobby" className="avatar-image" />
                ) : '👤'}
              </div>
              <div className="message-bubble">{chat.message}</div>
            </div>
          ))
        )}
        <div ref={chatEndRef} />
      </div>
      <ChatInput
        onSendMessage={handleSendMessage}
        isLoading={isSending}
        setInputText={setInputText}
        inputText={inputText}
      />
    </div>
  );
};

// =================================================================================
// Auth Components (Login and SignUp)
// =================================================================================

const AuthForm = ({ isLogin = false }) => {
  const navigate = useNavigate();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    setError('');
    if (!email || !password) {
      setError('Please fill in all fields.');
      return;
    }
    // In a real app, you'd integrate with Firebase or your backend for authentication
    // For this mock, we just set isLoggedIn to true
    mockUser.isLoggedIn = true;
    navigate('/chat');
  };

  return (
    <div className="auth-container">
      <form className="auth-form" onSubmit={handleSubmit}>
        <h2>{isLogin ? 'Log In' : 'Sign Up'}</h2>
        <div className="form-group">
          <label htmlFor="email">Email</label>
          <input type="email" id="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
        </div>
        <div className="form-group">
          <label htmlFor="password">Password</label>
          <input type="password" id="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
        </div>
        {error && <p className="error-message">{error}</p>}
        <button type="submit" className="btn-solid-green full-width">
          {isLogin ? 'Log In' : 'Sign Up'}
        </button>
        <div className="auth-switch">
          {isLogin ? (
            <p>Don't have an account? <Link to="/signup">Sign Up</Link></p>
          ) : (
            <p>Already have an account? <Link to="/login">Log In</Link></p>
          )}
        </div>
      </form>
    </div>
  );
};

const Login = () => <AuthForm isLogin={true} />;
const SignUp = () => <AuthForm isLogin={false} />;

// =================================================================================
// Header and Main App Component
// =================================================================================

const Header = ({ user }) => {
  const navigate = useNavigate();
  const handleLogout = () => {
    mockUser.isLoggedIn = false;
    navigate('/login');
  };

  return (
    <header className="app-header">
      <div className="logo">
        {/* Changed order: Dobby text first, then logo */}
        <div className="brand-names">
          <span className="main-brand">Dobby</span>
          <span className="sub-brand">GUVI Assistant</span>
        </div>
        <img src={chatbotLogo} alt="Dobby Logo" className="header-logo" />
      </div>
      <nav>
        {user && user.isLoggedIn ? (
          <button onClick={handleLogout} className="btn-solid-green">Log Out</button>
        ) : (
          <>
            <Link to="/login" className="link-green">Log In</Link>
            <Link to="/signup" className="btn-solid-green">Sign Up</Link>
          </>
        )}
      </nav>
    </header>
  );
};

function App() {
  const [user] = useState(mockUser);

  return (
    <Router>
      <div className="app-wrapper">
        <Header user={user} />
        <main className="main-content">
          <Routes>
            <Route path="/login" element={<Login />} />
            <Route path="/signup" element={<SignUp />} />
            <Route path="/chat" element={user.isLoggedIn ? <ChatPage /> : <Navigate to="/login" />} />
            <Route path="/" element={user.isLoggedIn ? <Navigate to="/chat" /> : <Navigate to="/login" />} />
          </Routes>
        </main>
      </div>
    </Router>
  );
}

export default App;