/**
 * 应用日志中心（我的 -> 数据 -> 应用日志）。
 *
 * 功能：
 * 1. 实时内存日志 + 磁盘历史日志文件查看
 * 2. 4 级日志（DEBUG/INFO/WARN/ERROR）与关键词/Tag 搜索过滤
 * 3. 展开查看结构化 JSON data 载荷与 Stack Trace
 * 4. 一键导出日志（调用原生分享/文件导出）与清空日志
 */

import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
  Alert,
  AppState,
  FlatList,
  Modal,
  Pressable,
  ScrollView,
  Share,
  StyleSheet,
  Text,
  TextInput,
  View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import * as FileSystem from 'expo-file-system/legacy';
import * as Sharing from 'expo-sharing';

import { ScreenHeader } from '../../components/layout/ScreenHeader';
import { useT } from '../../i18n';
import { useTheme } from '../../theme';
import { LogEntry, LogFileInfo, LogLevel, LEVEL_LABELS, logger } from '../../utils/logger';

export default function LogsScreen() {
  const { theme } = useTheme();
  const t = useT();

  const [selectedFileDate, setSelectedFileDate] = useState<string | null>(null); // null 表示“今天(实时)”
  const [logFiles, setLogFiles] = useState<LogFileInfo[]>([]);
  const [fileLogs, setFileLogs] = useState<LogEntry[]>([]);
  const [liveLogs, setLiveLogs] = useState<LogEntry[]>([]);
  const [levelFilter, setLevelFilter] = useState<LogLevel | 'ALL'>('ALL');
  const [dateModalOpen, setDateModalOpen] = useState(false);

  const selectedFile = useMemo(() => {
    return logFiles.find(f => f.date === selectedFileDate);
  }, [logFiles, selectedFileDate]);
  const [searchQuery, setSearchQuery] = useState<string>('');
  const [expandedIndex, setExpandedIndex] = useState<number | null>(null);

  // 刷新日志文件列表
  const refreshFileList = useCallback(async () => {
    const files = await logger.getLogFiles();
    setLogFiles(files);
  }, []);

  // 刷新实时内存日志与历史日志
  const refreshLogs = useCallback(async () => {
    // 强制刷新日志写入队列
    await logger.flushQueue();
    await refreshFileList();

    if (selectedFileDate === null) {
      const todayLogs = await logger.getTodayLogs();
      setLiveLogs(todayLogs);
    } else {
      const loaded = await logger.loadLogsFromFile(selectedFileDate);
      setFileLogs(loaded);
    }
  }, [selectedFileDate, refreshFileList]);

  useEffect(() => {
    void refreshLogs();
  }, [refreshLogs]);

  // 自动刷新：「今天(实时)」视图每 3 秒轮询；切回前台时立即刷新
  const refreshRef = useRef(refreshLogs);
  refreshRef.current = refreshLogs;
  useEffect(() => {
    if (selectedFileDate !== null) return; // 历史文件不轮询
    const timer = setInterval(() => { void refreshRef.current(); }, 3000);
    const sub = AppState.addEventListener('change', (state) => {
      if (state === 'active') void refreshRef.current();
    });
    return () => { clearInterval(timer); sub.remove(); };
  }, [selectedFileDate]);

  // 当前激活显示的原始日志列表
  const rawLogs = selectedFileDate === null ? liveLogs : fileLogs;

  // 过滤后的日志列表（按时间倒序排列：最新的日志在前面）
  const filteredLogs = useMemo(() => {
    const list = rawLogs.filter(e => {
      // 级别过滤
      if (levelFilter !== 'ALL' && e.level !== levelFilter) {
        return false;
      }
      // 搜索过滤
      if (searchQuery.trim()) {
        const q = searchQuery.trim().toLowerCase();
        const msgMatch = e.message.toLowerCase().includes(q);
        const tagMatch = e.tag.toLowerCase().includes(q);
        const dataMatch = e.data ? JSON.stringify(e.data).toLowerCase().includes(q) : false;
        if (!msgMatch && !tagMatch && !dataMatch) {
          return false;
        }
      }
      return true;
    });
    // 倒序排列（最新在前）
    return list.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
  }, [rawLogs, levelFilter, searchQuery]);

  // 统计各级别数量
  const counts = useMemo(() => {
    const res = { ALL: rawLogs.length, [LogLevel.DEBUG]: 0, [LogLevel.INFO]: 0, [LogLevel.WARN]: 0, [LogLevel.ERROR]: 0 };
    for (const item of rawLogs) {
      if (res[item.level] !== undefined) {
        res[item.level]++;
      }
    }
    return res;
  }, [rawLogs]);

  // 导出日志文件/文本
  const handleExport = async () => {
    try {
      const exportText = logger.exportAsFormattedText(filteredLogs);
      if (!exportText || filteredLogs.length === 0) {
        Alert.alert(t('common.error'), t('logs.empty'));
        return;
      }

      if (await Sharing.isAvailableAsync()) {
        const fileDateStr = selectedFileDate ?? new Date().toISOString().slice(0, 10);
        const tempPath = `${FileSystem.cacheDirectory}app-log-${fileDateStr}-${Date.now()}.txt`;
        await FileSystem.writeAsStringAsync(tempPath, exportText);
        await Sharing.shareAsync(tempPath, {
          mimeType: 'text/plain',
          dialogTitle: t('logs.export'),
        });
      } else {
        await Share.share({
          message: exportText,
          title: t('logs.title'),
        });
      }
    } catch (e) {
      Alert.alert(t('error.exportFail'), e instanceof Error ? e.message : String(e));
    }
  };

  // 清空所有日志
  const handleClear = () => {
    Alert.alert(
      t('logs.clearConfirmTitle'),
      t('logs.clearConfirmDesc'),
      [
        { text: t('common.cancel'), style: 'cancel' },
        {
          text: t('logs.clear'),
          style: 'destructive',
          onPress: async () => {
            await logger.clearAllLogs();
            setSelectedFileDate(null);
            await refreshLogs();
            Alert.alert(t('common.confirm'), t('logs.clearSuccess'));
          },
        },
      ],
    );
  };

  // 获取级别对应的色彩
  const getLevelStyle = (level: LogLevel) => {
    switch (level) {
      case LogLevel.DEBUG:
        return { bg: theme.colors.bgTertiary, fg: theme.colors.fgSecondary };
      case LogLevel.INFO:
        return { bg: theme.colors.accent + '22', fg: theme.colors.accent };
      case LogLevel.WARN:
        return { bg: '#E6A23C22', fg: '#E6A23C' };
      case LogLevel.ERROR:
        return { bg: theme.colors.error + '22', fg: theme.colors.error };
    }
  };

  // 格式化时间戳 (HH:mm:ss.SSS)
  const formatTime = (isoString: string) => {
    try {
      const d = new Date(isoString);
      const h = String(d.getHours()).padStart(2, '0');
      const m = String(d.getMinutes()).padStart(2, '0');
      const s = String(d.getSeconds()).padStart(2, '0');
      const ms = String(d.getMilliseconds()).padStart(3, '0');
      return `${h}:${m}:${s}.${ms}`;
    } catch {
      return isoString.slice(11, 23);
    }
  };

  const renderHeaderRight = (
    <View style={styles.headerRight}>
      <Pressable onPress={handleExport} hitSlop={8} style={({ pressed }) => [{ opacity: pressed ? 0.6 : 1 }]}>
        <Ionicons name="share-outline" size={22} color={theme.colors.accent} />
      </Pressable>
      <Pressable onPress={handleClear} hitSlop={8} style={({ pressed }) => [{ opacity: pressed ? 0.6 : 1 }]}>
        <Ionicons name="trash-outline" size={22} color={theme.colors.error} />
      </Pressable>
    </View>
  );

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

      {/* 日志日期 Dropdown 触发按钮 */}
      <View style={[styles.fileSelectorBar, { borderBottomColor: theme.colors.divider }]}>
        <Pressable
          onPress={() => setDateModalOpen(true)}
          style={[
            styles.dropdownTriggerBtn,
            {
              backgroundColor: theme.colors.bgSecondary,
              borderColor: theme.colors.border,
            },
          ]}
        >
          <Ionicons name="calendar-outline" size={16} color={theme.colors.accent} />
          <Text style={[theme.typography.bodySmall, { color: theme.colors.fgPrimary, fontWeight: '600', flex: 1, marginLeft: 8 }]}>
            {selectedFileDate === null
              ? t('logs.todayLive')
              : `${selectedFileDate} (${Math.round((selectedFile?.size ?? 0) / 1024)}KB)`}
          </Text>
          <Ionicons name="chevron-down" size={16} color={theme.colors.fgSecondary} />
        </Pressable>
      </View>

      {/* 日志日期 Dropdown 弹出菜单 Modal */}
      <Modal
        visible={dateModalOpen}
        transparent
        animationType="fade"
        onRequestClose={() => setDateModalOpen(false)}
      >
        <Pressable
          style={[styles.modalOverlay, { backgroundColor: theme.colors.overlay }]}
          onPress={() => setDateModalOpen(false)}
        >
          <Pressable
            style={[
              styles.dropdownMenu,
              theme.shadows.lg,
              {
                backgroundColor: theme.colors.bgSecondary,
                borderColor: theme.colors.border,
              },
            ]}
            onPress={e => e.stopPropagation()}
          >
            <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary, marginBottom: 8, fontWeight: '600' }]}>
              选择日志日期
            </Text>
            <ScrollView style={{ maxHeight: 300 }}>
              {/* 今天（实时） */}
              <Pressable
                onPress={() => {
                  setSelectedFileDate(null);
                  setDateModalOpen(false);
                }}
                style={[
                  styles.menuItem,
                  {
                    backgroundColor: selectedFileDate === null ? `${theme.colors.accent}15` : theme.colors.bgPrimary,
                    borderColor: selectedFileDate === null ? theme.colors.accent : theme.colors.border,
                  },
                ]}
              >
                <Text style={[theme.typography.bodySmall, { color: selectedFileDate === null ? theme.colors.accent : theme.colors.fgPrimary, fontWeight: '600' }]}>
                  {t('logs.todayLive')}
                </Text>
                {selectedFileDate === null && (
                  <Ionicons name="checkmark-circle" size={16} color={theme.colors.accent} />
                )}
              </Pressable>

              {/* 历史日志文件 */}
              {logFiles.map(file => {
                const isSelected = selectedFileDate === file.date;
                return (
                  <Pressable
                    key={file.name}
                    onPress={() => {
                      setSelectedFileDate(file.date);
                      setDateModalOpen(false);
                    }}
                    style={[
                      styles.menuItem,
                      {
                        backgroundColor: isSelected ? `${theme.colors.accent}15` : theme.colors.bgPrimary,
                        borderColor: isSelected ? theme.colors.accent : theme.colors.border,
                      },
                    ]}
                  >
                    <Text style={[theme.typography.bodySmall, { color: isSelected ? theme.colors.accent : theme.colors.fgPrimary, fontWeight: '600' }]}>
                      {file.date} ({Math.round(file.size / 1024)}KB)
                    </Text>
                    {isSelected && (
                      <Ionicons name="checkmark-circle" size={16} color={theme.colors.accent} />
                    )}
                  </Pressable>
                );
              })}
            </ScrollView>
          </Pressable>
        </Pressable>
      </Modal>

      {/* 搜索框 */}
      <View style={styles.searchContainer}>
        <View style={[styles.searchBox, { backgroundColor: theme.colors.bgSecondary, borderColor: theme.colors.border }]}>
          <Ionicons name="search-outline" size={16} color={theme.colors.fgSecondary} />
          <TextInput
            style={[theme.typography.bodySmall, styles.searchInput, { color: theme.colors.fgPrimary }]}
            placeholder={t('logs.searchPlaceholder')}
            placeholderTextColor={theme.colors.fgSecondary}
            value={searchQuery}
            onChangeText={setSearchQuery}
          />
          {searchQuery ? (
            <Pressable onPress={() => setSearchQuery('')} hitSlop={6}>
              <Ionicons name="close-circle" size={18} color={theme.colors.fgSecondary} />
            </Pressable>
          ) : null}
        </View>
      </View>

      {/* 级别 Chip 筛选 */}
      <View style={styles.levelFilterRow}>
        {(['ALL', LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR] as const).map(lvl => {
          const isSelected = levelFilter === lvl;
          const label = lvl === 'ALL' ? t('logs.filterLevelAll', { count: counts.ALL }) : `${LEVEL_LABELS[lvl]} (${counts[lvl]})`;
          return (
            <Pressable
              key={String(lvl)}
              onPress={() => setLevelFilter(lvl)}
              style={[
                styles.levelChip,
                {
                  backgroundColor: isSelected ? theme.colors.accent : theme.colors.bgTertiary,
                },
              ]}
            >
              <Text
                style={[
                  theme.typography.caption,
                  { color: isSelected ? theme.colors.fgInverse : theme.colors.fgSecondary, fontWeight: isSelected ? '700' : '400' },
                ]}
              >
                {label}
              </Text>
            </Pressable>
          );
        })}
      </View>

      {/* 日志列表 */}
      <FlatList
        data={filteredLogs}
        keyExtractor={(_, index) => String(index)}
        contentContainerStyle={[styles.listContent, { gap: theme.spacing.md }]}
        ListEmptyComponent={
          <View style={styles.emptyContainer}>
            <Ionicons name="document-text-outline" size={48} color={theme.colors.fgSecondary} />
            <Text style={[theme.typography.body, { color: theme.colors.fgSecondary, marginTop: 12 }]}>
              {t('logs.empty')}
            </Text>
          </View>
        }
        renderItem={({ item, index }) => {
          const style = getLevelStyle(item.level);
          const isExpanded = expandedIndex === index;
          const hasData = item.data !== undefined && item.data !== null;

          return (
            <Pressable
              onPress={() => setExpandedIndex(isExpanded ? null : index)}
              style={[
                styles.logCard,
                {
                  backgroundColor: theme.colors.bgSecondary,
                  borderColor: theme.colors.border,
                },
              ]}
            >
              <View style={styles.cardHeader}>
                <View style={[styles.levelBadge, { backgroundColor: style.bg }]}>
                  <Text style={[theme.typography.caption, { color: style.fg, fontWeight: '700', fontSize: 10 }]}>
                    {LEVEL_LABELS[item.level]}
                  </Text>
                </View>
                <Text style={[theme.typography.caption, styles.tagText, { color: theme.colors.accent }]}>
                  [{item.tag}]
                </Text>
                <Text style={[theme.typography.caption, styles.timeText, { color: theme.colors.fgSecondary }]}>
                  {formatTime(item.timestamp)}
                </Text>
              </View>

              <Text style={[theme.typography.bodySmall, { color: theme.colors.fgPrimary, marginTop: 6, lineHeight: 18 }]}>
                {item.message}
              </Text>

              {hasData && (
                <View style={styles.dataFooter}>
                  <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary }]}>
                    {isExpanded ? t('logs.collapseData') : t('logs.expandData')}
                  </Text>
                  <Ionicons name={isExpanded ? 'chevron-up' : 'chevron-down'} size={14} color={theme.colors.fgSecondary} />
                </View>
              )}

              {isExpanded && hasData && (
                <View style={[styles.dataBox, { backgroundColor: theme.colors.bgTertiary, borderColor: theme.colors.border }]}>
                  <Text style={[theme.typography.caption, { color: theme.colors.fgPrimary, fontFamily: 'monospace' }]}>
                    {typeof item.data === 'object' ? JSON.stringify(item.data, null, 2) : String(item.data)}
                  </Text>
                </View>
              )}
            </Pressable>
          );
        }}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  page: { flex: 1 },
  headerRight: { flexDirection: 'row', alignItems: 'center', gap: 16, marginRight: 8 },
  fileSelectorBar: { paddingHorizontal: 16, paddingVertical: 8, borderBottomWidth: 1 },
  dropdownTriggerBtn: { flexDirection: 'row', alignItems: 'center', borderRadius: 8, borderWidth: 1, paddingHorizontal: 12, minHeight: 38 },
  modalOverlay: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
  dropdownMenu: { width: '100%', maxWidth: 360, borderRadius: 16, borderWidth: 1, padding: 16 },
  menuItem: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 12, paddingVertical: 10, borderRadius: 8, borderWidth: 1, marginBottom: 6 },
  searchContainer: { paddingHorizontal: 16, paddingTop: 10 },
  searchBox: { flexDirection: 'row', alignItems: 'center', borderRadius: 8, borderWidth: 1, paddingHorizontal: 10, minHeight: 36, gap: 8 },
  searchInput: { flex: 1, paddingVertical: 0 },
  levelFilterRow: { flexDirection: 'row', paddingHorizontal: 16, paddingVertical: 10, gap: 6, flexWrap: 'wrap' },
  levelChip: { paddingHorizontal: 8, paddingVertical: 4, borderRadius: 12 },
  listContent: { padding: 16, paddingBottom: 40 },
  logCard: { borderRadius: 8, borderWidth: 1, padding: 12 },
  cardHeader: { flexDirection: 'row', alignItems: 'center', gap: 8 },
  levelBadge: { paddingHorizontal: 6, paddingVertical: 2, borderRadius: 4 },
  tagText: { fontWeight: '600' },
  timeText: { marginLeft: 'auto' },
  dataFooter: { flexDirection: 'row', alignItems: 'center', marginTop: 8, gap: 4 },
  dataBox: { marginTop: 8, padding: 8, borderRadius: 6, borderWidth: 1 },
  emptyContainer: { alignItems: 'center', justifyContent: 'center', paddingTop: 60 },
});
