import { HeaderBar } from '@/components/ui/HeaderBar';
import { Colors } from '@/constants/Colors';
import { useColorScheme } from '@/hooks/useColorScheme';
import { Ionicons } from '@expo/vector-icons';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as Haptics from 'expo-haptics';
import { useRouter } from 'expo-router';
import React, { useEffect, useMemo, useState } from 'react';
import {
  SafeAreaView,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import { ProgressBar } from '@/components/ProgressBar';
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
import { updateUser as updateUserApi } from '@/services/users';
import { fetchMyProfile } from '@/store/userSlice';
import { useFocusEffect } from '@react-navigation/native';

const STORAGE_KEYS = {
  calories: '@goal_calories_burn',
  steps: '@goal_daily_steps',
  purposes: '@goal_pilates_purposes',
} as const;

const CALORIES_RANGE = { min: 100, max: 1500, step: 50 };
const STEPS_RANGE = { min: 2000, max: 20000, step: 500 };

function arraysEqualUnordered(a?: string[], b?: string[]): boolean {
  if (!Array.isArray(a) && !Array.isArray(b)) return true;
  if (!Array.isArray(a) || !Array.isArray(b)) return false;
  if (a.length !== b.length) return false;
  const sa = [...a].sort();
  const sb = [...b].sort();
  for (let i = 0; i < sa.length; i += 1) {
    if (sa[i] !== sb[i]) return false;
  }
  return true;
}

export default function GoalsScreen() {
  const router = useRouter();
  const insets = useSafeAreaInsets();
  const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
  const colors = Colors[theme];
  const dispatch = useAppDispatch();
  const accountProfile = useAppSelector((s) => (s as any)?.user?.profile as any);
  const userId: string | undefined = useMemo(() => {
    return (
      accountProfile?.userId ||
      accountProfile?.id ||
      accountProfile?._id ||
      accountProfile?.uid ||
      undefined
    ) as string | undefined;
  }, [accountProfile]);

  const [calories, setCalories] = useState<number>(400);
  const [steps, setSteps] = useState<number>(8000);
  const [purposes, setPurposes] = useState<string[]>([]);
  const lastSentRef = React.useRef<{ calories?: number; steps?: number; purposes?: string[] }>({});

  useEffect(() => {
    const load = async () => {
      try {
        const [c, s, p] = await Promise.all([
          AsyncStorage.getItem(STORAGE_KEYS.calories),
          AsyncStorage.getItem(STORAGE_KEYS.steps),
          AsyncStorage.getItem(STORAGE_KEYS.purposes),
        ]);
        if (c) {
          const v = parseInt(c, 10);
          if (!Number.isNaN(v)) setCalories(v);
        }
        if (s) {
          const v = parseInt(s, 10);
          if (!Number.isNaN(v)) setSteps(v);
        }
        if (p) {
          try {
            const parsed = JSON.parse(p);
            if (Array.isArray(parsed)) setPurposes(parsed.filter((x) => typeof x === 'string'));
          } catch { }
        }
      } catch { }
    };
    load();
  }, []);

  // 页面聚焦时，从后端拉取并用全局 profile 的值覆盖 UI，保证是最新
  useFocusEffect(
    React.useCallback(() => {
      (async () => {
        try {
          await dispatch(fetchMyProfile() as any);
          const latest = (accountProfile ?? {}) as any;
          if (typeof latest?.dailyCaloriesGoal === 'number') setCalories(latest.dailyCaloriesGoal);
          if (typeof latest?.dailyStepsGoal === 'number') setSteps(latest.dailyStepsGoal);
          if (Array.isArray(latest?.pilatesPurposes)) setPurposes(latest.pilatesPurposes.filter((x: any) => typeof x === 'string'));
        } catch { }
      })();
    }, [dispatch])
  );

  // 当全局 profile 有变化时，同步覆盖 UI
  useEffect(() => {
    const latest = (accountProfile ?? {}) as any;
    if (typeof latest?.dailyCaloriesGoal === 'number') setCalories(latest.dailyCaloriesGoal);
    if (typeof latest?.dailyStepsGoal === 'number') setSteps(latest.dailyStepsGoal);
    if (Array.isArray(latest?.pilatesPurposes)) setPurposes(latest.pilatesPurposes.filter((x: any) => typeof x === 'string'));
  }, [accountProfile]);

  // 当全局 profile 变化（例如刚拉完或保存后刷新）时，将“已发送基线”对齐为后端值，避免重复上报
  useEffect(() => {
    const latest = (accountProfile ?? {}) as any;
    if (typeof latest?.dailyCaloriesGoal === 'number') {
      lastSentRef.current.calories = latest.dailyCaloriesGoal;
    }
    if (typeof latest?.dailyStepsGoal === 'number') {
      lastSentRef.current.steps = latest.dailyStepsGoal;
    }
    if (Array.isArray(latest?.pilatesPurposes)) {
      lastSentRef.current.purposes = [...latest.pilatesPurposes];
    }
  }, [accountProfile]);

  useEffect(() => {
    AsyncStorage.setItem(STORAGE_KEYS.calories, String(calories)).catch(() => { });
    if (!userId) return;
    if (lastSentRef.current.calories === calories) return;
    lastSentRef.current.calories = calories;
    (async () => {
      try {
        await updateUserApi({ userId, dailyCaloriesGoal: calories });
        await dispatch(fetchMyProfile() as any);
      } catch { }
    })();
  }, [calories, userId]);

  useEffect(() => {
    AsyncStorage.setItem(STORAGE_KEYS.steps, String(steps)).catch(() => { });
    if (!userId) return;
    if (lastSentRef.current.steps === steps) return;
    lastSentRef.current.steps = steps;
    (async () => {
      try {
        await updateUserApi({ userId, dailyStepsGoal: steps });
        await dispatch(fetchMyProfile() as any);
      } catch { }
    })();
  }, [steps, userId]);

  useEffect(() => {
    AsyncStorage.setItem(STORAGE_KEYS.purposes, JSON.stringify(purposes)).catch(() => { });
    if (!userId) return;
    if (arraysEqualUnordered(lastSentRef.current.purposes, purposes)) return;
    lastSentRef.current.purposes = [...purposes];
    (async () => {
      try {
        await updateUserApi({ userId, pilatesPurposes: purposes });
        await dispatch(fetchMyProfile() as any);
      } catch { }
    })();
  }, [purposes, userId]);

  const caloriesPercent = useMemo(() =>
    (Math.min(CALORIES_RANGE.max, Math.max(CALORIES_RANGE.min, calories)) - CALORIES_RANGE.min) /
    (CALORIES_RANGE.max - CALORIES_RANGE.min),
    [calories]);

  const stepsPercent = useMemo(() =>
    (Math.min(STEPS_RANGE.max, Math.max(STEPS_RANGE.min, steps)) - STEPS_RANGE.min) /
    (STEPS_RANGE.max - STEPS_RANGE.min),
    [steps]);

  const changeWithHaptics = (next: number, setter: (v: number) => void) => {
    if (process.env.EXPO_OS === 'ios') {
      Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
    }
    setter(next);
  };

  const inc = (value: number, range: { step: number; max: number }) => {
    return Math.min(range.max, value + range.step);
  };
  const dec = (value: number, range: { step: number; min: number }) => {
    return Math.max(range.min, value - range.step);
  };

  const SectionCard: React.FC<{ title: string; subtitle?: string; children: React.ReactNode }>
    = ({ title, subtitle, children }) => (
      <View style={[styles.card, { backgroundColor: colors.surface }]}>
        <Text style={[styles.cardTitle, { color: colors.text }]}>{title}</Text>
        {subtitle ? <Text style={[styles.cardSubtitle, { color: colors.textSecondary }]}>{subtitle}</Text> : null}
        {children}
      </View>
    );

  const PresetChip: React.FC<{ label: string; active?: boolean; onPress: () => void }>
    = ({ label, active, onPress }) => (
      <TouchableOpacity
        onPress={onPress}
        style={[styles.chip, { backgroundColor: active ? colors.primary : colors.card, borderColor: colors.border }]}
      >
        <Text style={[styles.chipText, { color: active ? colors.onPrimary : colors.text }]}>{label}</Text>
      </TouchableOpacity>
    );

  const Stepper: React.FC<{ onDec: () => void; onInc: () => void }>
    = ({ onDec, onInc }) => (
      <View style={styles.stepperRow}>
        <TouchableOpacity onPress={onDec} style={[styles.stepperBtn, { backgroundColor: colors.card, borderColor: colors.border }]}>
          <Text style={[styles.stepperText, { color: colors.text }]}>-</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={onInc} style={[styles.stepperBtn, { backgroundColor: colors.card, borderColor: colors.border }]}>
          <Text style={[styles.stepperText, { color: colors.text }]}>+</Text>
        </TouchableOpacity>
      </View>
    );

  const PURPOSE_OPTIONS: { id: string; label: string; icon: any }[] = [
    { id: 'core', label: '增强核心力量', icon: 'barbell-outline' },
    { id: 'posture', label: '改善姿势体态', icon: 'body-outline' },
    { id: 'flexibility', label: '提高柔韧灵活', icon: 'walk-outline' },
    { id: 'balance', label: '强化平衡稳定', icon: 'accessibility-outline' },
    { id: 'shape', label: '塑形与线条', icon: 'heart-outline' },
    { id: 'stress', label: '减压与身心放松', icon: 'leaf-outline' },
    { id: 'backpain', label: '预防/改善腰背痛', icon: 'shield-checkmark-outline' },
    { id: 'rehab', label: '术后/伤后康复', icon: 'medkit-outline' },
    { id: 'performance', label: '提升运动表现', icon: 'fitness-outline' },
  ];

  const togglePurpose = (id: string) => {
    if (process.env.EXPO_OS === 'ios') {
      Haptics.selectionAsync();
    }
    setPurposes((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]
    );
  };

  return (
    <View style={[styles.container, { backgroundColor: theme === 'light' ? '#F5F5F5' : colors.background }]}>
      <SafeAreaView style={styles.safeArea}>
        <HeaderBar title="目标管理" onBack={() => router.back()} withSafeTop={false} tone={theme} transparent />
        <ScrollView contentContainerStyle={[styles.content, { paddingBottom: Math.max(20, insets.bottom + 16) }]}
          showsVerticalScrollIndicator={false}
        >
          <SectionCard title="每日卡路里消耗目标" subtitle="设置你计划每天通过活动消耗的热量">
            <View style={styles.rowBetween}>
              <Text style={[styles.valueText, { color: colors.text }]}>{calories} kcal</Text>
              <Stepper
                onDec={() => changeWithHaptics(dec(calories, CALORIES_RANGE), setCalories)}
                onInc={() => changeWithHaptics(inc(calories, CALORIES_RANGE), setCalories)}
              />
            </View>
            <ProgressBar
              progress={caloriesPercent}
              height={18}
              style={styles.progressMargin}
              trackColor={theme === 'light' ? '#EDEDED' : colors.separator}
              fillColor={colors.primary}
            />
            <View style={styles.chipsRow}>
              {[200, 300, 400, 500, 600].map((v) => (
                <PresetChip key={v}
                  label={`${v}`}
                  active={v === calories}
                  onPress={() => changeWithHaptics(v, setCalories)}
                />
              ))}
            </View>
            <Text style={[styles.rangeHint, { color: colors.textMuted }]}>建议范围 {CALORIES_RANGE.min}-{CALORIES_RANGE.max} kcal，步进 {CALORIES_RANGE.step}</Text>
          </SectionCard>

          <SectionCard title="每日步数目标" subtitle="快速设置你的目标步数">
            <View style={styles.rowBetween}>
              <Text style={[styles.valueText, { color: colors.text }]}>{steps.toLocaleString()} 步</Text>
              <Stepper
                onDec={() => changeWithHaptics(dec(steps, STEPS_RANGE), setSteps)}
                onInc={() => changeWithHaptics(inc(steps, STEPS_RANGE), setSteps)}
              />
            </View>
            <ProgressBar
              progress={stepsPercent}
              height={18}
              style={styles.progressMargin}
              trackColor={theme === 'light' ? '#EDEDED' : colors.separator}
              fillColor={colors.primary}
            />
            <View style={styles.chipsRow}>
              {[6000, 8000, 10000, 12000, 15000].map((v) => (
                <PresetChip key={v}
                  label={`${v / 1000}k`}
                  active={v === steps}
                  onPress={() => changeWithHaptics(v, setSteps)}
                />
              ))}
            </View>
            <Text style={[styles.rangeHint, { color: colors.textMuted }]}>建议范围 {STEPS_RANGE.min.toLocaleString()}-{STEPS_RANGE.max.toLocaleString()}，步进 {STEPS_RANGE.step}</Text>
          </SectionCard>

          <SectionCard
            title="练习普拉提是为了什么"
            subtitle="可多选"
          >
            <View style={styles.grid}>
              {PURPOSE_OPTIONS.map((opt) => {
                const active = purposes.includes(opt.id);
                return (
                  <TouchableOpacity
                    key={opt.id}
                    style={[
                      styles.optionCard,
                      {
                        backgroundColor: active ? colors.primary : colors.card,
                        borderColor: active ? colors.primary : colors.border,
                      },
                    ]}
                    activeOpacity={0.9}
                    onPress={() => togglePurpose(opt.id)}
                  >
                    <View style={styles.optionIconWrap}>
                      <Ionicons
                        name={opt.icon}
                        size={20}
                        color={active ? colors.onPrimary : colors.text}
                      />
                    </View>
                    <Text
                      numberOfLines={2}
                      style={[
                        styles.optionLabel,
                        { color: active ? colors.onPrimary : colors.text },
                      ]}
                    >
                      {opt.label}
                    </Text>
                  </TouchableOpacity>
                );
              })}
            </View>
            {purposes.length > 0 && (
              <Text style={[styles.selectedHint, { color: colors.textSecondary }]}>已选择 {purposes.length} 项</Text>
            )}
          </SectionCard>
        </ScrollView>
      </SafeAreaView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 16,
  },
  backButton: {
    width: 32,
    height: 32,
    borderRadius: 16,
    alignItems: 'center',
    justifyContent: 'center',
  },
  headerTitle: {
    fontSize: 20,
    fontWeight: '700',
  },
  safeArea: {
    flex: 1,
  },
  content: {
    paddingHorizontal: 20,
    paddingTop: 8,
  },
  card: {
    borderRadius: 16,
    padding: 16,
    marginTop: 16,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.08,
    shadowRadius: 8,
    elevation: 2,
  },
  cardTitle: {
    fontSize: 18,
    fontWeight: '700',
  },
  cardSubtitle: {
    fontSize: 13,
    marginTop: 4,
  },
  rowBetween: {
    marginTop: 12,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  valueText: {
    fontSize: 24,
    fontWeight: '800',
  },
  chipsRow: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 8,
    marginTop: 14,
  },
  chip: {
    paddingHorizontal: 12,
    paddingVertical: 8,
    borderRadius: 20,
    borderWidth: 1,
  },
  chipText: {
    fontSize: 14,
    fontWeight: '600',
  },
  stepperRow: {
    flexDirection: 'row',
    gap: 10,
  },
  stepperBtn: {
    width: 36,
    height: 36,
    borderRadius: 18,
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 1,
  },
  stepperText: {
    fontSize: 20,
    fontWeight: '700',
  },
  rangeHint: {
    fontSize: 12,
    marginTop: 10,
  },
  progressMargin: {
    marginTop: 12,
  },
  grid: {
    marginTop: 12,
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'space-between',
    rowGap: 12,
  },
  optionCard: {
    width: '48%',
    borderRadius: 14,
    paddingVertical: 14,
    paddingHorizontal: 12,
    borderWidth: 1,
    flexDirection: 'row',
    alignItems: 'center',
    gap: 10,
  },
  optionIconWrap: {
    width: 28,
    height: 28,
    borderRadius: 14,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'rgba(0,0,0,0.04)',
  },
  optionLabel: {
    flex: 1,
    fontSize: 14,
    fontWeight: '700',
  },
  selectedHint: {
    marginTop: 10,
    fontSize: 12,
  },
});


