import { useState, useCallback, useEffect } from "react"; import { TopBar } from "@/components/transcript/TopBar"; import { TranscriptPanel } from "@/components/transcript/TranscriptPanel"; import { InputBar } from "@/components/transcript/InputBar"; import { SettingsPanel, TranscriptSettings } from "@/components/transcript/SettingsPanel"; import { TranscriptMessageData } from "@/components/transcript/TranscriptMessage"; import { AvatarFrame } from "@/components/AvatarFrame"; import { useHeyGenAvatar } from "@/hooks/useHeyGenAvatar"; import { supabase } from "@/integrations/supabase/client"; import { toast } from "@/hooks/use-toast"; import { VoiceEmotion } from "@heygen/streaming-avatar";

const Index = () => { const [messages, setMessages] = useState<TranscriptMessageData[] data-preserve-html-node="true">([]); const [isTyping, setIsTyping] = useState(false); const [isSettingsOpen, setIsSettingsOpen] = useState(false); const [isDark, setIsDark] = useState(true); const [settings, setSettings] = useState({ showTimestamps: false, showAvatars: true, connectionMethod: "embedded", sttProvider: "browser", heygenUrl: "", });

const [isSpeaking, setIsSpeaking] = useState(false); const [isMuted, setIsMuted] = useState(false); const [isVideoOff, setIsVideoOff] = useState(false);

// Apply theme useEffect(() => { document.documentElement.classList.toggle("dark", isDark); }, [isDark]);

const { isConnected, isLoading, error, mediaStream, connect, disconnect, speak, } = useHeyGenAvatar({ avatarId: "default", rate: 1.0, emotion: VoiceEmotion.FRIENDLY, onSpeakingStart: () => setIsSpeaking(true), onSpeakingEnd: () => setIsSpeaking(false), });

// Show error toast useEffect(() => { if (error) { toast({ title: "Connection Error", description: error, variant: "destructive", }); } }, [error]);

const handleConnect = useCallback(async () => { await connect(); toast({ title: "Connecting", description: "Establishing connection to HeyGen avatar...", }); }, [connect]);

const handleDisconnect = useCallback(async () => { await disconnect(); toast({ title: "Disconnected", description: "Session ended.", }); }, [disconnect]);

const handleSendMessage = useCallback( async (content: string) => { const userMessage: TranscriptMessageData = { id: Date.now().toString(), role: "user", content, timestamp: new Date(), }; setMessages((prev) => [...prev, userMessage]); setIsTyping(true);

try {
    const { data, error: fnError } = await supabase.functions.invoke("chat", {
      body: {
        messages: [
          ...messages.map((m) => ({
            role: m.role === "avatar" ? "assistant" : m.role,
            content: m.content,
          })),
          { role: "user", content },
        ],
      },
    });

    if (fnError) throw fnError;

    const aiResponse = data?.content || "I'm sorry, I couldn't generate a response.";

    if (isConnected) {
      await speak(aiResponse);
    }

    const avatarMessage: TranscriptMessageData = {
      id: (Date.now() + 1).toString(),
      role: "avatar",
      content: aiResponse,
      timestamp: new Date(),
    };
    setMessages((prev) => [...prev, avatarMessage]);
  } catch (err) {
    console.error("Failed to send message:", err);
    toast({
      title: "Error",
      description: err instanceof Error ? err.message : "Failed to get response",
      variant: "destructive",
    });
  } finally {
    setIsTyping(false);
  }
},
[speak, messages, isConnected]

);

const handleClearConversation = useCallback(() => { setMessages([]); toast({ title: "Cleared", description: "Conversation cleared.", }); }, []);

const handleCopyAll = useCallback(() => { const markdown = messages .map((m) => **${m.role === "user" ? "You" : "Avatar"}:** ${m.content}) .join("\n\n");

const plain = messages
  .map((m) => `${m.role === "user" ? "You" : "Avatar"}: ${m.content}`)
  .join("\n\n");

navigator.clipboard.writeText(plain).then(() => {
  toast({
    title: "Copied",
    description: "Full conversation copied to clipboard.",
  });
});

}, [messages]);

return (

<TopBar data-preserve-html-node="true" isConnected={isConnected} isConnecting={isLoading} sessionName={isConnected ? "HeyGen Session" : undefined} messageCount={messages.length} messages={messages} onConnect={handleConnect} onDisconnect={handleDisconnect} onClearConversation={handleClearConversation} onCopyAll={handleCopyAll} onOpenSettings={() => setIsSettingsOpen(true)} isDark={isDark} onToggleTheme={() => setIsDark(!isDark)} />

{/* Main content: Avatar + Transcript side by side */}
  <div className="flex-1 flex gap-4 p-4 overflow-hidden">
    {/* Avatar Frame */}
    <div className="w-1/2 min-w-[300px]">
      <AvatarFrame
        mediaStream={mediaStream}
        isConnected={isConnected}
        isLoading={isLoading}
        isSpeaking={isSpeaking}
        isMuted={isMuted}
        isVideoOff={isVideoOff}
        onToggleMute={() => setIsMuted(!isMuted)}
        onToggleVideo={() => setIsVideoOff(!isVideoOff)}
      />
    </div>

    {/* Transcript Panel */}
    <div className="flex-1 min-w-[300px]">
      <TranscriptPanel
        messages={messages}
        isTyping={isTyping}
        showTimestamps={settings.showTimestamps}
        showAvatars={settings.showAvatars}
      />
    </div>
  </div>

  <InputBar onSendMessage={handleSendMessage} disabled={!isConnected && settings.connectionMethod === "embedded"} />

  <SettingsPanel
    isOpen={isSettingsOpen}
    onClose={() => setIsSettingsOpen(false)}
    settings={settings}
    onUpdateSettings={setSettings}
  />
</div>

); };

export default Index;