import React, { useState, useRef, useCallback } from 'react';
import {
  View,
  Text,
  StyleSheet,
  FlatList,
  TextInput,
  TouchableOpacity,
  KeyboardAvoidingView,
  Platform,
  Animated,
} from 'react-native';
import { COLORS, FONT_SIZE, SPACING, RADIUS, TEXT, SHADOWS } from '../theme';
import { useTheme } from '../theme';
import { chatAPI } from '../services/api';

interface ChatInterfaceProps {
  chatbotId: string;
  welcomeMessage?: string;
  primaryColor?: string;
}

interface LocalMessage {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  pending?: boolean;
  time?: string;
}

function getTime() {
  return new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}

export function ChatInterface({ chatbotId, welcomeMessage, primaryColor }: ChatInterfaceProps) {
  const { theme, isDark } = useTheme();
  const accentColor = primaryColor ?? COLORS.primary;
  const flatRef = useRef<FlatList>(null);

  const [messages, setMessages] = useState<LocalMessage[]>(() =>
    welcomeMessage
      ? [{ id: 'welcome', role: 'assistant', content: welcomeMessage, time: getTime() }]
      : [],
  );
  const [input, setInput] = useState('');
  const [sending, setSending] = useState(false);
  const [sessionId, setSessionId] = useState<string | undefined>();

  const scrollToBottom = useCallback(() => {
    setTimeout(() => flatRef.current?.scrollToEnd({ animated: true }), 80);
  }, []);

  const sendMessage = async () => {
    const text = input.trim();
    if (!text || sending) return;

    const userMsg: LocalMessage = { id: Date.now().toString(), role: 'user', content: text, time: getTime() };
    const loadingMsg: LocalMessage = { id: 'loading', role: 'assistant', content: '', pending: true };

    setMessages(prev => [...prev, userMsg, loadingMsg]);
    setInput('');
    setSending(true);
    scrollToBottom();

    try {
      const data = await chatAPI.sendMessage(chatbotId, text, sessionId);
      if (!sessionId) setSessionId(data.session_id);
      setMessages(prev => [
        ...prev.filter(m => m.id !== 'loading'),
        { id: (Date.now() + 1).toString(), role: 'assistant', content: data.response, time: getTime() },
      ]);
    } catch {
      setMessages(prev => [
        ...prev.filter(m => m.id !== 'loading'),
        { id: (Date.now() + 1).toString(), role: 'assistant', content: "Sorry, I couldn't process your message. Please try again.", time: getTime() },
      ]);
    } finally {
      setSending(false);
      scrollToBottom();
    }
  };

  const renderMessage = ({ item }: { item: LocalMessage }) => {
    const isUser = item.role === 'user';
    return (
      <MessageBubble
        message={item}
        isUser={isUser}
        accentColor={accentColor}
        theme={theme}
        isDark={isDark}
      />
    );
  };

  return (
    <KeyboardAvoidingView
      style={[styles.container, { backgroundColor: theme.bg }]}
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      keyboardVerticalOffset={Platform.OS === 'ios' ? 90 : 0}>

      <FlatList
        ref={flatRef}
        data={messages}
        keyExtractor={item => item.id}
        renderItem={renderMessage}
        contentContainerStyle={styles.messageList}
        showsVerticalScrollIndicator={false}
        onContentSizeChange={scrollToBottom}
      />

      {/* Input bar */}
      <View style={[styles.inputBar, { backgroundColor: theme.surface, borderTopColor: theme.border }]}>
        <View style={[styles.inputWrapper, { backgroundColor: theme.bg, borderColor: theme.border }]}>
          <TextInput
            style={[styles.textInput, { color: theme.text }]}
            value={input}
            onChangeText={setInput}
            placeholder="Message..."
            placeholderTextColor={theme.placeholder}
            multiline
            maxLength={2000}
            onSubmitEditing={sendMessage}
            blurOnSubmit={false}
          />
        </View>
        <TouchableOpacity
          style={[
            styles.sendBtn,
            { backgroundColor: accentColor },
            (sending || !input.trim()) && styles.sendBtnDisabled,
            SHADOWS.primary,
          ]}
          onPress={sendMessage}
          disabled={sending || !input.trim()}>
          <Text style={styles.sendIcon}>↑</Text>
        </TouchableOpacity>
      </View>
    </KeyboardAvoidingView>
  );
}

