import { useEffect, useRef } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { X, Plus, Loader2, AlertTriangle, RotateCcw } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useChatSession } from '@/hooks/useChatSession';
import { ChatBubble } from './ChatBubble';
import { ChatInput } from './ChatInput';

export interface ChatTarget {
  type: 'phase' | 'task';
  id: string;
  name: string;
}

interface ChatSlideOverProps {
  target: ChatTarget | null;
  initiativeId: string;
  onClose: () => void;
}

export function ChatSlideOver({ target, initiativeId, onClose }: ChatSlideOverProps) {
  return (
    <AnimatePresence>
      {target && (
        <ChatSlideOverInner
          key={`${target.type}-${target.id}`}
          target={target}
          initiativeId={initiativeId}
          onClose={onClose}
        />
      )}
    </AnimatePresence>
  );
}

function ChatSlideOverInner({
  target,
  initiativeId,
  onClose,
}: {
  target: ChatTarget;
  initiativeId: string;
  onClose: () => void;
}) {
  const { session, messages, agentStatus, agentError, sendMessage, retryLastMessage, closeSession, startNewSession, isSending } =
    useChatSession(target.type, target.id, initiativeId);

  const scrollRef = useRef<HTMLDivElement>(null);

  // Auto-scroll on new messages
  useEffect(() => {
    const el = scrollRef.current;
    if (el) {
      el.scrollTop = el.scrollHeight;
    }
  }, [messages.length]);

  // Escape to close
  useEffect(() => {
    function onKeyDown(e: KeyboardEvent) {
      if (e.key === 'Escape') onClose();
    }
    document.addEventListener('keydown', onKeyDown);
    return () => document.removeEventListener('keydown', onKeyDown);
  }, [onClose]);

  const isAgentWorking = agentStatus === 'running' || isSending;

  function handleClose() {
    closeSession();
    onClose();
  }

  return (
    <>
      {/* Backdrop */}
      <motion.div
        className="fixed inset-0 z-40 bg-background/60 backdrop-blur-[2px]"
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        transition={{ duration: 0.2 }}
        onClick={onClose}
      />

      {/* Panel */}
      <motion.div
        className="fixed inset-y-0 right-0 z-50 flex w-full max-w-2xl flex-col border-l border-border bg-background shadow-xl"
        initial={{ x: '100%' }}
        animate={{ x: 0 }}
        exit={{ x: '100%' }}
        transition={{ duration: 0.25, ease: [0, 0, 0.2, 1] }}
      >
        {/* Header */}
        <div className="flex items-center gap-3 border-b border-border px-5 py-3">
          <div className="min-w-0 flex-1">
            <h3 className="text-sm font-semibold leading-snug">
              Chat: {target.name}
            </h3>
            <p className="text-xs text-muted-foreground capitalize">{target.type}</p>
          </div>
          {isAgentWorking && (
            <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
              <Loader2 className="h-3 w-3 animate-spin" />
              Processing...
            </div>
          )}
          {session && messages.length > 0 && (
            <button
              className="shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-50"
              title="New Chat"
              disabled={isAgentWorking}
              onClick={(e) => {
                if (!e.shiftKey && !window.confirm('Start a new chat? The current conversation will be closed.')) return;
                startNewSession();
              }}
            >
              <Plus className="h-4 w-4" />
            </button>
          )}
          <button
            className="shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"
            onClick={handleClose}
          >
            <X className="h-4 w-4" />
          </button>
        </div>

        {/* Messages */}
        <div ref={scrollRef} className="flex-1 overflow-y-auto py-3">
          {messages.length === 0 && (
            <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
              Send a message to start refining this {target.type}
            </div>
          )}
          {messages.map((msg) => (
            <ChatBubble key={msg.id} message={msg} />
          ))}
          {isAgentWorking && messages.length > 0 && (
            <div className="flex justify-start px-4 py-1.5">
              <div className="flex items-center gap-2 rounded-lg border border-border bg-card px-3 py-2 text-sm text-muted-foreground">
                <Loader2 className="h-3 w-3 animate-spin" />
                Thinking...
              </div>
            </div>
          )}
          {agentStatus === 'crashed' && agentError && (
            <div className="mx-4 my-2 rounded-lg border border-status-error-border bg-status-error-bg px-3 py-2.5">
              <div className="flex items-start gap-2">
                <AlertTriangle className="mt-0.5 h-3.5 w-3.5 shrink-0 text-status-error-fg" />
                <div className="min-w-0 flex-1">
                  <p className="text-xs font-medium text-status-error-fg">Agent error</p>
                  <p className="mt-0.5 text-xs text-status-error-fg/80 break-words">{agentError}</p>
                </div>
              </div>
              <div className="mt-2 flex justify-end">
                <Button
                  variant="outline"
                  size="sm"
                  className="h-6 gap-1.5 text-xs"
                  onClick={retryLastMessage}
                >
                  <RotateCcw className="h-3 w-3" />
                  Retry
                </Button>
              </div>
            </div>
          )}
        </div>

        {/* Input */}
        <ChatInput
          onSend={sendMessage}
          disabled={isAgentWorking}
          placeholder={`Tell the agent what to change...`}
        />
      </motion.div>
    </>
  );
}
