/**
 * 学科资料列表页：展示某个学科下的所有资料
 */
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  View,
  StyleSheet,
  ScrollView,
  TouchableOpacity,
  StatusBar,
  RefreshControl,
  FlatList,
} from 'react-native';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { useRouter, useLocalSearchParams } from 'expo-router';
import { MaterialCommunityIcons } from '@expo/vector-icons';

import {
  spacing,
  fontSizes,
  borderRadius,
  shadows,
  useAppColors,
  useResolvedColorScheme,
  type AppColors,
} from '../../theme';
import * as hrefs from '../../navigation/hrefs';
import { Text, ResponsiveContainer, Loading } from '../../components/common';
import { useResponsive, useResponsiveSpacing, useBreakpointGTE } from '../../hooks/useResponsive';
import type { MaterialSubject, MaterialFile, MaterialFileType } from '../../types/material';
import {
  materialRepository,
} from '../../data/repositories/MaterialRepository';
import {
  MATERIAL_FILE_TYPE_ICONS,
  MATERIAL_FILE_TYPE_COLORS,
  formatFileSize,
} from '../../types/material';

export const SubjectMaterialsScreen: React.FC = () => {
  const colors = useAppColors();
  const resolvedScheme = useResolvedColorScheme();
  const statusBarStyle = resolvedScheme === 'dark' ? 'light-content' : 'dark-content';
  const styles = useMemo(() => createSubjectMaterialsStyles(colors), [colors]);
  const router = useRouter();
  const params = useLocalSearchParams<{ subjectId: string }>();
  const insets = useSafeAreaInsets();
  const { isMobile } = useResponsive();
  const isWideScreen = useBreakpointGTE('lg');
  const responsivePadding = useResponsiveSpacing({ xs: 8, sm: 12, md: 16, lg: 24, xl: 32 });

  const [subject, setSubject] = useState<MaterialSubject | null>(null);
  const [materials, setMaterials] = useState<MaterialFile[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [selectedFileType, setSelectedFileType] = useState<MaterialFileType | null>(null);

  const scrollBottomInset = isMobile ? 88 + insets.bottom + spacing.md : spacing['3xl'];

  const loadData = useCallback(async () => {
    if (!params.subjectId) {
      setError('缺少学科ID');
      setIsLoading(false);
      return;
    }

    try {
      setError(null);
      const [subjectData, materialsData] = await Promise.all([
        materialRepository.getSubjectById(params.subjectId),
        materialRepository.getMaterials({ subjectId: params.subjectId }),
      ]);
      setSubject(subjectData);
      setMaterials(materialsData.materials);
    } catch (err) {
      setError('加载资料列表失败');
      console.error('Failed to load materials:', err);
    } finally {
      setIsLoading(false);
      setIsRefreshing(false);
    }
  }, [params.subjectId]);

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

  const handleRefresh = useCallback(() => {
    setIsRefreshing(true);
    loadData();
  }, [loadData]);

  const onOpenMaterial = useCallback(
    (materialId: string) => {
      router.push(hrefs.hrefMaterialDetail(materialId));
    },
    [router]
  );

  const filteredMaterials = useMemo(() => {
    if (!selectedFileType) return materials;
    return materials.filter((m) => m.file_type === selectedFileType);
  }, [materials, selectedFileType]);

  const fileTypes: { type: MaterialFileType | null; label: string }[] = [
    { type: null, label: '全部' },
    { type: 'pdf', label: 'PDF' },
    { type: 'word', label: 'Word' },
    { type: 'ppt', label: 'PPT' },
  ];

  const cardStyle = useMemo(
    () => ({
      backgroundColor: colors.background.paper,
      borderRadius: 12,
      overflow: 'hidden' as const,
      shadowColor: '#000',
      shadowOffset: { width: 0, height: 1 },
      shadowOpacity: 0.05,
      shadowRadius: 4,
      elevation: 1,
    }),
    [colors]
  );

  const renderMaterialItem = ({ item }: { item: MaterialFile }) => {
    const fileColor = MATERIAL_FILE_TYPE_COLORS[item.file_type];
    const iconName = MATERIAL_FILE_TYPE_ICONS[item.file_type];

    return (
      <TouchableOpacity
        style={[styles.materialCard, cardStyle]}
        onPress={() => onOpenMaterial(item.id)}
        activeOpacity={0.85}
      >
        <View style={[styles.fileTypeIcon, { backgroundColor: fileColor }]}>
          <MaterialCommunityIcons name={iconName as any} size={24} color="#FFFFFF" />
        </View>
        <View style={styles.materialContent}>
          <Text variant="body" style={styles.materialTitle} numberOfLines={2}>
            {item.title}
          </Text>
          <View style={styles.materialMeta}>
            <Text variant="caption" color={colors.text.hint}>
              {formatFileSize(item.file_size)}
            </Text>
            <Text variant="caption" color={colors.text.hint}>
              {' · '}
            </Text>
            <Text variant="caption" color={colors.text.hint}>
              {item.download_count} 次下载
            </Text>
          </View>
          {item.description && (
            <Text variant="caption" color={colors.text.secondary} numberOfLines={1}>
              {item.description}
            </Text>
          )}
        </View>
        <MaterialCommunityIcons name="chevron-right" size={20} color={colors.text.hint} />
      </TouchableOpacity>
    );
  };

  const renderFilterTabs = () => (
    <View style={styles.filterContainer}>
      {fileTypes.map(({ type, label }) => (
        <TouchableOpacity
          key={label}
          style={[
            styles.filterTab,
            selectedFileType === type && styles.filterTabActive,
            selectedFileType === type && { backgroundColor: colors.primary.main },
          ]}
          onPress={() => setSelectedFileType(type)}
          activeOpacity={0.7}
        >
          <Text
            variant="caption"
            color={selectedFileType === type ? colors.primary.contrast : colors.text.secondary}
            style={styles.filterTabText}
          >
            {label}
          </Text>
        </TouchableOpacity>
      ))}
    </View>
  );

  const renderEmptyComponent = () => (
    <View style={styles.centerContainer}>
      <MaterialCommunityIcons name="file-document-outline" size={64} color={colors.text.hint} />
      <Text variant="body" color={colors.text.secondary} style={styles.emptyText}>
        {selectedFileType ? '该类型暂无资料' : '暂无资料'}
      </Text>
    </View>
  );

  const renderContent = () => {
    if (isLoading) {
      return (
        <View style={styles.centerContainer}>
          <Loading size="large" />
        </View>
      );
    }

    if (error) {
      return (
        <View style={styles.centerContainer}>
          <MaterialCommunityIcons name="alert-circle-outline" size={48} color={colors.text.hint} />
          <Text variant="body" color={colors.text.secondary} style={styles.errorText}>
            {error}
          </Text>
          <TouchableOpacity onPress={loadData} style={styles.retryButton}>
            <Text variant="body" color={colors.primary.main}>
              重试
            </Text>
          </TouchableOpacity>
        </View>
      );
    }

    return (
      <FlatList
        data={filteredMaterials}
        keyExtractor={(item) => item.id}
        renderItem={renderMaterialItem}
        ListHeaderComponent={renderFilterTabs}
        ListEmptyComponent={renderEmptyComponent}
        contentContainerStyle={styles.listContent}
        showsVerticalScrollIndicator={false}
        refreshControl={
          <RefreshControl
            refreshing={isRefreshing}
            onRefresh={handleRefresh}
            tintColor={colors.primary.main}
          />
        }
      />
    );
  };

  return (
    <SafeAreaView style={styles.container} edges={['top', 'bottom']}>
      <StatusBar barStyle={statusBarStyle} backgroundColor={colors.background.default} />

      {/* Header */}
      <View style={[styles.header, isWideScreen && styles.headerWide]}>
        <View style={styles.headerLeft}>
          <TouchableOpacity onPress={() => router.back()} style={styles.backButton}>
            <MaterialCommunityIcons name="arrow-left" size={24} color={colors.text.primary} />
          </TouchableOpacity>
        </View>
        <View style={styles.headerCenter}>
          <Text style={[styles.headerTitle, isWideScreen && styles.headerTitleWide]}>
            {subject?.name || '资料列表'}
          </Text>
        </View>
        <View style={styles.headerRight}>
          <TouchableOpacity style={styles.searchButton}>
            <MaterialCommunityIcons name="magnify" size={24} color={colors.text.primary} />
          </TouchableOpacity>
        </View>
      </View>

      {/* Content */}
      {isWideScreen ? (
        <ResponsiveContainer maxWidth={800}>
          <View style={[styles.contentWrapper, { paddingBottom: scrollBottomInset }]}>
            {renderContent()}
          </View>
        </ResponsiveContainer>
      ) : (
        <View style={[styles.contentWrapper, { paddingBottom: scrollBottomInset, paddingHorizontal: responsivePadding }]}>
          {renderContent()}
        </View>
      )}
    </SafeAreaView>
  );
};

export default SubjectMaterialsScreen;

function createSubjectMaterialsStyles(colors: AppColors) {
  const headerBg = colors.background.default;
  return StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: colors.background.default,
    },
    header: {
      flexDirection: 'row',
      alignItems: 'center',
      justifyContent: 'space-between',
      paddingHorizontal: spacing.md,
      paddingVertical: spacing.md,
      backgroundColor: headerBg,
      ...shadows.sm,
    },
    headerWide: {
      paddingHorizontal: spacing.lg,
      paddingVertical: spacing.lg,
    },
    headerLeft: {
      width: 44,
      alignItems: 'flex-start',
    },
    backButton: {
      padding: spacing.xs,
    },
    headerCenter: {
      flexDirection: 'row',
      alignItems: 'center',
    },
    headerTitle: {
      fontSize: 19,
      fontWeight: '700',
      color: colors.text.primary,
    },
    headerTitleWide: {
      fontSize: 22,
    },
    headerRight: {
      width: 44,
      alignItems: 'flex-end',
    },
    searchButton: {
      padding: spacing.xs,
    },
    contentWrapper: {
      flex: 1,
    },
    listContent: {
      paddingTop: spacing.md,
    },
    filterContainer: {
      flexDirection: 'row',
      gap: spacing.sm,
      marginBottom: spacing.md,
    },
    filterTab: {
      paddingVertical: spacing.sm,
      paddingHorizontal: spacing.md,
      borderRadius: borderRadius.full,
      backgroundColor: colors.background.paper,
    },
    filterTabActive: {
      // backgroundColor set inline
    },
    filterTabText: {
      fontWeight: '600',
    },
    materialCard: {
      flexDirection: 'row',
      alignItems: 'center',
      paddingVertical: spacing.md,
      paddingHorizontal: spacing.md,
      marginBottom: spacing.sm,
    },
    fileTypeIcon: {
      width: 44,
      height: 44,
      borderRadius: borderRadius.md,
      alignItems: 'center',
      justifyContent: 'center',
    },
    materialContent: {
      flex: 1,
      marginLeft: spacing.md,
      marginRight: spacing.sm,
    },
    materialTitle: {
      fontWeight: '600',
      fontSize: fontSizes.md,
      color: colors.text.primary,
    },
    materialMeta: {
      flexDirection: 'row',
      alignItems: 'center',
      marginTop: 4,
    },
    centerContainer: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
      paddingVertical: spacing['3xl'],
    },
    errorText: {
      marginTop: spacing.md,
      textAlign: 'center',
    },
    emptyText: {
      marginTop: spacing.md,
      textAlign: 'center',
    },
    retryButton: {
      marginTop: spacing.md,
      paddingVertical: spacing.sm,
      paddingHorizontal: spacing.lg,
    },
  });
}
