
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { Search, Map, BrainCircuit, User, Bot, Globe, Send, ExternalLink, Loader } from 'lucide-react';
import { generateText } from '../services/geminiService';
import { ChatMessage, GroundingChunk } from '../types';

const GroundedSearchView: React.FC = () => {
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [input, setInput] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [useSearch, setUseSearch] = useState(true);
  const [useMaps, setUseMaps] = useState(false);
  const [useThinking, setUseThinking] = useState(false);

  const messagesEndRef = useRef<HTMLDivElement>(null);

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  useEffect(scrollToBottom, [messages]);
  
  const handleSend = useCallback(async () => {
    if (!input.trim()) return;

    const userMessage: ChatMessage = { role: 'user', parts: [{ text: input }] };
    setMessages(prev => [...prev, userMessage]);
    setInput('');
    setIsLoading(true);

    try {
      const response = await generateText(input, useSearch, useMaps, useThinking);
      const modelMessage: ChatMessage = {
        role: 'model',
        parts: [{ text: response.text }],
        groundingChunks: response.candidates?.[0]?.groundingMetadata?.groundingChunks as GroundingChunk[],
      };
      setMessages(prev => [...prev, modelMessage]);
    } catch (error) {
      console.error('API Error:', error);
      const errorMessage: ChatMessage = {
        role: 'model',
        parts: [{ text: `An error occurred: ${error instanceof Error ? error.message : String(error)}` }],
      };
      setMessages(prev => [...prev, errorMessage]);
    } finally {
      setIsLoading(false);
    }
  }, [input, useSearch, useMaps, useThinking]);

  const Toggle: React.FC<{
    icon: React.ReactNode;
    label: string;
    enabled: boolean;
    onChange: (enabled: boolean) => void;
  }> = ({ icon, label, enabled, onChange }) => (
    <button
      onClick={() => onChange(!enabled)}
      className={`flex items-center space-x-2 px-3 py-2 rounded-full text-sm transition-colors ${
        enabled ? 'bg-indigo-600 text-white' : 'bg-slate-700 text-slate-300 hover:bg-slate-600'
      }`}
    >
      {icon}
      <span>{label}</span>
    </button>
  );

  const Message: React.FC<{ message: ChatMessage }> = ({ message }) => {
    const isModel = message.role === 'model';
    return (
      <div className={`flex items-start gap-4 ${isModel ? '' : 'justify-end'}`}>
        {isModel && (
          <div className="flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center bg-indigo-600">
            <Bot className="text-white" />
          </div>
        )}
        <div className={`p-4 rounded-xl max-w-2xl ${isModel ? 'bg-slate-800' : 'bg-indigo-700 text-white'}`}>
            <p className="whitespace-pre-wrap">{message.parts[0].text}</p>
            {message.groundingChunks && message.groundingChunks.length > 0 && (
                <div className="mt-4 pt-3 border-t border-slate-700">
                    <h4 className="text-sm font-semibold text-slate-400 mb-2">Sources:</h4>
                    <div className="flex flex-wrap gap-2">
                        {message.groundingChunks.map((chunk, i) => {
                            const source = chunk.web || chunk.maps;
                            return source && (
                                <a href={source.uri} target="_blank" rel="noopener noreferrer" key={i} className="bg-slate-700 text-xs text-slate-300 px-2 py-1 rounded-md hover:bg-slate-600 transition-colors flex items-center gap-1">
                                    {chunk.web ? <Globe size={12}/> : <Map size={12}/>}
                                    {source.title}
                                    <ExternalLink size={12}/>
                                </a>
                            );
                        })}
                    </div>
                </div>
            )}
        </div>
        {!isModel && (
           <div className="flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center bg-slate-700">
             <User className="text-white" />
           </div>
        )}
      </div>
    );
  };

  return (
    <div className="h-full flex flex-col">
      <header className="border-b border-slate-700 pb-4 mb-4">
        <h1 className="text-3xl font-bold text-white">Grounded Search & Reasoning</h1>
        <p className="mt-1 text-slate-400">Get up-to-date information and handle complex queries using Gemini.</p>
      </header>
      <div className="flex items-center justify-center gap-3 mb-4">
        <Toggle icon={<Search size={16} />} label="Google Search" enabled={useSearch} onChange={setUseSearch} />
        <Toggle icon={<Map size={16} />} label="Google Maps" enabled={useMaps} onChange={setUseMaps} />
        <Toggle icon={<BrainCircuit size={16} />} label="Thinking Mode" enabled={useThinking} onChange={setUseThinking} />
      </div>
      <div className="flex-1 overflow-y-auto pr-4 space-y-6">
        {messages.map((msg, index) => <Message key={index} message={msg} />)}
        {isLoading && (
            <div className="flex items-start gap-4">
               <div className="flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center bg-indigo-600"><Bot className="text-white" /></div>
               <div className="p-4 rounded-xl max-w-2xl bg-slate-800"><Loader text="Consulting the Codex..." /></div>
            </div>
        )}
        <div ref={messagesEndRef} />
      </div>
      <div className="mt-6 flex items-center gap-4">
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyPress={(e) => e.key === 'Enter' && handleSend()}
          placeholder="Ask a complex question or for recent information..."
          className="flex-1 bg-slate-800 border border-slate-700 rounded-lg px-4 py-3 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
          disabled={isLoading}
        />
        <button onClick={handleSend} disabled={isLoading || !input.trim()} className="bg-indigo-600 text-white p-3 rounded-lg disabled:bg-indigo-900 disabled:cursor-not-allowed hover:bg-indigo-700 transition-colors">
          <Send />
        </button>
      </div>
    </div>
  );
};

export default GroundedSearchView;
