'use client';

import { useState, useRef, useEffect, useMemo } from 'react';
import {
  Box,
  Typography,
  Paper,
  Avatar,
  IconButton,
  Chip,
  useMediaQuery,
  Tooltip,
  Fab,
  Zoom,
} from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { motion, AnimatePresence } from 'framer-motion';
import {
  User,
  Bot,
  Sparkles,
  ChevronDown,
  RotateCcw,
  Copy,
  Check,
  AlertCircle,
} from 'lucide-react';
import Logo from './Logo';
import { useChatStore, type MessageAttachment } from '../services/chat-store';
import { useAuthStore } from '../services/auth-store';
import { useToolsStore } from '../services/tools-store';
import { useReservationStore } from '../services/reservation-store';
import { MOCK_USERS } from '../services/mock-data';
import { fileToDataUrl } from '../services/file-utils';
import AIInput from './AIInput';
import MarkdownMessage from './MarkdownMessage';

interface ChatApiResponse {
  content: string;
  mode?: 'live' | 'mock' | 'mock-fallback';
  matchedTools?: unknown[];
  sources?: string[];
  error?: string;
}

const SUGGESTED_PROMPTS = [
  { icon: '🔧', text: 'Wie repariere ich ein tropfendes Fahrrad-Ventil?' },
  { icon: '🪛', text: 'Welches Werkzeug brauche ich zum Bohren in Beton?' },
  { icon: '🖨️', text: 'Tipps für meinen ersten 3D-Druck mit PLA' },
  { icon: '📅', text: 'Wann ist das Repair Café geöffnet?' },
];

function formatTime(ts: number) {
  return new Date(ts).toLocaleTimeString('de-DE', {
    hour: '2-digit',
    minute: '2-digit',
  });
}

