/**
 * 数据与存储设置页 DataStorageScreen（响应式适配）
 * 威友 - 缓存管理、存储统计
 */

import React, { useState, useEffect, useCallback, useMemo } from 'react';
import {
  View,
  StyleSheet,
  TouchableOpacity,
  Alert,
  ScrollView,
  ActivityIndicator,
  Platform,
} from 'react-native';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Image } from 'expo-image';
import { Directory, File, Paths } from 'expo-file-system';
import { spacing, borderRadius, fontSizes, useAppColors, type AppColors } from '../../theme';
import { Text } from '../../components/common';
import { useResponsive, useResponsiveSpacing } from '../../hooks';
import { mediaCacheManager } from '../../infrastructure/cache';
import type { CacheStats } from '../../infrastructure/cache';

const CONTENT_MAX_WIDTH = 720;

function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

interface StorageStatItem {
  icon: string;
  label: string;
  value: string;
  count?: number;
}

export const DataStorageScreen: React.FC = () => {
  const colors = useAppColors();
  const styles = useMemo(() => createDataStorageStyles(colors), [colors]);
  const { isMobile } = useResponsive();
  const insets = useSafeAreaInsets();
  const responsivePadding = useResponsiveSpacing({ xs: 8, sm: 12, md: 16, lg: 24, xl: 32 });

  const [cacheStats, setCacheStats] = useState<CacheStats | null>(null);
  const [asyncStorageSize, setAsyncStorageSize] = useState(0);
  const [expoImageCacheSize, setExpoImageCacheSize] = useState(0);
  const [loading, setLoading] = useState(true);
  const [clearing, setClearing] = useState(false);

  const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.md;

  const loadExpoImageCacheSize = useCallback(async (): Promise<number> => {
    if (Platform.OS === 'web') return 0;
    try {
      const cacheDir = Paths.cache;
      const sdImageCacheDir = new Directory(cacheDir, 'defaultDiskCache');
      const expoImageCacheDir = new Directory(cacheDir, 'expo-image');

      const scanDirectorySize = async (dir: Directory): Promise<number> => {
        let size = 0;
        try {
          if (!(await dir.exists)) return 0;
          const items = dir.list();
          for (const item of items) {
            try {
              if (item instanceof File) {
                const info = await item.info();
                if (info.exists && info.size) {
                  size += info.size;
                }
              } else if (item instanceof Directory) {
                size += await scanDirectorySize(item);
              }
            } catch {}
          }
        } catch {}
        return size;
      };

      const totalSize = await scanDirectorySize(sdImageCacheDir) + await scanDirectorySize(expoImageCacheDir);
      return totalSize;
    } catch (error) {
      console.warn('读取 expo-image 缓存大小失败:', error);
      return 0;
    }
  }, []);

  const loadStats = useCallback(async () => {
    try {
      setLoading(true);
      await mediaCacheManager.initialize();
      const stats = mediaCacheManager.getCacheStats();
      setCacheStats(stats);

      const imageCacheSize = await loadExpoImageCacheSize();
      setExpoImageCacheSize(imageCacheSize);

      const keys = await AsyncStorage.getAllKeys();
      if (keys.length > 0) {
        const items = await AsyncStorage.multiGet(keys);
        let totalSize = 0;
        for (const [, value] of items) {
          if (value) {
            totalSize += value.length * 2;
          }
        }
        setAsyncStorageSize(totalSize);
      } else {
        setAsyncStorageSize(0);
      }
    } catch (error) {
      console.error('加载存储统计失败:', error);
    } finally {
      setLoading(false);
    }
  }, [loadExpoImageCacheSize]);

  useEffect(() => {
    loadStats();
  }, [loadStats]);

  const handleClearCache = () => {
    Alert.alert(
      '清除缓存',
      '确定要清除所有缓存吗？此操作不可撤销。',
      [
        { text: '取消', style: 'cancel' },
        {
          text: '清除',
          style: 'destructive',
          onPress: async () => {
            try {
              setClearing(true);
              await mediaCacheManager.clearAll();
              await Image.clearDiskCache();
              await Image.clearMemoryCache();
              await loadStats();
              Alert.alert('完成', '缓存已清除');
            } catch (error) {
              console.error('清除缓存失败:', error);
              Alert.alert('错误', '清除缓存失败，请稍后重试');
            } finally {
              setClearing(false);
            }
          },
        },
      ]
    );
  };

  const handleCleanupExpired = () => {
    Alert.alert(
      '清理过期缓存',
      '将清理超过 7 天未访问的缓存文件。',
      [
        { text: '取消', style: 'cancel' },
        {
          text: '清理',
          onPress: async () => {
            try {
              setClearing(true);
              const result = await mediaCacheManager.cleanupExpired();
              await loadStats();
              Alert.alert(
                '清理完成',
                `已清理 ${result.deletedCount} 个文件，释放 ${formatBytes(result.freedSize)} 空间`
              );
            } catch (error) {
              console.error('清理过期缓存失败:', error);
              Alert.alert('错误', '清理失败，请稍后重试');
            } finally {
              setClearing(false);
            }
          },
        },
      ]
    );
  };

  const totalSize = (cacheStats?.totalSize ?? 0) + asyncStorageSize + expoImageCacheSize;

  const storageItems: StorageStatItem[] = useMemo(() => {
    return [
      {
        icon: 'image-outline',
        label: '图片缓存',
        value: expoImageCacheSize > 0 ? `${formatBytes(expoImageCacheSize)}` : cacheStats && cacheStats.imageCount > 0 ? `${cacheStats.imageCount} 个文件` : '暂无',
        count: expoImageCacheSize > 0 ? undefined : cacheStats?.imageCount,
      },
      {
        icon: 'video-outline',
        label: '视频缓存',
        value: cacheStats && cacheStats.videoCount > 0 ? `${cacheStats.videoCount} 个文件` : '暂无',
        count: cacheStats?.videoCount,
      },
      {
        icon: 'music-note-outline',
        label: '音频缓存',
        value: cacheStats && cacheStats.audioCount > 0 ? `${cacheStats.audioCount} 个文件` : '暂无',
        count: cacheStats?.audioCount,
      },
      {
        icon: 'file-document-outline',
        label: '本地数据',
        value: asyncStorageSize > 0 ? formatBytes(asyncStorageSize) : '暂无',
      },
    ];
  }, [cacheStats, asyncStorageSize, expoImageCacheSize]);

  const renderContent = () => {
    if (loading) {
      return (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color={colors.primary.main} />
          <Text variant="body" color={colors.text.secondary} style={styles.loadingText}>
            正在计算存储空间...
          </Text>
        </View>
      );
    }

    return (
      <>
        {/* 存储总览 */}
        <View style={styles.section}>
          <View style={styles.sectionHeader}>
            <Text variant="caption" style={styles.sectionTitle}>
              存储使用
            </Text>
          </View>
          <View style={styles.totalCard}>
            <View style={styles.totalCardTop}>
              <MaterialCommunityIcons name="database" size={28} color={colors.primary.main} />
              <View style={styles.totalCardInfo}>
                <Text variant="h3" color={colors.text.primary} style={styles.totalSize}>
                  {formatBytes(totalSize)}
                </Text>
                <Text variant="caption" color={colors.text.secondary}>
                  总缓存大小
                </Text>
              </View>
            </View>
            <View style={styles.progressBarBg}>
              <View
                style={[
                  styles.progressBarFill,
                  {
                    width: `${Math.min((totalSize / (500 * 1024 * 1024)) * 100, 100)}%`,
                    backgroundColor:
                      totalSize > 400 * 1024 * 1024
                        ? colors.error.main
                        : totalSize > 250 * 1024 * 1024
                          ? colors.warning.main
                          : colors.primary.main,
                  },
                ]}
              />
            </View>
            <Text variant="caption" color={colors.text.hint}>
              上限 500 MB
            </Text>
          </View>
        </View>

        {/* 缓存明细 */}
        <View style={styles.section}>
          <View style={styles.sectionHeader}>
            <Text variant="caption" style={styles.sectionTitle}>
              缓存明细
            </Text>
          </View>
          {storageItems.map((item) => (
            <View key={item.icon} style={styles.statItem}>
              <View style={styles.statItemLeft}>
                <View style={styles.iconContainer}>
                  <MaterialCommunityIcons
                    name={item.icon as any}
                    size={22}
                    color={colors.text.secondary}
                  />
                </View>
                <Text variant="body" color={colors.text.primary}>
                  {item.label}
                </Text>
              </View>
              <Text variant="body" color={colors.text.secondary}>
                {item.value}
              </Text>
            </View>
          ))}
        </View>

        {/* 缓存管理 */}
        <View style={styles.section}>
          <View style={styles.sectionHeader}>
            <Text variant="caption" style={styles.sectionTitle}>
              缓存管理
            </Text>
          </View>
          <TouchableOpacity
            style={styles.actionItem}
            onPress={handleCleanupExpired}
            disabled={clearing}
            activeOpacity={0.7}
          >
            <View style={styles.actionItemLeft}>
              <View style={styles.iconContainer}>
                <MaterialCommunityIcons
                  name="broom"
                  size={22}
                  color={colors.text.secondary}
                />
              </View>
              <View>
                <Text variant="body" color={colors.text.primary}>
                  清理过期缓存
                </Text>
                <Text variant="caption" color={colors.text.secondary} style={styles.subtitle}>
                  清除超过 7 天未访问的缓存
                </Text>
              </View>
            </View>
            <MaterialCommunityIcons name="chevron-right" size={20} color={colors.text.hint} />
          </TouchableOpacity>
          <TouchableOpacity
            style={[styles.actionItem, styles.actionItemLast]}
            onPress={handleClearCache}
            disabled={clearing}
            activeOpacity={0.7}
          >
            <View style={styles.actionItemLeft}>
              <View style={styles.iconContainer}>
                <MaterialCommunityIcons
                  name="delete-sweep-outline"
                  size={22}
                  color={colors.error.main}
                />
              </View>
              <View>
                <Text variant="body" color={colors.error.main}>
                  清除所有缓存
                </Text>
                <Text variant="caption" color={colors.text.secondary} style={styles.subtitle}>
                  删除所有已缓存的媒体文件
                </Text>
              </View>
            </View>
            {clearing ? (
              <ActivityIndicator size="small" color={colors.error.main} />
            ) : (
              <MaterialCommunityIcons name="chevron-right" size={20} color={colors.text.hint} />
            )}
          </TouchableOpacity>
        </View>

        {/* 缓存策略说明 */}
        <View style={styles.tipContainer}>
          <MaterialCommunityIcons name="information-outline" size={16} color={colors.text.hint} />
          <Text variant="caption" color={colors.text.hint} style={styles.tipText}>
            应用会自动清理过期缓存（7 天未访问）并在缓存超过 500 MB 时启用 LRU 策略自动回收空间。清除缓存不会影响账号数据与聊天记录。
          </Text>
        </View>
      </>
    );
  };

  return (
    <SafeAreaView style={styles.container} edges={['bottom']}>
      <ScrollView
        contentContainerStyle={[
          styles.scrollContent,
          { paddingBottom: scrollBottomInset, paddingHorizontal: responsivePadding },
        ]}
      >
        {renderContent()}
      </ScrollView>
    </SafeAreaView>
  );
};

