import { HeaderBar } from '@/components/ui/HeaderBar';
import { Colors } from '@/constants/Colors';
import { useAppDispatch } from '@/hooks/redux';
import { useColorScheme } from '@/hooks/useColorScheme';
import { fetchExerciseConfig, normalizeToLibraryItems } from '@/services/exercises';
import { addExercise } from '@/store/checkinSlice';
import { EXERCISE_LIBRARY, getCategories } from '@/utils/exerciseLibrary';
import { Ionicons } from '@expo/vector-icons';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as Haptics from 'expo-haptics';
import { useLocalSearchParams, useRouter } from 'expo-router';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { Animated, FlatList, LayoutAnimation, Modal, Platform, SafeAreaView, StyleSheet, Text, TextInput, TouchableOpacity, UIManager, View } from 'react-native';

function formatDate(d: Date) {
  const y = d.getFullYear();
  const m = `${d.getMonth() + 1}`.padStart(2, '0');
  const day = `${d.getDate()}`.padStart(2, '0');
  return `${y}-${m}-${day}`;
}

export default function SelectExerciseScreen() {
  const dispatch = useAppDispatch();
  const router = useRouter();
  const params = useLocalSearchParams<{ date?: string }>();
  const today = useMemo(() => formatDate(new Date()), []);
  const currentDate = (typeof params?.date === 'string' && params.date) ? params.date : today;
  const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
  const colorTokens = Colors[theme];

  const [keyword, setKeyword] = useState('');
  const [category, setCategory] = useState<string>('全部');
  const [selectedKey, setSelectedKey] = useState<string | null>(null);
  const [sets, setSets] = useState(3);
  const [reps, setReps] = useState<number | undefined>(undefined);
  const [showCustomReps, setShowCustomReps] = useState(false);
  const [customRepsInput, setCustomRepsInput] = useState('');
  const [showCategoryPicker, setShowCategoryPicker] = useState(false);
  const [serverLibrary, setServerLibrary] = useState<{ key: string; name: string; description: string; category: string }[] | null>(null);
  const [serverCategories, setServerCategories] = useState<string[] | null>(null);

  const controlsOpacity = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
      UIManager.setLayoutAnimationEnabledExperimental(true);
    }
  }, []);
  useEffect(() => {
    let aborted = false;
    const CACHE_KEY = '@exercise_config_v1';
    (async () => {
      try {
        const cached = await AsyncStorage.getItem(CACHE_KEY);
        if (cached && !aborted) {
          const parsed = JSON.parse(cached);
          const items = normalizeToLibraryItems(parsed);
          if (items.length) {
            setServerLibrary(items);
            const cats = Array.from(new Set(items.map((i) => i.category)));
            setServerCategories(cats);
          }
        }
      } catch {}
      try {
        const resp = await fetchExerciseConfig();
        console.log('fetchExerciseConfig', resp);
        if (aborted) return;
        const items = normalizeToLibraryItems(resp);
        setServerLibrary(items);
        const cats = Array.from(new Set(items.map((i) => i.category)));
        setServerCategories(cats);
        try { await AsyncStorage.setItem(CACHE_KEY, JSON.stringify(resp)); } catch {}
      } catch (err) {}
    })();
    return () => { aborted = true; };
  }, []);

  const categories = useMemo(() => {
    const base = serverCategories ?? getCategories();
    return ['全部', ...base];
  }, [serverCategories]);
  const mainCategories = useMemo(() => {
    const preferred = ['全部', '核心与腹部', '脊柱与后链', '侧链与髋', '平衡与支撑'];
    const exists = (name: string) => categories.includes(name);
    const picked = preferred.filter(exists);
    // 兜底：若某些偏好分类不存在，补足其他分类
    const rest = categories.filter((c) => !picked.includes(c));
    while (picked.length < 5 && rest.length) picked.push(rest.shift() as string);
    return picked;
  }, [categories]);
  const library = useMemo(() => serverLibrary ?? EXERCISE_LIBRARY, [serverLibrary]);
  const filtered = useMemo(() => {
    const kw = keyword.trim().toLowerCase();
    const base = kw
      ? library.filter((e) => e.name.toLowerCase().includes(kw) || (e.description || '').toLowerCase().includes(kw))
      : library;
    if (category === '全部') return base;
    return base.filter((e) => e.category === category);
  }, [keyword, category, library]);

  const selected = useMemo(() => library.find((e) => e.key === selectedKey) || null, [selectedKey, library]);

  useEffect(() => {
    Animated.timing(controlsOpacity, {
      toValue: selected ? 1 : 0,
      duration: selected ? 220 : 160,
      useNativeDriver: true,
    }).start();
  }, [selected, controlsOpacity]);

  const handleAdd = () => {
    if (!selected) return;
    dispatch(addExercise({
      date: currentDate,
      item: {
        key: selected.key,
        name: selected.name,
        category: selected.category,
        sets: Math.max(1, sets),
        reps: reps && reps > 0 ? reps : undefined,
      },
    }));
    console.log('addExercise', currentDate, selected.key, sets, reps);
    // 自动同步将由中间件处理，无需手动调用 syncCheckin
    router.back();
  };

  const onSelectItem = (key: string) => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    if (selectedKey === key) {
      setSelectedKey(null);
      return;
    }
    setSets(3);
    setReps(undefined);
    setShowCustomReps(false);
    setCustomRepsInput('');
    setSelectedKey(key);
  };

  return (
    <SafeAreaView style={[styles.safeArea, { backgroundColor: theme === 'light' ? colorTokens.pageBackgroundEmphasis : colorTokens.background }]}>
      <View style={[styles.container, { backgroundColor: theme === 'light' ? colorTokens.pageBackgroundEmphasis : colorTokens.background }]}>
        <View pointerEvents="none" style={styles.bgOrnaments}>
          <View style={[styles.blob, { backgroundColor: colorTokens.ornamentPrimary, top: -60, right: -60 }]} />
          <View style={[styles.blob, { backgroundColor: colorTokens.ornamentAccent, bottom: -70, left: -70 }]} />
        </View>

        <HeaderBar title="选择动作" onBack={() => router.back()} withSafeTop={false} transparent />
        <View style={[styles.hero, { backgroundColor: colorTokens.heroSurfaceTint }]}>
          <Text style={[styles.subtitle, { color: colorTokens.textMuted }]}>从动作库里选择一个动作，设置组数与每组次数</Text>
        </View>

        {/* 大分类宫格（无横向滚动） */}
        <View style={styles.catGrid}>
          {[...mainCategories, '更多'].map((item) => {
            const active = category === item;
            const meta: Record<string, { bg: string }> = {
              全部: { bg: 'rgba(187,242,70,0.22)' },
              核心与腹部: { bg: 'rgba(187,242,70,0.18)' },
              脊柱与后链: { bg: 'rgba(149,204,227,0.20)' },
              侧链与髋: { bg: 'rgba(164,138,237,0.20)' },
              平衡与支撑: { bg: 'rgba(252,196,111,0.22)' },
              进阶控制: { bg: 'rgba(237,71,71,0.18)' },
              柔韧与拉伸: { bg: 'rgba(149,204,227,0.18)' },
              更多: { bg: 'rgba(24,24,27,0.06)' },
            };
            const scale = new Animated.Value(1);
            const onPressIn = () => Animated.spring(scale, { toValue: 0.96, useNativeDriver: true, speed: 20, bounciness: 6 }).start();
            const onPressOut = () => Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 20, bounciness: 6 }).start();
            const handlePress = () => {
              onPressOut();
              if (item === '更多') {
                setShowCategoryPicker(true);
                Haptics.selectionAsync();
              } else {
                setCategory(item);
                Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
              }
            };
            return (
              <Animated.View key={item} style={[styles.catTileWrapper, { transform: [{ scale }] }]}>
                <TouchableOpacity
                  activeOpacity={0.9}
                  onPressIn={onPressIn}
                  onPressOut={handlePress}
                  style={[styles.catTile, { backgroundColor: meta[item]?.bg ?? colorTokens.surface }, active && styles.catTileActive]}
                >
                  <Text style={[styles.catText, { color: active ? colorTokens.onPrimary : colorTokens.text }]}>{item}</Text>
                </TouchableOpacity>
              </Animated.View>
            );
          })}
        </View>

        {/* 分类选择弹层（更多） */}
        <Modal
          visible={showCategoryPicker}
          animationType="fade"
          transparent
          onRequestClose={() => setShowCategoryPicker(false)}
        >
          <TouchableOpacity activeOpacity={1} style={styles.modalOverlay} onPress={() => setShowCategoryPicker(false)}>
            <TouchableOpacity activeOpacity={1} style={[styles.modalSheet, { backgroundColor: colorTokens.card }]}
              onPress={(e) => e.stopPropagation() as any}
            >
              <Text style={[styles.modalTitle, { color: colorTokens.text }]}>选择分类</Text>
              <View style={styles.catGridModal}>
                {categories.filter((c) => c !== '全部').map((c) => {
                  const scale = new Animated.Value(1);
                  const onPressIn = () => Animated.spring(scale, { toValue: 0.96, useNativeDriver: true, speed: 20, bounciness: 6 }).start();
                  const onPressOut = () => Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 20, bounciness: 6 }).start();
                  return (
                    <Animated.View key={c} style={[styles.catTileWrapper, { transform: [{ scale }] }]}>
                      <TouchableOpacity
                        onPressIn={onPressIn}
                        onPressOut={() => {
                          onPressOut();
                          setCategory(c);
                          setShowCategoryPicker(false);
                          Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
                        }}
                        activeOpacity={0.9}
                        style={[styles.catTile, { backgroundColor: 'rgba(24,24,27,0.06)' }]}
                      >
                        <Text style={styles.catText}>{c}</Text>
                      </TouchableOpacity>
                    </Animated.View>
                  );
                })}
              </View>
            </TouchableOpacity>
          </TouchableOpacity>
        </Modal>

        <View style={styles.searchRow}>
          <TextInput
            value={keyword}
            onChangeText={setKeyword}
            placeholder="搜索动作名称/要点"
            placeholderTextColor={colorTokens.textMuted}
            style={[styles.searchInput, { backgroundColor: colorTokens.card, color: colorTokens.text, borderColor: colorTokens.border }]}
          />
        </View>

        <FlatList
          data={filtered}
          keyExtractor={(item) => item.key}
          contentContainerStyle={{ paddingHorizontal: 20, paddingBottom: 40 }}
          renderItem={({ item }) => {
            const isSelected = item.key === selectedKey;
            return (
              <TouchableOpacity
                style={[
                  styles.itemCard,
                  { backgroundColor: colorTokens.card },
                  isSelected && { borderWidth: 2, borderColor: colorTokens.primary },
                ]}
                onPress={() => onSelectItem(item.key)}
                activeOpacity={0.9}
              >
                <View style={{ flex: 1 }}>
                  <Text style={[styles.itemTitle, { color: colorTokens.text }]}>{item.name}</Text>
                  <Text style={[styles.itemMeta, { color: colorTokens.textMuted }]}>{item.category}</Text>
                  <Text style={[styles.itemDesc, { color: colorTokens.textMuted }]}>{item.description}</Text>
                </View>
                {isSelected && <Ionicons name="chevron-down" size={20} color={colorTokens.text} />}
                {isSelected && (
                  <Animated.View style={[styles.expandedBox, { opacity: controlsOpacity }]}>
                    <View style={styles.controlsRow}>
                      <View style={[styles.counterBox, { backgroundColor: colorTokens.surface }]}>
                        <Text style={[styles.counterLabel, { color: colorTokens.textMuted }]}>组数</Text>
                        <View style={styles.counterRow}>
                          <TouchableOpacity style={[styles.counterBtn, { backgroundColor: colorTokens.border }]} onPress={() => setSets(Math.max(1, sets - 1))}><Text style={[styles.counterBtnText, { color: colorTokens.text }]}>-</Text></TouchableOpacity>
                          <Text style={[styles.counterValue, { color: colorTokens.text }]}>{sets}</Text>
                          <TouchableOpacity style={[styles.counterBtn, { backgroundColor: colorTokens.border }]} onPress={() => setSets(Math.min(20, sets + 1))}><Text style={[styles.counterBtnText, { color: colorTokens.text }]}>+</Text></TouchableOpacity>
                        </View>
                      </View>

                      <View style={[styles.counterBox, { backgroundColor: colorTokens.surface }]}>
                        <Text style={[styles.counterLabel, { color: colorTokens.textMuted }]}>每组次数</Text>
                        <View style={styles.repsChipsRow}>
                          {[6, 8, 10, 12, 15, 20, 25, 30].map((v) => {
                            const active = reps === v;
                            return (
                              <TouchableOpacity
                                key={v}
                                style={[styles.repChip, active && { backgroundColor: colorTokens.primary, borderColor: colorTokens.primary }]}
                                onPress={() => {
                                  setReps(v);
                                  Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
                                }}
                              >
                                <Text style={[styles.repChipText, active && { color: colorTokens.onPrimary }]}>{v}</Text>
                              </TouchableOpacity>
                            );
                          })}
                          <TouchableOpacity
                            style={[styles.repChipGhost, { borderColor: colorTokens.border }]}
                            onPress={() => {
                              setShowCustomReps((s) => !s);
                              Haptics.selectionAsync();
                            }}
                          >
                            <Text style={[styles.repChipGhostText, { color: colorTokens.text }]}>自定义</Text>
                          </TouchableOpacity>
                        </View>
                        {showCustomReps && (
                          <View style={styles.customRepsRow}>
                            <TextInput
                              keyboardType="number-pad"
                              value={customRepsInput}
                              onChangeText={setCustomRepsInput}
                              placeholder="输入次数 (1-100)"
                              placeholderTextColor={colorTokens.textMuted}
                              style={[styles.customRepsInput, { borderColor: colorTokens.border, color: colorTokens.text }]}
                            />
                            <TouchableOpacity
                              style={[styles.customRepsBtn, { backgroundColor: colorTokens.primary }]}
                              onPress={() => {
                                const n = Math.max(1, Math.min(100, parseInt(customRepsInput || '0', 10)));
                                if (!Number.isNaN(n)) {
                                  setReps(n);
                                  Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
                                }
                              }}
                            >
                              <Text style={[styles.customRepsBtnText, { color: colorTokens.onPrimary }]}>确定</Text>
                            </TouchableOpacity>
                          </View>
                        )}
                      </View>
                    </View>

                    <TouchableOpacity
                      style={[styles.primaryBtn, { backgroundColor: colorTokens.primary }, (!reps || reps <= 0) && { opacity: 0.5 }]}
                      disabled={!reps || reps <= 0}
                      onPress={handleAdd}
                    >
                      <Text style={[styles.primaryBtnText, { color: colorTokens.onPrimary }]}>添加到今日打卡</Text>
                    </TouchableOpacity>
                  </Animated.View>
                )}
              </TouchableOpacity>
            );
          }}
        />


      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  safeArea: { flex: 1, backgroundColor: '#F7F8FA' },
  container: { flex: 1, backgroundColor: '#F7F8FA' },
  header: { paddingHorizontal: 20, paddingTop: 10, paddingBottom: 10 },
  headerRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', zIndex: 2 },
  backButton: { width: 32, height: 32, borderRadius: 16, alignItems: 'center', justifyContent: 'center', backgroundColor: '#E5E7EB' },
  headerTitle: { fontSize: 18, fontWeight: '800', color: '#1A1A1A' },
  subtitle: { marginTop: 6, fontSize: 12, color: '#6B7280' },
  catCard: { paddingHorizontal: 14, paddingVertical: 10, borderRadius: 14, flexDirection: 'row', alignItems: 'center' },
  catCardActive: { borderWidth: 2, borderColor: '#BBF246' },
  catEmoji: { fontSize: 16, marginRight: 6 },
  catText: { fontSize: 13, fontWeight: '800' },
  hero: { backgroundColor: 'rgba(187,242,70,0.18)', borderRadius: 16, padding: 14, marginTop: 8 },
  bgOrnaments: { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 },
  blob: { position: 'absolute', width: 260, height: 260, borderRadius: 999 },
  catGrid: { paddingHorizontal: 16, paddingTop: 10, flexDirection: 'row', flexWrap: 'wrap' },
  catTileWrapper: { width: '33.33%', padding: 6 },
  catTile: { borderRadius: 14, paddingVertical: 16, paddingHorizontal: 8, alignItems: 'center', justifyContent: 'center' },
  catTileActive: { borderWidth: 2, borderColor: '#BBF246' },
  searchRow: { paddingHorizontal: 20, marginTop: 8 },
  searchInput: { backgroundColor: '#FFFFFF', borderRadius: 12, paddingHorizontal: 12, paddingVertical: 10, color: '#111827' },
  itemCard: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 16, marginTop: 12, shadowColor: '#000', shadowOpacity: 0.06, shadowRadius: 12, shadowOffset: { width: 0, height: 6 }, elevation: 3 },
  itemCardSelected: { borderWidth: 2, borderColor: '#10B981' },
  itemTitle: { fontSize: 16, fontWeight: '800', color: '#111827' },
  itemMeta: { marginTop: 4, fontSize: 12, color: '#6B7280' },
  itemDesc: { marginTop: 6, fontSize: 12, color: '#6B7280' },
  expandedBox: { marginTop: 12 },
  controlsRow: { flexDirection: 'row', alignItems: 'center', gap: 12, flexWrap: 'wrap', marginBottom: 10 },
  counterBox: { backgroundColor: '#F3F4F6', borderRadius: 8, padding: 8 },
  counterLabel: { fontSize: 10, color: '#6B7280' },
  counterRow: { flexDirection: 'row', alignItems: 'center' },
  counterBtn: { backgroundColor: '#E5E7EB', width: 28, height: 28, borderRadius: 6, alignItems: 'center', justifyContent: 'center' },
  counterBtnText: { fontWeight: '800', color: '#111827' },
  counterValue: { minWidth: 40, textAlign: 'center', fontWeight: '700', color: '#111827' },
  repsChipsRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginTop: 6 },
  repChip: { paddingHorizontal: 12, paddingVertical: 8, borderRadius: 999, backgroundColor: '#F3F4F6', borderWidth: 1, borderColor: '#E5E7EB' },
  repChipText: { color: '#111827', fontWeight: '700' },
  repChipGhost: { paddingHorizontal: 12, paddingVertical: 8, borderRadius: 999, borderWidth: 1, backgroundColor: 'transparent' },
  repChipGhostText: { fontWeight: '700' },
  customRepsRow: { flexDirection: 'row', alignItems: 'center', gap: 10, marginTop: 8 },
  customRepsInput: { flex: 1, height: 40, borderWidth: 1, borderRadius: 10, paddingHorizontal: 12 },
  customRepsBtn: { paddingHorizontal: 12, paddingVertical: 10, borderRadius: 10 },
  customRepsBtnText: { fontWeight: '800' },
  modalOverlay: { flex: 1, backgroundColor: 'rgba(0,0,0,0.35)', alignItems: 'center', justifyContent: 'flex-end' },
  modalSheet: { width: '100%', borderTopLeftRadius: 16, borderTopRightRadius: 16, paddingHorizontal: 16, paddingTop: 14, paddingBottom: 24 },
  modalTitle: { fontSize: 16, fontWeight: '800', marginBottom: 8 },
  catGridModal: { flexDirection: 'row', flexWrap: 'wrap' },
  primaryBtn: { backgroundColor: '#111827', paddingVertical: 12, borderRadius: 12, alignItems: 'center' },
  primaryBtnText: { color: '#FFFFFF', fontWeight: '800' },
});


