import {
  ensureHealthPermissions,
  fetchWristTemperature,
  fetchWristTemperatureHistory,
  WristTemperatureHistoryPoint
} from '@/utils/health';
import { HealthKitUtils } from '@/utils/healthKit';
import { Ionicons } from '@expo/vector-icons';
import { useIsFocused } from '@react-navigation/native';
import dayjs from 'dayjs';
import { LinearGradient } from 'expo-linear-gradient';
import { BlurView } from 'expo-blur';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Dimensions,
  Modal,
  Platform,
  Pressable,
  StyleSheet,
  Text,
  View
} from 'react-native';
import Svg, {
  Circle,
  Defs,
  Line,
  Path,
  Stop,
  LinearGradient as SvgLinearGradient
} from 'react-native-svg';
import HealthDataCard from './HealthDataCard';

interface WristTemperatureCardProps {
  style?: object;
  selectedDate?: Date;
}

const screenWidth = Dimensions.get('window').width;
const INITIAL_CHART_WIDTH = screenWidth - 32;
const CHART_HEIGHT = 240;
const CHART_HORIZONTAL_PADDING = 20;
const LABEL_ESTIMATED_WIDTH = 44;

const WristTemperatureCard: React.FC<WristTemperatureCardProps> = ({
  style,
  selectedDate
}) => {
  const { t } = useTranslation();
  const isFocused = useIsFocused();
  const [temperature, setTemperature] = useState<number | null>(null);
  const [loading, setLoading] = useState(false);
  const loadingRef = useRef(false);
  const [historyVisible, setHistoryVisible] = useState(false);
  const [history, setHistory] = useState<WristTemperatureHistoryPoint[]>([]);
  const [historyLoading, setHistoryLoading] = useState(false);
  const historyLoadingRef = useRef(false);
  const [chartWidth, setChartWidth] = useState(INITIAL_CHART_WIDTH);

  useEffect(() => {
    const loadData = async () => {
      const dateToUse = selectedDate || new Date();

      if (!isFocused) return;
      if (!HealthKitUtils.isAvailable()) {
        setTemperature(null);
        return;
      }

      // 防止重复请求
      if (loadingRef.current) return;

      try {
        loadingRef.current = true;
        setLoading(true);

        const hasPermission = await ensureHealthPermissions();
        if (!hasPermission) {
          setTemperature(null);
          return;
        }

        const dayStart = dayjs(dateToUse).startOf('day');
        // wrist temperature samples often start于前一晚，查询时向前扩展一天以包含跨夜数据
        const options = {
          startDate: dayStart.subtract(1, 'day').toDate().toISOString(),
          endDate: dayStart.endOf('day').toDate().toISOString()
        };

        const data = await fetchWristTemperature(options, dateToUse);
        setTemperature(data);
      } catch (error) {
        console.error('WristTemperatureCard: Failed to get wrist temperature data:', error);
        setTemperature(null);
      } finally {
        setLoading(false);
        loadingRef.current = false;
      }
    };

    loadData();
  }, [isFocused, selectedDate]);

  useEffect(() => {
    if (!historyVisible || !isFocused) return;

    const loadHistory = async () => {
      if (historyLoadingRef.current) return;
      if (!HealthKitUtils.isAvailable()) {
        setHistory([]);
        return;
      }

      try {
        historyLoadingRef.current = true;
        setHistoryLoading(true);

        const hasPermission = await ensureHealthPermissions();
        if (!hasPermission) {
          setHistory([]);
          return;
        }

        const end = dayjs(selectedDate || new Date()).endOf('day');
        const start = end.subtract(30, 'day').startOf('day').subtract(1, 'day');
        const options = {
          startDate: start.toDate().toISOString(),
          endDate: end.toDate().toISOString(),
          limit: 1200
        };

        const historyData = await fetchWristTemperatureHistory(options);
        setHistory(historyData);
      } catch (error) {
        console.error('WristTemperatureCard: Failed to get wrist temperature history:', error);
        setHistory([]);
      } finally {
        historyLoadingRef.current = false;
        setHistoryLoading(false);
      }
    };

    loadHistory();
  }, [historyVisible, selectedDate, isFocused]);

  const baseline = useMemo(() => {
    if (!history.length) return null;
    const avg = history.reduce((sum, point) => sum + point.value, 0) / history.length;
    return Number(avg.toFixed(2));
  }, [history]);

  const chartRange = useMemo(() => {
    if (!history.length) return { min: -1, max: 1 };

    const values = history.map((p) => p.value);
    const minValue = Math.min(...values);
    const maxValue = Math.max(...values);
    const center = baseline ?? (minValue + maxValue) / 2;
    const maxDeviation = Math.max(Math.abs(maxValue - center), Math.abs(minValue - center), 0.2);
    const padding = Math.max(maxDeviation * 0.25, 0.15);

    return {
      min: center - maxDeviation - padding,
      max: center + maxDeviation + padding
    };
  }, [baseline, history]);

  const xStep = useMemo(() => {
    if (history.length <= 1) return 0;
    return (chartWidth - CHART_HORIZONTAL_PADDING * 2) / (history.length - 1);
  }, [history.length, chartWidth]);

  const valueToY = useCallback(
    (value: number) => {
      const range = chartRange.max - chartRange.min || 1;
      return ((chartRange.max - value) / range) * CHART_HEIGHT;
    },
    [chartRange.max, chartRange.min]
  );

  const linePath = useMemo(() => {
    if (!history.length) return '';
    return history.reduce((path, point, index) => {
      const x = CHART_HORIZONTAL_PADDING + xStep * index;
      const y = valueToY(point.value);
      if (index === 0) return `M ${x} ${y}`;
      return `${path} L ${x} ${y}`;
    }, '');
  }, [history, valueToY, xStep]);

  const latestValue = history.length ? history[history.length - 1].value : null;
  const latestChange = baseline !== null && latestValue !== null ? latestValue - baseline : null;

  const dateLabels = useMemo(() => {
    if (!history.length) return [];
    const first = history[0];
    const middle = history[Math.floor(history.length / 2)];
    const last = history[history.length - 1];
    const uniqueDates = [first, middle, last].filter((item, idx, arr) => {
      if (!item) return false;
      return arr.findIndex((it) => it?.date === item.date) === idx;
    });

    return uniqueDates.map((point) => {
      const index = history.findIndex((p) => p.date === point.date);
      const positionIndex = index >= 0 ? index : 0;

      return {
        date: point.date,
        label: dayjs(point.date).format('MM.DD'),
        x: CHART_HORIZONTAL_PADDING + positionIndex * xStep
      };
    });
  }, [history, xStep]);

  const openHistory = useCallback(() => {
    setHistoryVisible(true);
  }, []);

  const closeHistory = useCallback(() => {
    setHistoryVisible(false);
  }, []);

  return (
    <>
      <HealthDataCard
        title={t('statistics.components.wristTemperature.title')}
        value={loading ? '--' : (temperature !== null && temperature !== undefined ? temperature.toFixed(1) : '--')}
        unit="°C"
        style={style}
        onPress={openHistory}
      />

      <Modal
        visible={historyVisible}
        animationType="slide"
        presentationStyle={Platform.OS === 'ios' ? 'pageSheet' : 'fullScreen'}
        onRequestClose={closeHistory}
      >
        <View style={styles.modalSafeArea}>
          <LinearGradient
            colors={['#F7F6FF', '#FFFFFF']}
            start={{ x: 0, y: 0 }}
            end={{ x: 0, y: 1 }}
            style={StyleSheet.absoluteFill}
          />
          <View style={styles.modalContainer}>
            <View style={styles.modalHeader}>
              <View>
                <Text style={styles.modalTitle}>{t('statistics.components.wristTemperature.title')}</Text>
                <Text style={styles.modalSubtitle}>{t('statistics.components.wristTemperature.last30Days')}</Text>
              </View>
              <Pressable style={styles.closeButton} onPress={closeHistory} hitSlop={10}>
                <BlurView intensity={24} tint="light" style={StyleSheet.absoluteFill} />
                <View style={styles.closeButtonInner}>
                  <Ionicons name="close" size={18} color="#111827" />
                </View>
              </Pressable>
            </View>

            {historyLoading ? (
              <Text style={styles.hintText}>{t('statistics.components.wristTemperature.syncing')}</Text>
            ) : null}

            {history.length === 0 ? (
              <View style={styles.emptyState}>
                <Text style={styles.emptyText}>{t('statistics.components.wristTemperature.noData')}</Text>
              </View>
            ) : (
              <View
                style={styles.chartCard}
                onLayout={(event) => {
                  const nextWidth = event.nativeEvent.layout.width;
                  if (nextWidth > 120 && Math.abs(nextWidth - chartWidth) > 2) {
                    setChartWidth(nextWidth);
                  }
                }}
              >
                <Svg width={chartWidth} height={CHART_HEIGHT + 36}>
                  <Defs>
                    <SvgLinearGradient id="lineFade" x1="0%" y1="0%" x2="0%" y2="100%">
                      <Stop offset="0%" stopColor="#1F2A44" stopOpacity="1" />
                      <Stop offset="100%" stopColor="#1F2A44" stopOpacity="0.78" />
                    </SvgLinearGradient>
                  </Defs>

                  <Line
                    x1={CHART_HORIZONTAL_PADDING}
                    y1={valueToY(baseline ?? 0)}
                    x2={chartWidth - CHART_HORIZONTAL_PADDING}
                    y2={valueToY(baseline ?? 0)}
                    stroke="#CBD5E1"
                    strokeDasharray="6 6"
                    strokeWidth={1.2}
                  />

                  <Path d={linePath} stroke="url(#lineFade)" strokeWidth={2.6} fill="none" strokeLinecap="round" />

                  {history.map((point, index) => {
                    const x = CHART_HORIZONTAL_PADDING + xStep * index;
                    const y = valueToY(point.value);
                    return (
                      <Circle
                        key={point.date}
                        cx={x}
                        cy={y}
                        r={5}
                        stroke="#1F2A44"
                        strokeWidth={1.6}
                        fill="#FFFFFF"
                      />
                    );
                  })}
                </Svg>
                <View style={styles.labelRow}>
                  {dateLabels.map((item) => {
                    const clampedLeft = Math.min(
                      Math.max(item.x - LABEL_ESTIMATED_WIDTH / 2, CHART_HORIZONTAL_PADDING),
                      chartWidth - CHART_HORIZONTAL_PADDING - LABEL_ESTIMATED_WIDTH
                    );
                    return (
                      <Text key={item.date} style={[styles.axisLabel, { left: clampedLeft, width: LABEL_ESTIMATED_WIDTH }]}>
                        {item.label}
                      </Text>
                    );
                  })}
                  <View style={styles.baselineLabelWrapper}>
                    <View style={styles.baselinePill}>
                      <View style={styles.baselineDot} />
                      <Text style={styles.axisHint}>{t('statistics.components.wristTemperature.baseline')}</Text>
                      {baseline !== null && (
                        <Text style={styles.axisHintValue}>
                          {baseline.toFixed(1)}
                          °C
                        </Text>
                      )}
                    </View>
                  </View>
                  {latestChange !== null && (
                    <View style={styles.deviationBadge}>
                      <Text style={styles.deviationBadgeText}>
                        {latestChange >= 0 ? '+' : ''}
                        {latestChange.toFixed(1)}°C
                      </Text>
                    </View>
                  )}
                </View>
              </View>
            )}

            <View style={styles.metricsRow}>
              <View style={styles.metric}>
                <Text style={styles.metricLabel}>{t('statistics.components.wristTemperature.average')}</Text>
                <Text style={styles.metricValue}>
                  {baseline !== null ? baseline.toFixed(1) : '--'}
                  <Text style={styles.metricUnit}>°C</Text>
                </Text>
              </View>
              <View style={styles.metric}>
                <Text style={styles.metricLabel}>{t('statistics.components.wristTemperature.latest')}</Text>
                <Text style={styles.metricValue}>
                  {latestValue !== null ? latestValue.toFixed(1) : '--'}
                  <Text style={styles.metricUnit}>°C</Text>
                </Text>
                {latestChange !== null && (
                  <Text style={styles.metricHint}>
                    {latestChange >= 0 ? '+' : ''}
                    {latestChange.toFixed(1)}°C {t('statistics.components.wristTemperature.vsBaseline')}
                  </Text>
                )}
              </View>
            </View>
          </View>
        </View>
      </Modal>
    </>
  );
};

