'use client'
import { useState, useEffect, useRef } from 'react'
import { useChat } from '@ai-sdk/react'
import { DefaultChatTransport, type UIMessage } from 'ai'
import { Button } from '~/components/ui/button'
import { Textarea } from '~/components/ui/textarea'
import { SignInButton } from '@clerk/nextjs'
import {
	useGsapContext,
} from '~/app/_providers/GsapProvicer';
import Messages from './Messages'
import { DeleteIcon } from 'lucide-react';
import { Spinner } from '~/components/ui/spinner';
import { useMessages } from '~/app/_providers/MessagesProvider';
interface DBMessage {
	id: string
	role: 'user' | 'assistant'
	content: string
}

interface ChatInterfaceProps {
	sessionId?: string,
	dbMessages: DBMessage[],
}

function SignInChatPrompt() {
	return (
		<div className="flex h-full w-full flex-col items-center justify-center gap-4 text-center">
			<div className="space-y-2">
				<h2 className="text-xl font-semibold">Sign in to use the chat</h2>
				<p className="text-sm text-muted-foreground">
					You need to be signed in before you can talk to Gregor's AI assistant.
				</p>
			</div>
			<SignInButton mode="modal">
				<Button type="button">Sign in</Button>
			</SignInButton>
		</div>
	)
}

function toUIMessages(dbMessages: DBMessage[]): UIMessage[] {
	return dbMessages.map((m) => ({
		id: m.id,
		role: m.role,
		parts: [{ type: 'text' as const, text: m.content }],
	}))
}

function addInitMessage(messageArray: UIMessage[]) {
	if (messageArray.at(0)?.id != 'init') {
		messageArray.unshift({
			id: "init",
			role: 'assistant',
			parts: [{
				type: 'text',
				text: "Hi, I'm Gregor's AI assistant. Ask me about his experience, projects, blog posts, or availability for a meeting."
			}],
		})
	}
}

function AuthenticatedChatInterface({ dbMessages, sessionId }: ChatInterfaceProps & { sessionId: string }) {
	const [input, setInput] = useState('')
	const {  clearingChat, clearChat, refetchMessages } = useMessages();
	const initialMessages = toUIMessages(dbMessages)
	addInitMessage(initialMessages)
	const { messages, sendMessage, status, error, clearError, setMessages } = useChat({
		transport: new DefaultChatTransport({
			api: '/api/chat', body: { sessionId },
		}),
		messages: initialMessages,
	})
	useEffect(() => {
		return () => {
			refetchMessages()
		}
	}, [])
	const handleSend = () => {
		const text = input.trim()
		if (!text || status != 'ready' || clearingChat) return
		setInput('')
		sendMessage({ text })
	}
	const gsapContext = useGsapContext()
	const didInitialScroll = useRef(false)
	useEffect(() => {
		const scroller = gsapContext?.getScroller()
		if (!scroller || scroller instanceof Window) {
			return
		}
		// Jump instantly on first open so the chat starts pinned to the bottom;
		// animate subsequent updates. Defer a frame so the messages have laid out
		// (and any streaming content has grown) before we measure scrollHeight.
		const behavior: ScrollBehavior = didInitialScroll.current ? 'smooth' : 'auto'
		didInitialScroll.current = true
		requestAnimationFrame(() => {
			scroller.scrollTo({ behavior, top: scroller.scrollHeight })
		})
	}, [messages, status])
	return (
		<div className="flex flex-col h-full">
			{messages &&
				<Messages status={status} messages={messages} />
			}
			{error && (
				<div className="mx-4 mb-2 flex items-start gap-2 rounded-lg border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm text-destructive">
					<span className="flex-1">
						{error.message.includes('quota') || error.message.includes('429')
							? 'OpenAI quota exceeded. Please try again later.'
							: `Error: ${error.message}`}
					</span>
					<Button
						type="button"
						onClick={clearError}
						className="shrink-0 opacity-60 hover:opacity-100"
						variant='destructive'
					>
						<DeleteIcon />
					</Button>
				</div>
			)}

			<div className="p-4 border-t flex flex-row gap-2 shrink-0">
				<Textarea
					name='message'
					value={input}
					onChange={(e) => setInput(e.target.value)}
					placeholder="Ask about Gregor's experience or schedule a meeting…"
					className="resize-none"
					rows={2}
					onKeyDown={(e) => {
						if (e.key === 'Enter' && !e.shiftKey) {
							e.preventDefault()
							handleSend()
						}
					}}
				/>
				<div className='flex flex-col gap-2'>
					<Button
						onClick={handleSend}
						disabled={status != "ready" || !input.trim()}
					>
						Send
					</Button>
					<Button
						variant='destructive'
						onClick={() => {
							clearChat(() => {
								let messages: UIMessage[] = [];
								addInitMessage(messages);
								setMessages(messages)
							})
						}}
						disabled={status != "ready" || clearingChat}
					>
						{clearingChat ?
							<Spinner /> :
							"Clear Chat"
						}
					</Button>
				</div>
			</div>
		</div>
	)
}

export default function ChatInterface({ dbMessages, sessionId }: ChatInterfaceProps) {
	if (sessionId == undefined) {
		return <SignInChatPrompt />
	}
	return <AuthenticatedChatInterface sessionId={sessionId} dbMessages={dbMessages} />
}