export default function ChatWindow() {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
  const { sessions, activeSessionId, addMessage, createSession } = useChatStore();

  const [isLoading, setIsLoading] = useState(false);
  const [lastMode, setLastMode] = useState<ChatApiResponse['mode'] | null>(null);
  const [showScrollDown, setShowScrollDown] = useState(false);
  const [copiedId, setCopiedId] = useState<string | null>(null);

  const scrollRef = useRef<HTMLDivElement>(null);
  const bottomRef = useRef<HTMLDivElement>(null);
  const activeSession = useMemo(
    () => sessions.find((s) => s.id === activeSessionId) ?? null,
    [sessions, activeSessionId]
  );

  useEffect(() => {
    if (!activeSession || activeSession.messages.length === 0) return;
    const last = activeSession.messages[activeSession.messages.length - 1];
    if (last.role === 'user' && !isLoading) {
      void sendToApi(activeSession.id);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeSession?.messages.length]);

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' });
  }, [activeSession?.messages.length, isLoading]);

  useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    const onScroll = () => {
      const distance = el.scrollHeight - el.scrollTop - el.clientHeight;
      setShowScrollDown(distance > 200);
    };
    el.addEventListener('scroll', onScroll);
    return () => el.removeEventListener('scroll', onScroll);
  }, [activeSessionId]);

  const sendToApi = async (sessionId: string) => {
    const current = useChatStore.getState().sessions.find((s) => s.id === sessionId);
    if (!current) return;
    setIsLoading(true);
    try {
      const history = current.messages.map((m) => ({
        role: m.role,
        content: m.content,
        attachments: m.attachments,
      }));
      const user = useAuthStore.getState().user;
      const tools = useToolsStore.getState().tools;
      const reservations = useReservationStore.getState().reservations;
      const context = {
        userRole: user?.role,
        username: user?.username,
        tools,
        reservations,
        users: MOCK_USERS.map((u) => ({ id: u.id, username: u.username, role: u.role })),
      };
      const response = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ messages: history, context }),
      });
      const data = (await response.json()) as ChatApiResponse;
      if (data.error || !data.content) throw new Error(data.error || 'Empty response');
      setLastMode(data.mode ?? null);
      addMessage(sessionId, { role: 'assistant', content: data.content });
    } catch (error) {
      const msg = error instanceof Error ? error.message : 'Unbekannter Fehler';
      addMessage(sessionId, {
        role: 'assistant',
        content: `⚠️ Es gab ein Problem bei der Verbindung: ${msg}`,
      });
    } finally {
      setIsLoading(false);
    }
  };

  const handleSend = async (content: string, files?: File[]) => {
    const hasFiles = Boolean(files && files.length > 0);
    if (!content.trim() && !hasFiles) return;
    let targetId = activeSessionId;
    if (!targetId) targetId = createSession(content.slice(0, 30) || 'Bild-Analyse');

    let attachments: MessageAttachment[] | undefined;
    if (hasFiles) {
      const processed = await Promise.all(
        files!.map(async (file) => {
          const { dataUrl, type, size } = await fileToDataUrl(file);
          return { name: file.name, type, dataUrl, size };
        })
      );
      attachments = processed;
    }

    addMessage(targetId, {
      role: 'user',
      content: content.trim(),
      attachments,
    });
  };

  const handleSuggested = (text: string) => handleSend(text);

  const handleCopy = async (id: string, text: string) => {
    try {
      await navigator.clipboard.writeText(text);
      setCopiedId(id);
      setTimeout(() => setCopiedId((cur) => (cur === id ? null : cur)), 1500);
    } catch {
      /* ignore */
    }
  };

  const handleRetry = () => {
    if (!activeSession || activeSession.messages.length === 0 || !activeSessionId) return;
    const lastUser = [...activeSession.messages].reverse().find((m) => m.role === 'user');
    if (lastUser) void sendToApi(activeSessionId);
  };

  const scrollToBottom = () =>
    bottomRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' });

  if (!activeSession) return <EmptyState onPick={handleSuggested} />;

  const isEmpty = activeSession.messages.length === 0;

  return (
    <Box
      sx={{
        flexGrow: 1,
        display: 'flex',
        flexDirection: 'column',
        height: '100%',
        bgcolor: 'background.default',
        position: 'relative',
        minWidth: 0,
      }}
    >
      {/* Header */}
      <Box
        sx={{
          px: { xs: 2, md: 3 },
          py: 1.5,
          borderBottom: '1px solid',
          borderColor: 'divider',
          bgcolor: 'background.paper',
          display: 'flex',
          alignItems: 'center',
          gap: 1.5,
          minHeight: 56,
          flexShrink: 0,
        }}
      >
        <Box
          sx={{
            width: 34,
            height: 34,
            borderRadius: 2.5,
            background: 'linear-gradient(135deg, #FF6B00, #E55F00)',
            color: 'white',
            display: 'grid',
            placeItems: 'center',
            flexShrink: 0,
            boxShadow: 'var(--pp-shadow-brand)',
          }}
        >
          <Bot size={16} />
        </Box>
        <Box sx={{ flexGrow: 1, minWidth: 0 }}>
          <Typography
            variant="subtitle1"
            sx={{
              fontWeight: 700,
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              whiteSpace: 'nowrap',
              fontSize: '0.95rem',
              lineHeight: 1.2,
            }}
          >
            {activeSession.title}
          </Typography>
          <Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.72rem' }}>
            {activeSession.messages.length} Nachrichten · PatchPilot-KI
          </Typography>
        </Box>
        <ModeBadge mode={lastMode} />
      </Box>

      {/* Messages */}
      <Box
        ref={scrollRef}
        sx={{
          flexGrow: 1,
          overflowY: 'auto',
          px: { xs: 2, md: 4 },
          py: { xs: 2.5, md: 3.5 },
          display: 'flex',
          flexDirection: 'column',
          gap: 2,
        }}
      >
        {isEmpty && (
          <Box sx={{ m: 'auto', textAlign: 'center', maxWidth: 480, py: 4 }}>
            <Box
              sx={{
                width: 52,
                height: 52,
                mx: 'auto',
                borderRadius: 3,
                display: 'grid',
                placeItems: 'center',
                background: 'linear-gradient(135deg, #FF6B00, #E55F00)',
                color: 'white',
                mb: 2,
                boxShadow: 'var(--pp-shadow-brand)',
              }}
            >
              <Sparkles size={24} />
            </Box>
            <Typography variant="h6" sx={{ fontWeight: 700, mb: 0.5 }}>
              Worüber sollen wir reden?
            </Typography>
            <Typography variant="body2" color="text.secondary">
              Wähle einen Vorschlag unten oder schreibe deine Frage.
            </Typography>
          </Box>
        )}

        <AnimatePresence initial={false}>
          {activeSession.messages.map((msg) => {
            const isUser = msg.role === 'user';
            return (
              <motion.div
                key={msg.id}
                initial={{ opacity: 0, y: 8 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0 }}
                transition={{ duration: 0.22, ease: 'easeOut' }}
              >
                <Box
                  sx={{
                    display: 'flex',
                    gap: { xs: 1.25, md: 1.5 },
                    flexDirection: isUser ? 'row-reverse' : 'row',
                    alignItems: 'flex-start',
                  }}
                >
                  <Avatar
                    sx={{
                      bgcolor: isUser ? 'primary.main' : 'secondary.main',
                      color: 'white',
                      width: 30,
                      height: 30,
                      mt: 0.5,
                      flexShrink: 0,
                    }}
                  >
                    {isUser ? <User size={15} /> : <Bot size={15} />}
                  </Avatar>
                  <Box
                    sx={{
                      maxWidth: { xs: '85%', md: '75%' },
                      display: 'flex',
                      flexDirection: 'column',
                      alignItems: isUser ? 'flex-end' : 'flex-start',
                      gap: 0.5,
                    }}
                  >
                    <Paper
                      elevation={0}
                      sx={{
                        px: { xs: 1.75, md: 2 },
                        py: { xs: 1.25, md: 1.5 },
                        borderRadius: 2.5,
                        borderTopRightRadius: isUser ? 6 : undefined,
                        borderTopLeftRadius: !isUser ? 6 : undefined,
                        bgcolor: isUser ? 'primary.main' : 'background.paper',
                        color: isUser ? 'white' : 'text.primary',
                        border: isUser ? 'none' : '1px solid',
                        borderColor: 'divider',
                        wordBreak: 'break-word',
                      }}
                    >
                      {msg.attachments && msg.attachments.length > 0 && (
                        <Box
                          sx={{
                            display: 'grid',
                            gridTemplateColumns:
                              msg.attachments.length === 1
                                ? '1fr'
                                : 'repeat(auto-fill, minmax(120px, 1fr))',
                            gap: 0.75,
                            mb: msg.content ? 1 : 0,
                          }}
                        >
                          {msg.attachments.map((att, i) =>
                            att.type.startsWith('image/') ? (
                              <Box
                                key={i}
                                component="a"
                                href={att.dataUrl}
                                target="_blank"
                                rel="noopener noreferrer"
                                sx={{
                                  display: 'block',
                                  borderRadius: 1.5,
                                  overflow: 'hidden',
                                  border: '1px solid',
                                  borderColor: isUser ? 'rgba(255,255,255,0.25)' : 'divider',
                                  maxWidth: msg.attachments!.length === 1 ? 280 : 'unset',
                                }}
                              >
                                <Box
                                  component="img"
                                  src={att.dataUrl}
                                  alt={att.name}
                                  sx={{
                                    width: '100%',
                                    height: 'auto',
                                    display: 'block',
                                    maxHeight: 260,
                                    objectFit: 'cover',
                                  }}
                                />
                              </Box>
                            ) : (
                              <Box
                                key={i}
                                sx={{
                                  p: 1,
                                  borderRadius: 1.5,
                                  border: '1px solid',
                                  borderColor: isUser ? 'rgba(255,255,255,0.25)' : 'divider',
                                  fontSize: '0.75rem',
                                  fontWeight: 600,
                                  bgcolor: isUser ? 'rgba(255,255,255,0.1)' : 'action.hover',
                                  display: 'flex',
                                  alignItems: 'center',
                                  gap: 0.75,
                                }}
                              >
                                📎 {att.name}
                              </Box>
                            )
                          )}
                        </Box>
                      )}
                      {msg.content &&
                        (isUser ? (
                          <Typography
                            variant="body1"
                            sx={{ fontSize: '0.95rem', lineHeight: 1.55, whiteSpace: 'pre-wrap' }}
                          >
                            {msg.content}
                          </Typography>
                        ) : (
                          <MarkdownMessage content={msg.content} />
                        ))}
                    </Paper>
                    <Box
                      sx={{
                        display: 'flex',
                        alignItems: 'center',
                        gap: 0.5,
                        px: 0.25,
                        opacity: 0.7,
                      }}
                    >
                      <Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.7rem' }}>
                        {formatTime(msg.timestamp)}
                      </Typography>
                      {!isUser && (
                        <Tooltip title={copiedId === msg.id ? 'Kopiert!' : 'Kopieren'}>
                          <IconButton
                            size="small"
                            onClick={() => handleCopy(msg.id, msg.content)}
                            sx={{ p: 0.25, color: 'text.secondary' }}
                          >
                            {copiedId === msg.id ? <Check size={12} /> : <Copy size={12} />}
                          </IconButton>
                        </Tooltip>
                      )}
                    </Box>
                  </Box>
                </Box>
              </motion.div>
            );
          })}
        </AnimatePresence>

        {isLoading && (
          <motion.div
            initial={{ opacity: 0, y: 8 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.2 }}
          >
            <Box sx={{ display: 'flex', gap: 1.5, alignItems: 'flex-start' }}>
              <Avatar
                sx={{
                  bgcolor: 'secondary.main',
                  color: 'white',
                  width: 30,
                  height: 30,
                  mt: 0.5,
                  flexShrink: 0,
                }}
              >
                <Bot size={15} />
              </Avatar>
              <Paper
                elevation={0}
                sx={{
                  px: 2,
                  py: 1.5,
                  borderRadius: 2.5,
                  borderTopLeftRadius: 6,
                  border: '1px solid',
                  borderColor: 'divider',
                  bgcolor: 'background.paper',
                  display: 'inline-flex',
                  alignItems: 'center',
                  color: 'text.secondary',
                }}
              >
                <Box component="span" className="pp-typing">
                  <span /> <span /> <span />
                </Box>
              </Paper>
            </Box>
          </motion.div>
        )}

        <div ref={bottomRef} />
      </Box>

      {/* Scroll-to-bottom */}
      <Zoom in={showScrollDown}>
        <Fab
          size="small"
          color="primary"
          onClick={scrollToBottom}
          sx={{
            position: 'absolute',
            bottom: { xs: 140, md: 150 },
            right: { xs: 16, md: 28 },
            boxShadow: 'var(--pp-shadow-brand)',
          }}
          aria-label="Zum Ende scrollen"
        >
          <ChevronDown size={18} />
        </Fab>
      </Zoom>

      {/* Footer */}
      <Box
        sx={{
          px: { xs: 2, md: 4 },
          pt: 1.5,
          pb: { xs: 2, md: 2.5 },
          borderTop: '1px solid',
          borderColor: 'divider',
          bgcolor: 'background.paper',
          flexShrink: 0,
        }}
      >
        {isEmpty && (
          <Box
            sx={{
              display: 'flex',
              flexWrap: 'wrap',
              gap: 1,
              mb: 1.5,
              maxWidth: 760,
              mx: 'auto',
            }}
          >
            {SUGGESTED_PROMPTS.map((p) => (
              <Chip
                key={p.text}
                onClick={() => handleSuggested(p.text)}
                clickable
                variant="outlined"
                label={`${p.icon}  ${p.text}`}
                sx={{
                  borderRadius: 2,
                  height: 32,
                  fontSize: '0.78rem',
                  borderStyle: 'dashed',
                  '&:hover': {
                    borderColor: 'primary.main',
                    bgcolor: 'action.hover',
                    borderStyle: 'solid',
                  },
                }}
              />
            ))}
          </Box>
        )}
        <Box
          sx={{
            display: 'flex',
            alignItems: 'flex-end',
            gap: 1,
            maxWidth: 760,
            mx: 'auto',
          }}
        >
          <Box sx={{ flexGrow: 1, minWidth: 0 }}>
            <AIInput onSend={handleSend} isLoading={isLoading} compact />
          </Box>
          {!isMobile && (
            <Tooltip title="Letzte Anfrage erneut senden">
              <span>
                <IconButton
                  onClick={handleRetry}
                  disabled={isLoading || activeSession.messages.length === 0}
                  sx={{
                    border: '1px solid',
                    borderColor: 'divider',
                    borderRadius: 2,
                    width: 40,
                    height: 40,
                  }}
                >
                  <RotateCcw size={16} />
                </IconButton>
              </span>
            </Tooltip>
          )}
        </Box>
      </Box>
    </Box>
  );
}