function createDataStorageStyles(colors: AppColors) {
  return StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: colors.background.paper,
    },
    scrollContent: {
      paddingVertical: spacing.lg,
    },
    loadingContainer: {
      alignItems: 'center',
      justifyContent: 'center',
      paddingVertical: spacing['3xl'],
    },
    loadingText: {
      marginTop: spacing.md,
    },
    section: {
      marginBottom: spacing.xl,
      maxWidth: CONTENT_MAX_WIDTH,
      alignSelf: 'center',
      width: '100%',
    },
    sectionHeader: {
      paddingHorizontal: spacing['2xl'],
      marginBottom: spacing.sm,
      marginTop: spacing.sm,
    },
    sectionTitle: {
      fontWeight: '600',
      fontSize: fontSizes.sm,
      color: colors.text.secondary,
      textTransform: 'uppercase',
      letterSpacing: 0.5,
    },
    totalCard: {
      marginHorizontal: spacing.lg,
      padding: spacing.xl,
      borderRadius: borderRadius.lg,
      backgroundColor: colors.background.default,
    },
    totalCardTop: {
      flexDirection: 'row',
      alignItems: 'center',
      marginBottom: spacing.lg,
    },
    totalCardInfo: {
      marginLeft: spacing.lg,
    },
    totalSize: {
      marginBottom: 2,
    },
    progressBarBg: {
      height: 6,
      borderRadius: 3,
      backgroundColor: colors.divider,
      marginBottom: spacing.sm,
      overflow: 'hidden',
    },
    progressBarFill: {
      height: '100%',
      borderRadius: 3,
    },
    statItem: {
      flexDirection: 'row',
      alignItems: 'center',
      justifyContent: 'space-between',
      paddingVertical: 14,
      paddingHorizontal: spacing['2xl'],
      borderBottomWidth: StyleSheet.hairlineWidth,
      borderBottomColor: colors.divider,
    },
    statItemLeft: {
      flexDirection: 'row',
      alignItems: 'center',
    },
    iconContainer: {
      width: 24,
      height: 24,
      justifyContent: 'center',
      alignItems: 'center',
      marginRight: spacing.lg,
    },
    actionItem: {
      flexDirection: 'row',
      alignItems: 'center',
      justifyContent: 'space-between',
      paddingVertical: 16,
      paddingHorizontal: spacing['2xl'],
      borderBottomWidth: StyleSheet.hairlineWidth,
      borderBottomColor: colors.divider,
    },
    actionItemLast: {
      borderBottomWidth: 0,
    },
    actionItemLeft: {
      flexDirection: 'row',
      alignItems: 'center',
      flex: 1,
    },
    subtitle: {
      marginTop: 2,
    },
    tipContainer: {
      flexDirection: 'row',
      alignItems: 'flex-start',
      marginHorizontal: spacing['2xl'],
      padding: spacing.md,
      backgroundColor: colors.background.default,
      borderRadius: 14,
      gap: spacing.sm,
      maxWidth: CONTENT_MAX_WIDTH,
      alignSelf: 'center',
      width: '100%',
    },
    tipText: {
      flex: 1,
      lineHeight: 20,
    },
  });
}

export default DataStorageScreen;