function MessageBubble({
  message,
  isUser,
  accentColor,
  theme,
  isDark,
}: {
  message: LocalMessage;
  isUser: boolean;
  accentColor: string;
  theme: any;
  isDark: boolean;
}) {
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const slideAnim = useRef(new Animated.Value(8)).current;

  React.useEffect(() => {
    Animated.parallel([
      Animated.timing(fadeAnim, { toValue: 1, duration: 250, useNativeDriver: true }),
      Animated.spring(slideAnim, { toValue: 0, useNativeDriver: true, speed: 20, bounciness: 2 }),
    ]).start();
  }, []);

  return (
    <Animated.View
      style={[
        styles.msgRow,
        isUser && styles.msgRowUser,
        { opacity: fadeAnim, transform: [{ translateY: slideAnim }] },
      ]}>
      {!isUser && (
        <View style={[styles.avatar, { backgroundColor: accentColor }]}>
          <Text style={styles.avatarText}>AI</Text>
        </View>
      )}

      <View style={styles.bubbleWrapper}>
        <View
          style={[
            styles.bubble,
            isUser
              ? [styles.bubbleUser, { backgroundColor: accentColor }]
              : [styles.bubbleBot, { backgroundColor: theme.surface, borderColor: theme.border }],
          ]}>
          {message.pending ? (
            <TypingIndicator />
          ) : (
            <Text style={[styles.bubbleText, { color: isUser ? COLORS.white : theme.text }]}>
              {message.content}
            </Text>
          )}
        </View>
        {message.time && !message.pending ? (
          <Text style={[styles.timestamp, { color: theme.textMuted, alignSelf: isUser ? 'flex-end' : 'flex-start' }]}>
            {message.time}
          </Text>
        ) : null}
      </View>
    </Animated.View>
  );
}

function TypingIndicator() {
  const dot1 = useRef(new Animated.Value(0.3)).current;
  const dot2 = useRef(new Animated.Value(0.3)).current;
  const dot3 = useRef(new Animated.Value(0.3)).current;

  React.useEffect(() => {
    const pulse = (dot: Animated.Value, delay: number) =>
      Animated.loop(
        Animated.sequence([
          Animated.delay(delay),
          Animated.timing(dot, { toValue: 1, duration: 300, useNativeDriver: true }),
          Animated.timing(dot, { toValue: 0.3, duration: 300, useNativeDriver: true }),
          Animated.delay(600 - delay),
        ]),
      );

    const a1 = pulse(dot1, 0);
    const a2 = pulse(dot2, 200);
    const a3 = pulse(dot3, 400);
    a1.start(); a2.start(); a3.start();
    return () => { a1.stop(); a2.stop(); a3.stop(); };
  }, []);

  return (
    <View style={typingStyles.row}>
      {[dot1, dot2, dot3].map((dot, i) => (
        <Animated.View key={i} style={[typingStyles.dot, { opacity: dot }]} />
      ))}
    </View>
  );
}

const typingStyles = StyleSheet.create({
  row: { flexDirection: 'row', gap: 5, paddingVertical: 4, paddingHorizontal: 2 },
  dot: { width: 8, height: 8, borderRadius: 4, backgroundColor: COLORS.primary },
});

const styles = StyleSheet.create({
  container: { flex: 1 },
  messageList: {
    paddingHorizontal: SPACING.md,
    paddingVertical: SPACING.lg,
    gap: SPACING.md,
    paddingBottom: SPACING.xl,
  },

  msgRow: { flexDirection: 'row', gap: SPACING.sm, alignItems: 'flex-end', maxWidth: '100%' },
  msgRowUser: { flexDirection: 'row-reverse' },

  avatar: {
    width: 32,
    height: 32,
    borderRadius: RADIUS.full,
    alignItems: 'center',
    justifyContent: 'center',
    flexShrink: 0,
  },
  avatarText: { color: COLORS.white, fontSize: 10, fontWeight: '800' },

  bubbleWrapper: { flex: 1, gap: 4 },
  bubble: { maxWidth: '80%', borderRadius: RADIUS.xl, padding: SPACING.md },
  bubbleUser: { alignSelf: 'flex-end', borderBottomRightRadius: RADIUS.xs },
  bubbleBot: {
    alignSelf: 'flex-start',
    borderWidth: 1,
    borderBottomLeftRadius: RADIUS.xs,
  },
  bubbleText: { fontSize: FONT_SIZE.md, lineHeight: 22 },
  timestamp: { fontSize: 10, paddingHorizontal: 2 },

  inputBar: {
    flexDirection: 'row',
    alignItems: 'flex-end',
    paddingHorizontal: SPACING.md,
    paddingVertical: SPACING.md,
    borderTopWidth: 1,
    gap: SPACING.sm,
  },
  inputWrapper: {
    flex: 1,
    borderRadius: RADIUS.xl,
    borderWidth: 1.5,
    paddingHorizontal: SPACING.md,
    paddingVertical: Platform.OS === 'ios' ? SPACING.sm : 0,
    maxHeight: 120,
  },
  textInput: {
    fontSize: FONT_SIZE.md,
    minHeight: 40,
    paddingTop: Platform.OS === 'android' ? SPACING.sm : 0,
  },
  sendBtn: {
    width: 46,
    height: 46,
    borderRadius: RADIUS.full,
    alignItems: 'center',
    justifyContent: 'center',
    flexShrink: 0,
  },
  sendBtnDisabled: { opacity: 0.45 },
  sendIcon: { color: COLORS.white, fontSize: 20, fontWeight: '700', marginTop: -2 },
});