function EmptyState({ onPick }: { onPick: (text: string) => void }) {
  return (
    <Box
      sx={{
        flexGrow: 1,
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        p: { xs: 3, md: 6 },
        textAlign: 'center',
        bgcolor: 'background.default',
        minWidth: 0,
      }}
    >
      <Box sx={{ mb: 2.5 }}>
        <Logo size={72} />
      </Box>
      <Typography variant="h5" sx={{ fontWeight: 800, mb: 1, letterSpacing: '-0.01em' }}>
        Womit darf ich helfen?
      </Typography>
      <Typography color="text.secondary" sx={{ maxWidth: 460, mb: 4, lineHeight: 1.55 }}>
        Frag mich nach Werkzeugen, Reparatur-Tipps oder beschreibe dein Problem.
      </Typography>
      <Box
        sx={{
          display: 'grid',
          gridTemplateColumns: { xs: '1fr', sm: 'repeat(2, 1fr)' },
          gap: 1.5,
          width: '100%',
          maxWidth: 640,
        }}
      >
        {SUGGESTED_PROMPTS.map((p) => (
          <Paper
            key={p.text}
            variant="outlined"
            onClick={() => onPick(p.text)}
            sx={{
              p: 2,
              cursor: 'pointer',
              textAlign: 'left',
              borderRadius: 2.5,
              transition: 'all 0.2s',
              borderStyle: 'dashed',
              '&:hover': {
                borderColor: 'primary.main',
                bgcolor: 'action.hover',
                transform: 'translateY(-2px)',
                borderStyle: 'solid',
              },
            }}
          >
            <Typography variant="body2" sx={{ fontWeight: 600, fontSize: '0.88rem' }}>
              {p.icon}&nbsp;&nbsp;{p.text}
            </Typography>
          </Paper>
        ))}
      </Box>
    </Box>
  );
}

function ModeBadge({ mode }: { mode: ChatApiResponse['mode'] | null }) {
  if (!mode) return null;
  if (mode === 'live') {
    return (
      <Chip
        size="small"
        label="Live"
        sx={{
          bgcolor: 'success.main',
          color: 'white',
          fontWeight: 700,
          fontSize: '0.65rem',
          height: 22,
          letterSpacing: '0.05em',
        }}
      />
    );
  }
  if (mode === 'mock-fallback') {
    return (
      <Tooltip title="Live-API nicht erreichbar, Fallback aktiv">
        <Chip
          size="small"
          icon={<AlertCircle size={11} />}
          label="Fallback"
          sx={{
            bgcolor: 'warning.main',
            color: 'white',
            fontWeight: 700,
            fontSize: '0.65rem',
            height: 22,
          }}
        />
      </Tooltip>
    );
  }
  return (
    <Chip
      size="small"
      label="Demo"
      variant="outlined"
      sx={{ fontWeight: 700, fontSize: '0.65rem', height: 22 }}
    />
  );
}
