'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { ArrowUp, Sparkles, X } from 'lucide-react';
import { cn } from '@/lib/cn';
import { useMessages } from '@/i18n/client';
import { ChatText } from './ChatText';

export interface ChatSeed {
  id: number;
  text: string;
}

interface Message {
  id: string;
  role: 'user' | 'assistant';
  content: string;
}

interface AskAiSheetProps {
  open: boolean;
  onClose: () => void;
  /** Question to send as soon as the sheet opens (from a chapter's "Tanya AI" link). */
  seed: ChatSeed | null;
  /** The report the assistant answers from — the server loads it and checks access. */
  reportId: string;
  suggestions: string[];
}

export function AskAiSheet({ open, onClose, seed, reportId, suggestions }: AskAiSheetProps) {
  const t = useMessages().chat;
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const scrollRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLTextAreaElement>(null);
  const handledSeed = useRef<number | null>(null);

  const send = useCallback(
    async (text: string) => {
      const query = text.trim();
      if (!query || loading) return;

      const userMsg: Message = { id: crypto.randomUUID(), role: 'user', content: query };
      const history = [...messages, userMsg];
      setMessages(history);
      setInput('');
      setLoading(true);

      let reply = t.unavailable;
      try {
        const res = await fetch('/api/chat', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            messages: history.map(({ role, content }) => ({ role, content })),
            reportId,
          }),
        });
        const data = await res.json();
        if (data.reply) reply = data.reply;
        else if (data.error) reply = data.error;
      } catch {
        // fall through to the friendly error reply
      }
      setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'assistant', content: reply }]);
      setLoading(false);
    },
    [reportId, loading, messages, t.unavailable],
  );

  useEffect(() => {
    if (!open || !seed || handledSeed.current === seed.id) return;
    handledSeed.current = seed.id;
    send(seed.text);
  }, [open, seed, send]);

  useEffect(() => {
    if (!open) return;
    inputRef.current?.focus();
    const onKey = (e: KeyboardEvent) => e.key === 'Escape' && onClose();
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [open, onClose]);

  useEffect(() => {
    scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight, behavior: 'smooth' });
  }, [messages, loading]);

  return (
    <AnimatePresence>
      {open && (
        <>
          {/* Dim only on small screens; on desktop the report stays readable beside the panel. */}
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            onClick={onClose}
            className="fixed inset-0 z-40 bg-night-950/40 backdrop-blur-[2px] lg:hidden print:hidden"
          />
          <motion.aside
            role="complementary"
            aria-label={t.title}
            initial={{ x: '100%' }}
            animate={{ x: 0 }}
            exit={{ x: '100%' }}
            transition={{ duration: 0.4, ease: [0.16, 1, 0.3, 1] }}
            className="fixed inset-y-0 right-0 z-50 flex w-full flex-col bg-surface shadow-float sm:w-[420px] lg:border-l lg:border-line lg:shadow-none print:hidden"
          >
            <header className="flex h-16 shrink-0 items-center justify-between gap-4 border-b border-line px-5">
              <div className="flex items-center gap-3">
                <span className="inline-flex size-9 items-center justify-center rounded-full bg-night-900 text-white">
                  <Sparkles className="size-4" aria-hidden />
                </span>
                <div>
                  <p className="text-sm font-semibold text-ink">{t.title}</p>
                  <p className="text-xs text-muted">{t.subtitle}</p>
                </div>
              </div>
              <button
                type="button"
                onClick={onClose}
                aria-label={t.close}
                className="inline-flex size-9 items-center justify-center rounded-full text-ink-soft transition-colors hover:bg-canvas"
              >
                <X className="size-4" />
              </button>
            </header>

            <div ref={scrollRef} className="flex-1 overflow-y-auto px-5 py-6">
              {messages.length === 0 ? (
                <div>
                  <p className="text-[15px] leading-relaxed text-ink">{t.greeting}</p>
                  <p className="eyebrow mt-8 mb-3 text-subtle">{t.tryAsking}</p>
                  <ul className="space-y-2">
                    {suggestions.map((s) => (
                      <li key={s}>
                        <button
                          type="button"
                          onClick={() => send(s)}
                          className="w-full rounded-2xl bg-canvas px-4 py-3 text-left text-[13px] leading-snug text-ink-soft ring-1 ring-line transition-colors hover:bg-accent-soft hover:text-ink"
                        >
                          {s}
                        </button>
                      </li>
                    ))}
                  </ul>
                </div>
              ) : (
                <ol className="space-y-5" aria-live="polite">
                  {messages.map((m) => (
                    <li key={m.id} className={cn('flex', m.role === 'user' && 'justify-end')}>
                      <div
                        className={cn(
                          'text-[14px] leading-relaxed',
                          m.role === 'user'
                            ? 'max-w-[85%] whitespace-pre-line rounded-[20px] rounded-br-md bg-ink px-4 py-2.5 text-white'
                            : 'text-ink-soft',
                        )}
                      >
                        {m.role === 'assistant' ? <ChatText text={m.content} /> : m.content}
                      </div>
                    </li>
                  ))}
                  {loading && (
                    <li className="flex items-center gap-1.5 py-2" aria-label={t.typing}>
                      {[0, 150, 300].map((d) => (
                        <span
                          key={d}
                          className="size-1.5 animate-bounce rounded-full bg-subtle"
                          style={{ animationDelay: `${d}ms` }}
                        />
                      ))}
                    </li>
                  )}
                </ol>
              )}
            </div>

            <form
              onSubmit={(e) => {
                e.preventDefault();
                send(input);
              }}
              className="shrink-0 border-t border-line p-4"
            >
              <div className="flex items-end gap-2 rounded-[22px] bg-canvas p-1.5 pl-4 ring-1 ring-line transition-shadow focus-within:ring-ink/25">
                <label htmlFor="ask-ai-input" className="sr-only">
                  {t.question}
                </label>
                <textarea
                  id="ask-ai-input"
                  ref={inputRef}
                  rows={1}
                  value={input}
                  onChange={(e) => setInput(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {
                      e.preventDefault();
                      send(input);
                    }
                  }}
                  placeholder={t.placeholder}
                  className="max-h-32 min-h-9 flex-1 resize-none bg-transparent py-2 text-sm text-ink [field-sizing:content] placeholder:text-subtle focus:outline-none"
                />
                <button
                  type="submit"
                  disabled={!input.trim() || loading}
                  aria-label={t.send}
                  className="inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-ink text-white transition-opacity disabled:opacity-25"
                >
                  <ArrowUp className="size-4" />
                </button>
              </div>
              <p className="mt-2 text-center text-[11px] text-subtle">
                {t.disclaimer}
              </p>
            </form>
          </motion.aside>
        </>
      )}
    </AnimatePresence>
  );
}