export default WristTemperatureCard;

const styles = StyleSheet.create({
  modalSafeArea: {
    flex: 1,
    backgroundColor: '#FFFFFF',
    paddingTop: Platform.OS === 'ios' ? 10 : 0
  },
  modalContainer: {
    flex: 1,
    paddingHorizontal: 20,
    paddingTop: 22
  },
  modalHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: 14
  },
  modalTitle: {
    fontSize: 22,
    fontWeight: '700',
    color: '#1C1C28',
    fontFamily: 'AliBold'
  },
  modalSubtitle: {
    fontSize: 13,
    color: '#6B7280',
    marginTop: 4,
    fontFamily: 'AliRegular'
  },
  closeButton: {
    width: 36,
    height: 36,
    borderRadius: 18,
    backgroundColor: 'rgba(255,255,255,0.42)',
    alignItems: 'center',
    justifyContent: 'center',
    overflow: 'hidden',
    borderWidth: 0.5,
    borderColor: 'rgba(255,255,255,0.6)',
    shadowColor: '#0F172A',
    shadowOpacity: 0.08,
    shadowRadius: 8,
    shadowOffset: { width: 0, height: 4 },
    elevation: 2
  },
  closeButtonInner: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  },
  chartCard: {
    backgroundColor: '#FFFFFF',
    borderRadius: 24,
    paddingVertical: 12,
    paddingHorizontal: 12,
    shadowColor: '#000',
    shadowOpacity: 0.04,
    shadowRadius: 12,
    shadowOffset: { width: 0, height: 10 },
    elevation: 4,
    marginTop: 8,
    marginBottom: 14,
    borderWidth: 1,
    borderColor: '#F1F5F9'
  },
  labelRow: {
    marginTop: -6,
    paddingHorizontal: 12,
    height: 44,
    justifyContent: 'center'
  },
  axisLabel: {
    position: 'absolute',
    bottom: 0,
    fontSize: 11,
    color: '#94A3B8',
    fontFamily: 'AliRegular',
    textAlign: 'center'
  },
  baselineLabelWrapper: {
    position: 'absolute',
    left: 0,
    top: -4,
    flexDirection: 'row',
    alignItems: 'center'
  },
  baselinePill: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 10,
    paddingVertical: 6,
    backgroundColor: '#F1F5F9',
    borderRadius: 14,
    borderWidth: 1,
    borderColor: '#E2E8F0',
    gap: 6
  },
  baselineDot: {
    width: 8,
    height: 8,
    borderRadius: 4,
    backgroundColor: '#94A3B8'
  },
  axisHint: {
    fontSize: 12,
    color: '#6B7280',
    fontFamily: 'AliRegular'
  },
  axisHintValue: {
    fontSize: 13,
    color: '#111827',
    fontWeight: '700',
    fontFamily: 'AliBold'
  },
  deviationBadge: {
    position: 'absolute',
    right: 12,
    bottom: 2,
    backgroundColor: '#ECFEFF',
    borderRadius: 12,
    paddingHorizontal: 12,
    paddingVertical: 5,
    borderWidth: 1,
    borderColor: '#CFFAFE'
  },
  deviationBadgeText: {
    fontSize: 12,
    color: '#0EA5E9',
    fontWeight: '700',
    fontFamily: 'AliBold'
  },
  metricsRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    gap: 12,
    paddingVertical: 6
  },
  metric: {
    flex: 1,
    backgroundColor: '#F8FAFC',
    borderRadius: 18,
    padding: 14,
    borderWidth: 1,
    borderColor: '#E2E8F0'
  },
  metricLabel: {
    fontSize: 12,
    color: '#6B7280',
    marginBottom: 6,
    fontFamily: 'AliRegular'
  },
  metricValue: {
    fontSize: 20,
    color: '#111827',
    fontWeight: '700',
    fontFamily: 'AliBold'
  },
  metricUnit: {
    fontSize: 12,
    color: '#6B7280',
    marginLeft: 4,
    fontWeight: '500',
    fontFamily: 'AliRegular'
  },
  metricHint: {
    marginTop: 6,
    fontSize: 12,
    color: '#6B21A8',
    fontFamily: 'AliRegular'
  },
  emptyState: {
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 32
  },
  emptyText: {
    fontSize: 14,
    color: '#94A3B8',
    fontFamily: 'AliRegular'
  },
  hintText: {
    fontSize: 12,
    color: '#6B7280',
    marginBottom: 6,
    fontFamily: 'AliRegular'
  }
});
