/**
 * AI 聊天助手（plan.md「8.1 AI 聊天助手」）。
 *
 * 功能：
 * - 自然语言记账（"昨天星巴克花了35" → 生成账单卡片）
 * - 自由聊天（AI 回复）
 * - 账单卡片点击跳转 new.tsx 预填
 *
 * 使用 chatAssistant.processChatMessage + BaseOpenAIProvider（OpenAI 兼容协议）。
 * AI 未配置时降级为提示用户去设置。
 */
import React, { useState, useCallback, useRef } from 'react';
import { FlatList, KeyboardAvoidingView, Platform, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import { useTheme } from '../../theme';
import { useT } from '../../i18n';
import { useSettingsStore } from '../../store/settingsStore';
import { useNumpadUiStore } from '../../store/numpadUiStore';
import { BaseOpenAIProvider, type AiProviderConfig, type AiProvider, type ChatMessage as AiChatMessage } from '../../domain/ai';
import { processChatMessage, createConversation, appendMessage, type ChatConversation, type ChatResponse } from '../../ai/chatAssistant';
import { ScreenHeader } from '../../components/ScreenHeader';

interface UiMessage {
  role: 'user' | 'assistant';
  content: string;
  billCards?: ChatResponse['billCards'];
}

/** 构造 AiProvider（从 settingsStore）。 */
function buildProvider(get: ReturnType<typeof useSettingsStore.getState>): AiProvider | null {
  if (!get.aiEnabled || !get.aiApiKey) return null;
  const config: AiProviderConfig = {
    id: get.aiProviderId,
    name: get.aiProviderId,
    apiKey: get.aiApiKey,
    baseUrl: get.aiBaseUrl || 'https://api.openai.com/v1',
    model: get.aiModel || 'gpt-4o-mini',
  };
  // BaseOpenAIProvider 是 abstract 但 chat 方法已实现，创建匿名子类
  return new (class extends BaseOpenAIProvider {})(config);
}

export default function AIChatScreen() {
  const { theme } = useTheme();
  const t = useT();
  const router = useRouter();
  const aiEnabled = useSettingsStore(s => s.aiEnabled);
  const aiApiKey = useSettingsStore(s => s.aiApiKey);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const [messages, setMessages] = useState<UiMessage[]>([
    { role: 'assistant', content: t('ai.welcome') },
  ]);
  const conversationRef = useRef<ChatConversation>(createConversation());
  const listRef = useRef<FlatList<UiMessage>>(null);

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

    // 添加用户消息
    const userMsg: UiMessage = { role: 'user', content: text };
    setMessages(prev => [...prev, userMsg]);
    setInput('');
    setLoading(true);

    try {
      const provider = buildProvider(useSettingsStore.getState());
      if (!provider) {
        setMessages(prev => [...prev, { role: 'assistant', content: t('ai.notConfigured') }]);
        return;
      }

      const response = await processChatMessage(text, provider, conversationRef.current);
      conversationRef.current = appendMessage(conversationRef.current, { role: 'user', content: text });

      if (response.type === 'bill_card' && response.billCards && response.billCards.length > 0) {
        const assistantMsg: UiMessage = {
          role: 'assistant',
          content: t('ai.billDetected'),
          billCards: response.billCards,
        };
        setMessages(prev => [...prev, assistantMsg]);
        conversationRef.current = appendMessage(conversationRef.current, { role: 'assistant', content: response.text || '' });
      } else if (response.type === 'text' && response.text) {
        setMessages(prev => [...prev, { role: 'assistant', content: response.text! }]);
        conversationRef.current = appendMessage(conversationRef.current, { role: 'assistant', content: response.text });
      } else if (response.type === 'error') {
        setMessages(prev => [...prev, { role: 'assistant', content: response.error || t('ai.error') }]);
      } else {
        setMessages(prev => [...prev, { role: 'assistant', content: response.text || t('ai.error') }]);
      }
    } catch (e) {
      setMessages(prev => [...prev, { role: 'assistant', content: `${t('ai.error')}: ${e instanceof Error ? e.message : String(e)}` }]);
    } finally {
      setLoading(false);
      setTimeout(() => listRef.current?.scrollToEnd(), 100);
    }
  }, [input, loading, t]);

  const renderMessage = ({ item }: { item: UiMessage }) => {
    const isUser = item.role === 'user';
    return (
      <View style={[styles.msgRow, { justifyContent: isUser ? 'flex-end' : 'flex-start' }]}>
        <View style={[
          styles.bubble,
          {
            backgroundColor: isUser ? theme.colors.accent : theme.colors.bgTertiary,
            borderColor: theme.colors.border,
          },
        ]}>
          <Text style={{ color: isUser ? theme.colors.fgInverse : theme.colors.fgPrimary, fontSize: 15, lineHeight: 20 }}>
            {item.content}
          </Text>
          {/* 账单卡片 */}
          {item.billCards && item.billCards.map((card, i) => {
            // 方向符号 + 金额上色，与全局方向色约定一致（TransactionCard：income 绿 / expense 红 / transfer 蓝）
            const dirColor = card.type === 'income' ? theme.colors.financial.income
              : card.type === 'transfer' ? theme.colors.financial.transfer
              : theme.colors.financial.expense;
            const dirSign = card.type === 'income' ? '＋' : card.type === 'transfer' ? '⇄' : '－';
            return (
            <Pressable
              key={i}
              onPress={() => useNumpadUiStore.getState().open({ autoOcr: true })}
              style={[styles.billCard, { backgroundColor: theme.colors.bgPrimary, borderColor: theme.colors.accent }]}
            >
              <Text style={[theme.typography.bodySmall, { color: dirColor, fontWeight: '700' }]}>
                {dirSign} {card.amount} {card.currency}
              </Text>
              <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary }]}>
                {card.counterparty} · {card.narration}
              </Text>
              <View style={{ flexDirection: 'row', alignItems: 'center', gap: 4, marginTop: 4 }}>
                <Text style={[theme.typography.caption, { color: theme.colors.accent }]}>
                  {t('ai.tapToRecord')}
                </Text>
                <Ionicons name="arrow-forward" size={12} color={theme.colors.accent} />
              </View>
            </Pressable>
            );
          })}
        </View>
      </View>
    );
  };

  return (
    <SafeAreaView style={[styles.page, { backgroundColor: theme.colors.bgPrimary }]} edges={['top']}>
      <ScreenHeader title={t('ai.chatTitle')} />

      <FlatList
        ref={listRef}
        data={messages}
        keyExtractor={(item, index) => `${index}`}
        renderItem={renderMessage}
        contentContainerStyle={{ padding: 16, gap: 8 }}
        onContentSizeChange={() => listRef.current?.scrollToEnd()}
      />

      {loading && (
        <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary, textAlign: 'center', paddingBottom: 4 }]}>
          {t('ai.thinking')}
        </Text>
      )}

      <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : undefined}>
        <View style={[styles.inputRow, { backgroundColor: theme.colors.bgSecondary, borderTopColor: theme.colors.border }]}>
          <TextInput
            value={input}
            onChangeText={setInput}
            placeholder={t('ai.inputPlaceholder')}
            placeholderTextColor={theme.colors.fgSecondary}
            style={[styles.input, { color: theme.colors.fgPrimary }]}
            multiline
          />
          <Pressable
            onPress={sendMessage}
            disabled={!input.trim() || loading}
            style={({ pressed }) => [
              styles.sendBtn,
              { backgroundColor: theme.colors.accent, opacity: (!input.trim() || loading) ? 0.4 : pressed ? 0.7 : 1 },
            ]}
          >
            <Ionicons name="send" size={18} color={theme.colors.fgInverse} />
          </Pressable>
        </View>
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  page: { flex: 1 },
  msgRow: { flexDirection: 'row', maxWidth: '100%' },
  bubble: { maxWidth: '85%', borderRadius: 12, padding: 12, borderWidth: 1 },
  billCard: { marginTop: 8, padding: 10, borderRadius: 8, borderWidth: 1 },
  inputRow: { flexDirection: 'row', alignItems: 'flex-end', paddingHorizontal: 12, paddingVertical: 8, borderTopWidth: 1, gap: 8 },
  input: { flex: 1, maxHeight: 100, fontSize: 15, paddingVertical: 8 },
  sendBtn: { width: 36, height: 36, borderRadius: 18, alignItems: 'center', justifyContent: 'center' },
});
