import { Ionicons, MaterialCommunityIcons } from '@expo/vector-icons';
import dayjs from 'dayjs';
import 'dayjs/locale/en';
import 'dayjs/locale/zh-cn';
import { GlassView, isLiquidGlassAvailable } from 'expo-glass-effect';
import { LinearGradient } from 'expo-linear-gradient';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
  ActivityIndicator,
  Dimensions,
  Modal,
  Platform,
  Pressable,
  ScrollView,
  Share,
  StyleSheet,
  Text,
  TouchableOpacity,
  TouchableWithoutFeedback,
  View,
} from 'react-native';
import ViewShot from 'react-native-view-shot';

import { useI18n } from '@/hooks/useI18n';
import {
  HeartRateZoneStat,
  WorkoutDetailMetrics,
} from '@/services/workoutDetail';
import {
  getWorkoutTypeDisplayName,
  WorkoutActivityType,
  WorkoutData,
} from '@/utils/health';
import { Toast } from '@/utils/toast.utils';

export interface IntensityBadge {
  label: string;
  color: string;
  background: string;
}

interface WorkoutDetailModalProps {
  visible: boolean;
  onClose: () => void;
  workout: WorkoutData | null;
  metrics: WorkoutDetailMetrics | null;
  loading: boolean;
  intensityBadge?: IntensityBadge;
  monthOccurrenceText?: string;
  onRetry?: () => void;
  errorMessage?: string | null;
}

const SCREEN_HEIGHT = Dimensions.get('window').height;
const SHEET_MAX_HEIGHT = SCREEN_HEIGHT * 0.9;

const HEART_RATE_CHART_MAX_POINTS = 80;

export function WorkoutDetailModal({
  visible,
  onClose,
  workout,
  metrics,
  loading,
  intensityBadge,
  monthOccurrenceText,
  onRetry,
  errorMessage,
}: WorkoutDetailModalProps) {
  const { t, i18n } = useI18n();
  const [isMounted, setIsMounted] = useState(visible);
  const [shouldRenderChart, setShouldRenderChart] = useState(visible);
  const [showIntensityInfo, setShowIntensityInfo] = useState(false);
  const [sharing, setSharing] = useState(false);
  const shareContentRef = useRef<ViewShot | null>(null);

  const locale = useMemo(() => (i18n.language?.startsWith('en') ? 'en' : 'zh-cn'), [i18n.language]);

  useEffect(() => {
    if (visible) {
      setIsMounted(true);
      setShouldRenderChart(true);
    } else {
      setShouldRenderChart(false);
      setIsMounted(false);
      setShowIntensityInfo(false);
    }
  }, [visible]);

  const activityName = workout
    ? getWorkoutTypeDisplayName(workout.workoutActivityType as WorkoutActivityType)
    : '';
  const chartWidth = useMemo(
    () => Math.max(Dimensions.get('window').width - 96, 240),
    []
  );

  const dateInfo = useMemo(() => {
    if (!workout) {
      return { title: '', subtitle: '' };
    }

    const date = dayjs(workout.startDate || workout.endDate).locale(locale);
    if (!date.isValid()) {
      return { title: '', subtitle: '' };
    }

    return {
      title: locale === 'en' ? date.format('MMM D') : date.format('M月D日'),
      subtitle: locale === 'en'
        ? date.format('dddd, MMM D, YYYY HH:mm')
        : date.format('YYYY年M月D日 dddd HH:mm'),
    };
  }, [locale, workout]);

  const heartRateChart = useMemo(() => {
    if (!metrics?.heartRateSeries?.length) {
      return null;
    }

    const sortedSeries = metrics.heartRateSeries;
    const trimmed = trimHeartRateSeries(sortedSeries);

    const labels = trimmed.map((point, index) => {
      if (
        index === 0 ||
        index === trimmed.length - 1 ||
        index === Math.floor(trimmed.length / 2)
      ) {
        return dayjs(point.timestamp).format('HH:mm');
      }
      return '';
    });

    const data = trimmed.map((point) => Math.round(point.value));

    return {
      labels,
      data,
    };
  }, [metrics?.heartRateSeries]);

  const handleBackdropPress = () => {
    if (!loading) {
      onClose();
    }
  };

  const handleShare = useCallback(async () => {
    if (!shareContentRef.current || !workout || sharing) {
      return;
    }
    setSharing(true);
    try {
      Toast.show({
        type: 'info',
        text1: t('workoutDetail.share.generating', '正在生成分享卡片…'),
      });
      const uri = await shareContentRef.current.capture?.({
        format: 'png',
        quality: 0.95,
        snapshotContentContainer: true,
      });
      if (!uri) {
        throw new Error('share-capture-failed');
      }
      const shareTitle = t('workoutDetail.share.title', { defaultValue: activityName || t('workoutDetail.title', '锻炼详情') });
      const caloriesLabel = metrics?.calories != null
        ? `${metrics.calories} ${t('workoutDetail.metrics.caloriesUnit')}`
        : '--';
      const shareMessage = t('workoutDetail.share.message', {
        activity: activityName || t('workoutDetail.share.activityFallback', '锻炼'),
        duration: metrics?.durationLabel ?? '--',
        calories: caloriesLabel,
        date: dateInfo.subtitle,
        defaultValue: `我的${activityName || '锻炼'}：${dateInfo.subtitle}，持续${metrics?.durationLabel ?? '--'}，消耗${caloriesLabel}`,
      });

      await Share.share({
        title: shareTitle,
        message: shareMessage,
        url: Platform.OS === 'ios' ? uri : `file://${uri}`,
      });
    } catch (error) {
      console.warn('workout-detail-share-failed', error);
      Toast.error(t('workoutDetail.share.failed', '分享失败，请稍后再试'));
    } finally {
      setSharing(false);
    }
  }, [activityName, dateInfo.subtitle, metrics?.calories, metrics?.durationLabel, sharing, t, workout]);

  if (!isMounted) {
    return null;
  }

  return (
    <Modal
      transparent
      visible={visible}
      animationType='slide'
      onRequestClose={onClose}
    >
      <View style={styles.modalContainer}>
        <TouchableWithoutFeedback onPress={handleBackdropPress}>
          <View style={styles.backdrop} />
        </TouchableWithoutFeedback>

        <View style={styles.sheetContainer}>
          <LinearGradient
            colors={['#FFFFFF', '#F3F5FF']}
            start={{ x: 0, y: 0 }}
            end={{ x: 0, y: 1 }}
            style={styles.gradientBackground}
          />

          <View style={styles.handleWrapper}>
            <View style={styles.handle} />
          </View>

          <View style={styles.headerRow}>
            <TouchableOpacity onPress={onClose} style={styles.headerIconButton} disabled={loading}>
              <MaterialCommunityIcons name="chevron-down" size={26} color="#262A5D" />
            </TouchableOpacity>

            <View style={styles.headerTitleWrapper}>
              <Text style={styles.headerTitle}>{dateInfo.title}</Text>
              <Text style={styles.headerSubtitle}>{dateInfo.subtitle}</Text>
            </View>

            {isLiquidGlassAvailable() ? (
              <Pressable
                onPress={handleShare}
                disabled={loading || sharing || !workout}
                style={({ pressed }) => [
                  styles.headerIconButton,
                  styles.glassButtonWrapper,
                  pressed && styles.headerIconPressed,
                  (loading || sharing || !workout) && styles.headerIconDisabled,
                ]}
                accessibilityRole="button"
                accessibilityLabel={t('workoutDetail.share.accessibilityLabel', '分享锻炼记录')}
              >
                <GlassView glassEffectStyle="regular" tintColor="rgba(255,255,255,0.9)" isInteractive style={styles.glassButton}>
                  <View style={styles.glassButtonInner}>
                    <Ionicons name="share-outline" size={20} color="#1E2148" />
                  </View>
                </GlassView>
              </Pressable>
            ) : (
              <Pressable
                onPress={handleShare}
                disabled={loading || sharing || !workout}
                style={({ pressed }) => [
                  styles.headerIconButton,
                  styles.headerIconFallback,
                  pressed && styles.headerIconPressed,
                  (loading || sharing || !workout) && styles.headerIconDisabled,
                ]}
                accessibilityRole="button"
                accessibilityLabel={t('workoutDetail.share.accessibilityLabel', '分享锻炼记录')}
              >
                <LinearGradient
                  colors={['#EEF2FF', '#E0E7FF']}
                  start={{ x: 0, y: 0 }}
                  end={{ x: 1, y: 1 }}
                  style={styles.glassButtonInner}
                >
                  <Ionicons name="share-outline" size={20} color="#1E2148" />
                </LinearGradient>
              </Pressable>
            )}
          </View>

          <View style={styles.heroIconWrapper}>
            <MaterialCommunityIcons name="run" size={160} color="#E8EAFE" />
          </View>

          <ScrollView
            bounces={false}
            showsVerticalScrollIndicator={false}
            contentContainerStyle={styles.contentContainer}
          >
            <View style={[styles.summaryCard, loading ? styles.summaryCardLoading : null]}>
              <View style={styles.summaryHeader}>
                <Text style={styles.activityName}>{activityName}</Text>
                {intensityBadge ? (
                  <View
                    style={[
                      styles.intensityPill,
                      { backgroundColor: intensityBadge.background },
                    ]}
                  >
                    <Text style={[styles.intensityPillText, { color: intensityBadge.color }]}>
                      {intensityBadge.label}
                    </Text>
                  </View>
                ) : null}
              </View>
              <Text style={styles.summarySubtitle}>
                {dayjs(workout?.startDate || workout?.endDate)
                  .locale(locale)
                  .format(locale === 'en' ? 'dddd, MMM D, YYYY HH:mm' : 'YYYY年M月D日 dddd HH:mm')}
              </Text>

              {loading ? (
                <View style={styles.loadingBlock}>
                  <ActivityIndicator color="#5C55FF" />
                  <Text style={styles.loadingLabel}>{t('workoutDetail.loading')}</Text>
                </View>
              ) : metrics ? (
                <>
                  <View style={styles.metricsRow}>
                    <View style={styles.metricItem}>
                      <Text style={styles.metricTitle}>{t('workoutDetail.metrics.duration')}</Text>
                      <Text style={styles.metricValue}>{metrics.durationLabel}</Text>
                    </View>
                    <View style={styles.metricItem}>
                      <Text style={styles.metricTitle}>{t('workoutDetail.metrics.calories')}</Text>
                      <Text style={styles.metricValue}>
                        {metrics.calories != null ? `${metrics.calories} ${t('workoutDetail.metrics.caloriesUnit')}` : '--'}
                      </Text>
                    </View>
                  </View>
                  <View style={styles.metricsRow}>
                    <View style={styles.metricItem}>
                      <View style={styles.metricTitleRow}>
                        <Text style={styles.metricTitle}>{t('workoutDetail.metrics.intensity')}</Text>
                        <TouchableOpacity
                          onPress={() => setShowIntensityInfo(true)}
                          style={styles.metricInfoButton}
                          hitSlop={{ top: 6, bottom: 6, left: 6, right: 6 }}
                        >
                          <MaterialCommunityIcons name="information-outline" size={16} color="#7780AA" />
                        </TouchableOpacity>
                      </View>
                      <Text style={styles.metricValue}>
                        {formatMetsValue(metrics.mets)}
                      </Text>
                    </View>
                    <View style={styles.metricItem}>
                      <Text style={styles.metricTitle}>{t('workoutDetail.metrics.averageHeartRate')}</Text>
                      <Text style={styles.metricValue}>
                        {metrics.averageHeartRate != null ? `${metrics.averageHeartRate} ${t('workoutDetail.metrics.heartRateUnit')}` : '--'}
                      </Text>
                    </View>
                  </View>
                  {monthOccurrenceText ? (
                    <Text style={styles.monthOccurrenceText}>{monthOccurrenceText}</Text>
                  ) : null}
                </>
              ) : (
                <View style={styles.errorBlock}>
                  <Text style={styles.errorText}>
                    {errorMessage || t('workoutDetail.errors.loadFailed')}
                  </Text>
                  {onRetry ? (
                    <TouchableOpacity style={styles.retryButton} onPress={onRetry}>
                      <Text style={styles.retryButtonText}>{t('workoutDetail.retry')}</Text>
                    </TouchableOpacity>
                  ) : null}
                </View>
              )}
            </View>

            <View style={[styles.section, loading ? styles.sectionHeartRateLoading : null]}>
              <View style={styles.sectionHeader}>
                <Text style={styles.sectionTitle}>{t('workoutDetail.sections.heartRateRange')}</Text>
              </View>

              {loading ? (
                <View style={styles.sectionLoading}>
                  <ActivityIndicator color="#5C55FF" />
                </View>
              ) : metrics ? (
                <>
                  <View style={styles.heartRateSummaryRow}>
                    <View style={styles.heartRateStat}>
                      <Text style={styles.statLabel}>{t('workoutDetail.sections.averageHeartRate')}</Text>
                      <Text style={styles.statValue}>
                        {metrics.averageHeartRate != null ? `${metrics.averageHeartRate} ${t('workoutDetail.sections.heartRateUnit')}` : '--'}
                      </Text>
                    </View>
                    <View style={styles.heartRateStat}>
                      <Text style={styles.statLabel}>{t('workoutDetail.sections.maximumHeartRate')}</Text>
                      <Text style={styles.statValue}>
                        {metrics.maximumHeartRate != null ? `${metrics.maximumHeartRate} ${t('workoutDetail.sections.heartRateUnit')}` : '--'}
                      </Text>
                    </View>
                    <View style={styles.heartRateStat}>
                      <Text style={styles.statLabel}>{t('workoutDetail.sections.minimumHeartRate')}</Text>
                      <Text style={styles.statValue}>
                        {metrics.minimumHeartRate != null ? `${metrics.minimumHeartRate} ${t('workoutDetail.sections.heartRateUnit')}` : '--'}
                      </Text>
                    </View>
                  </View>

                  {heartRateChart ? (
                    LineChart ? (
                      <View style={styles.chartWrapper}>
                        {shouldRenderChart ? (
                          /* @ts-ignore - react-native-chart-kit types are outdated */
                          <LineChart
                            data={{
                              labels: heartRateChart.labels,
                              datasets: [
                                {
                                  data: heartRateChart.data,
                                  color: () => '#5C55FF',
                                  strokeWidth: 2,
                                },
                              ],
                            }}
                            width={chartWidth}
                            height={220}
                            fromZero={false}
                            yAxisSuffix={t('workoutDetail.sections.heartRateUnit')}
                            withInnerLines={false}
                            bezier
                            paddingRight={48}
                            chartConfig={{
                              backgroundColor: '#FFFFFF',
                              backgroundGradientFrom: '#FFFFFF',
                              backgroundGradientTo: '#FFFFFF',
                              decimalPlaces: 0,
                              color: (opacity = 1) => `rgba(92, 85, 255, ${opacity})`,
                              labelColor: (opacity = 1) => `rgba(98, 105, 138, ${opacity})`,
                              propsForDots: {
                                r: '3',
                                strokeWidth: '2',
                                stroke: '#FFFFFF',
                              },
                              fillShadowGradientFromOpacity: 0.1,
                              fillShadowGradientToOpacity: 0.02,
                            }}
                            style={styles.chartStyle}
                          />
                        ) : (
                          <View style={[styles.chartLoading, { width: chartWidth }]}>
                            <ActivityIndicator color="#5C55FF" />
                            <Text style={styles.chartLoadingText}>{t('workoutDetail.loading')}</Text>
                          </View>
                        )}
                      </View>
                    ) : (
                      <View style={styles.chartEmpty}>
                        <MaterialCommunityIcons name="chart-line-variant" size={32} color="#C5CBE2" />
                        <Text style={styles.chartEmptyText}>{t('workoutDetail.chart.unavailable')}</Text>
                      </View>
                    )
                  ) : (
                    <View style={styles.chartEmpty}>
                      <MaterialCommunityIcons name="heart-off-outline" size={32} color="#C5CBE2" />
                      <Text style={styles.chartEmptyText}>{t('workoutDetail.chart.noData')}</Text>
                    </View>
                  )}
                </>
              ) : (
                <View style={styles.sectionError}>
                  <Text style={styles.errorTextSmall}>
                    {errorMessage || t('workoutDetail.errors.noHeartRateData')}
                  </Text>
                </View>
              )}
            </View>

            <View style={[styles.section, loading ? styles.sectionZonesLoading : null]}>
              <View style={styles.sectionHeader}>
                <Text style={styles.sectionTitle}>{t('workoutDetail.sections.heartRateZones')}</Text>
              </View>

              {loading ? (
                <View style={styles.sectionLoading}>
                  <ActivityIndicator color="#5C55FF" />
                </View>
              ) : metrics ? (
                metrics.heartRateZones.map((zone) => renderHeartRateZone(zone, t))
              ) : (
                <Text style={styles.errorTextSmall}>{t('workoutDetail.errors.noZoneStats')}</Text>
              )}
            </View>

            <View style={styles.homeIndicatorSpacer} />
          </ScrollView>
        </View>

        {/* Hidden share capture renders full content height for complete screenshots */}
        <ViewShot
          ref={shareContentRef}
          style={[styles.sheetContainer, styles.shareCaptureContainer]}
          collapsable={false}
          options={{ format: 'png', quality: 0.95, snapshotContentContainer: true }}
        >
          <LinearGradient
            colors={['#FFFFFF', '#F3F5FF']}
            start={{ x: 0, y: 0 }}
            end={{ x: 0, y: 1 }}
            style={styles.gradientBackground}
          />
          <View style={styles.handleWrapper}>
            <View style={styles.handle} />
          </View>
          <View style={styles.headerRow}>
            <View style={styles.headerIconButton} />
            <View style={styles.headerTitleWrapper}>
              <Text style={styles.headerTitle}>{dateInfo.title}</Text>
              <Text style={styles.headerSubtitle}>{dateInfo.subtitle}</Text>
            </View>
            <View style={styles.headerIconButton} />
          </View>
          <View style={styles.heroIconWrapper}>
            <MaterialCommunityIcons name="run" size={160} color="#E8EAFE" />
          </View>
          <ScrollView
            bounces={false}
            showsVerticalScrollIndicator={false}
            contentContainerStyle={styles.contentContainer}
          >
            <View style={[styles.summaryCard, loading ? styles.summaryCardLoading : null]}>
              <View style={styles.summaryHeader}>
                <Text style={styles.activityName}>{activityName}</Text>
                {intensityBadge ? (
                  <View
                    style={[
                      styles.intensityPill,
                      { backgroundColor: intensityBadge.background },
                    ]}
                  >
                    <Text style={[styles.intensityPillText, { color: intensityBadge.color }]}>
                      {intensityBadge.label}
                    </Text>
                  </View>
                ) : null}
              </View>
              <Text style={styles.summarySubtitle}>
                {dayjs(workout?.startDate || workout?.endDate)
                  .locale(locale)
                  .format(locale === 'en' ? 'dddd, MMM D, YYYY HH:mm' : 'YYYY年M月D日 dddd HH:mm')}
              </Text>

              {loading ? (
                <View style={styles.loadingBlock}>
                  <ActivityIndicator color="#5C55FF" />
                  <Text style={styles.loadingLabel}>{t('workoutDetail.loading')}</Text>
                </View>
              ) : metrics ? (
                <>
                  <View style={styles.metricsRow}>
                    <View style={styles.metricItem}>
                      <Text style={styles.metricTitle}>{t('workoutDetail.metrics.duration')}</Text>
                      <Text style={styles.metricValue}>{metrics.durationLabel}</Text>
                    </View>
                    <View style={styles.metricItem}>
                      <Text style={styles.metricTitle}>{t('workoutDetail.metrics.calories')}</Text>
                      <Text style={styles.metricValue}>
                        {metrics.calories != null ? `${metrics.calories} ${t('workoutDetail.metrics.caloriesUnit')}` : '--'}
                      </Text>
                    </View>
                  </View>
                  <View style={styles.metricsRow}>
                    <View style={styles.metricItem}>
                      <View style={styles.metricTitleRow}>
                        <Text style={styles.metricTitle}>{t('workoutDetail.metrics.intensity')}</Text>
                        <View style={styles.metricInfoButton}>
                          <MaterialCommunityIcons name="information-outline" size={16} color="#7780AA" />
                        </View>
                      </View>
                      <Text style={styles.metricValue}>
                        {formatMetsValue(metrics.mets)}
                      </Text>
                    </View>
                    <View style={styles.metricItem}>
                      <Text style={styles.metricTitle}>{t('workoutDetail.metrics.averageHeartRate')}</Text>
                      <Text style={styles.metricValue}>
                        {metrics.averageHeartRate != null ? `${metrics.averageHeartRate} ${t('workoutDetail.metrics.heartRateUnit')}` : '--'}
                      </Text>
                    </View>
                  </View>
                  {monthOccurrenceText ? (
                    <Text style={styles.monthOccurrenceText}>{monthOccurrenceText}</Text>
                  ) : null}
                </>
              ) : (
                <View style={styles.errorBlock}>
                  <Text style={styles.errorText}>
                    {errorMessage || t('workoutDetail.errors.loadFailed')}
                  </Text>
                  {onRetry ? (
                    <View style={[styles.retryButton, styles.retryButtonDisabled]}>
                      <Text style={styles.retryButtonText}>{t('workoutDetail.retry')}</Text>
                    </View>
                  ) : null}
                </View>
              )}
            </View>

            <View style={[styles.section, loading ? styles.sectionHeartRateLoading : null]}>
              <View style={styles.sectionHeader}>
                <Text style={styles.sectionTitle}>{t('workoutDetail.sections.heartRateRange')}</Text>
              </View>

              {loading ? (
                <View style={styles.sectionLoading}>
                  <ActivityIndicator color="#5C55FF" />
                </View>
              ) : metrics ? (
                <>
                  <View style={styles.heartRateSummaryRow}>
                    <View style={styles.heartRateStat}>
                      <Text style={styles.statLabel}>{t('workoutDetail.sections.averageHeartRate')}</Text>
                      <Text style={styles.statValue}>
                        {metrics.averageHeartRate != null ? `${metrics.averageHeartRate} ${t('workoutDetail.sections.heartRateUnit')}` : '--'}
                      </Text>
                    </View>
                    <View style={styles.heartRateStat}>
                      <Text style={styles.statLabel}>{t('workoutDetail.sections.maximumHeartRate')}</Text>
                      <Text style={styles.statValue}>
                        {metrics.maximumHeartRate != null ? `${metrics.maximumHeartRate} ${t('workoutDetail.sections.heartRateUnit')}` : '--'}
                      </Text>
                    </View>
                    <View style={styles.heartRateStat}>
                      <Text style={styles.statLabel}>{t('workoutDetail.sections.minimumHeartRate')}</Text>
                      <Text style={styles.statValue}>
                        {metrics.minimumHeartRate != null ? `${metrics.minimumHeartRate} ${t('workoutDetail.sections.heartRateUnit')}` : '--'}
                      </Text>
                    </View>
                  </View>

                  {heartRateChart ? (
                    LineChart ? (
                      <View style={styles.chartWrapper}>
                        {shouldRenderChart ? (
                          /* @ts-ignore - react-native-chart-kit types are outdated */
                          <LineChart
                            data={{
                              labels: heartRateChart.labels,
                              datasets: [
                                {
                                  data: heartRateChart.data,
                                  color: () => '#5C55FF',
                                  strokeWidth: 2,
                                },
                              ],
                            }}
                            width={chartWidth}
                            height={220}
                            fromZero={false}
                            yAxisSuffix={t('workoutDetail.sections.heartRateUnit')}
                            withInnerLines={false}
                            bezier
                            paddingRight={48}
                            chartConfig={{
                              backgroundColor: '#FFFFFF',
                              backgroundGradientFrom: '#FFFFFF',
                              backgroundGradientTo: '#FFFFFF',
                              decimalPlaces: 0,
                              color: (opacity = 1) => `rgba(92, 85, 255, ${opacity})`,
                              labelColor: (opacity = 1) => `rgba(98, 105, 138, ${opacity})`,
                              propsForDots: {
                                r: '3',
                                strokeWidth: '2',
                                stroke: '#FFFFFF',
                              },
                              fillShadowGradientFromOpacity: 0.1,
                              fillShadowGradientToOpacity: 0.02,
                            }}
                            style={styles.chartStyle}
                          />
                        ) : (
                          <View style={[styles.chartLoading, { width: chartWidth }]}>
                            <ActivityIndicator color="#5C55FF" />
                            <Text style={styles.chartLoadingText}>{t('workoutDetail.loading')}</Text>
                          </View>
                        )}
                      </View>
                    ) : (
                      <View style={styles.chartEmpty}>
                        <MaterialCommunityIcons name="chart-line-variant" size={32} color="#C5CBE2" />
                        <Text style={styles.chartEmptyText}>{t('workoutDetail.chart.unavailable')}</Text>
                      </View>
                    )
                  ) : (
                    <View style={styles.chartEmpty}>
                      <MaterialCommunityIcons name="heart-off-outline" size={32} color="#C5CBE2" />
                      <Text style={styles.chartEmptyText}>{t('workoutDetail.chart.noData')}</Text>
                    </View>
                  )}
                </>
              ) : (
                <View style={styles.sectionError}>
                  <Text style={styles.errorTextSmall}>
                    {errorMessage || t('workoutDetail.errors.noHeartRateData')}
                  </Text>
                </View>
              )}
            </View>

            <View style={[styles.section, loading ? styles.sectionZonesLoading : null]}>
              <View style={styles.sectionHeader}>
                <Text style={styles.sectionTitle}>{t('workoutDetail.sections.heartRateZones')}</Text>
              </View>

              {loading ? (
                <View style={styles.sectionLoading}>
                  <ActivityIndicator color="#5C55FF" />
                </View>
              ) : metrics ? (
                metrics.heartRateZones.map((zone) => renderHeartRateZone(zone, t))
              ) : (
                <Text style={styles.errorTextSmall}>{t('workoutDetail.errors.noZoneStats')}</Text>
              )}
            </View>

            <View style={styles.homeIndicatorSpacer} />
          </ScrollView>
        </ViewShot>

        {showIntensityInfo ? (
          <Modal
            transparent
            visible={showIntensityInfo}
            animationType="fade"
            onRequestClose={() => setShowIntensityInfo(false)}
          >
            <TouchableWithoutFeedback onPress={() => setShowIntensityInfo(false)}>
              <View style={styles.infoBackdrop}>
                <TouchableWithoutFeedback onPress={() => { }}>
                  <View style={styles.intensityInfoSheet}>
                    <View style={styles.intensityHandle} />
                    <Text style={styles.intensityInfoTitle}>{t('workoutDetail.intensityInfo.title')}</Text>
                    <Text style={styles.intensityInfoText}>
                      {t('workoutDetail.intensityInfo.description1')}
                    </Text>
                    <Text style={styles.intensityInfoText}>
                      {t('workoutDetail.intensityInfo.description2')}
                    </Text>
                    <Text style={styles.intensityInfoText}>
                      {t('workoutDetail.intensityInfo.description3')}
                    </Text>
                    <Text style={styles.intensityInfoText}>
                      {t('workoutDetail.intensityInfo.description4')}
                    </Text>
                    <View style={styles.intensityFormula}>
                      <Text style={styles.intensityFormulaLabel}>{t('workoutDetail.intensityInfo.formula.title')}</Text>
                      <Text style={styles.intensityFormulaValue}>{t('workoutDetail.intensityInfo.formula.value')}</Text>
                    </View>

                    <View style={styles.intensityLegend}>
                      <View style={styles.intensityLegendRow}>
                        <Text style={styles.intensityLegendRange}>{t('workoutDetail.intensityInfo.legend.low')}</Text>
                        <Text style={[styles.intensityLegendLabel, styles.intensityLow]}>{t('workoutDetail.intensityInfo.legend.lowLabel')}</Text>
                      </View>
                      <View style={styles.intensityLegendRow}>
                        <Text style={styles.intensityLegendRange}>{t('workoutDetail.intensityInfo.legend.medium')}</Text>
                        <Text style={[styles.intensityLegendLabel, styles.intensityMedium]}>{t('workoutDetail.intensityInfo.legend.mediumLabel')}</Text>
                      </View>
                      <View style={styles.intensityLegendRow}>
                        <Text style={styles.intensityLegendRange}>{t('workoutDetail.intensityInfo.legend.high')}</Text>
                        <Text style={[styles.intensityLegendLabel, styles.intensityHigh]}>{t('workoutDetail.intensityInfo.legend.highLabel')}</Text>
                      </View>
                    </View>
                  </View>
                </TouchableWithoutFeedback>
              </View>
            </TouchableWithoutFeedback>
          </Modal>
        ) : null}
      </View>
    </Modal>
  );
}

// 格式化 METs 值显示
function formatMetsValue(mets: number | null): string {
  if (mets == null) {
    return '—';
  }

  // 保留一位小数
  const formattedMets = mets.toFixed(1);
  return `${formattedMets} METs`;
}

function trimHeartRateSeries(series: WorkoutDetailMetrics['heartRateSeries']) {
  if (series.length <= HEART_RATE_CHART_MAX_POINTS) {
    return series;
  }

  // 智能采样算法：保留重要特征点（峰值、谷值、变化率大的点）
  const result: typeof series = [];
  const n = series.length;

  // 总是保留第一个和最后一个点
  result.push(series[0]);

  // 计算心率变化率
  const changeRates: number[] = [];
  for (let i = 1; i < n; i++) {
    const prevValue = series[i - 1].value;
    const currValue = series[i].value;
    const prevTime = dayjs(series[i - 1].timestamp).valueOf();
    const currTime = dayjs(series[i].timestamp).valueOf();
    const timeDiff = Math.max(currTime - prevTime, 1000); // 至少1秒，避免除零
    const valueDiff = Math.abs(currValue - prevValue);
    changeRates.push(valueDiff / timeDiff * 1000); // 变化率：每秒变化量
  }

  // 计算变化率的阈值（前75%的分位数）
  const sortedRates = [...changeRates].sort((a, b) => a - b);
  const thresholdIndex = Math.floor(sortedRates.length * 0.75);
  const changeThreshold = sortedRates[thresholdIndex] || 0;

  // 识别局部极值点
  const isLocalExtremum = (index: number): boolean => {
    if (index === 0 || index === n - 1) return false;

    const prev = series[index - 1].value;
    const curr = series[index].value;
    const next = series[index + 1].value;

    // 局部最大值
    if (curr > prev && curr > next) return true;
    // 局部最小值
    if (curr < prev && curr < next) return true;

    return false;
  };

  // 遍历所有点，选择重要点
  let minDistance = Math.max(1, Math.floor(n / HEART_RATE_CHART_MAX_POINTS));
  let lastSelectedIndex = 0;

  for (let i = 1; i < n - 1; i++) {
    const shouldKeep =
      // 1. 是局部极值点
      isLocalExtremum(i) ||
      // 2. 变化率超过阈值
      (i > 0 && changeRates[i - 1] > changeThreshold) ||
      // 3. 均匀分布的点（确保基本覆盖）
      (i % minDistance === 0);

    if (shouldKeep) {
      // 检查与上一个选中点的距离，避免过于密集
      if (i - lastSelectedIndex >= minDistance || isLocalExtremum(i)) {
        result.push(series[i]);
        lastSelectedIndex = i;
      }
    }
  }

  // 确保最后一个点被包含
  if (result[result.length - 1].timestamp !== series[n - 1].timestamp) {
    result.push(series[n - 1]);
  }

  // 如果结果仍然太多，进行二次采样
  if (result.length > HEART_RATE_CHART_MAX_POINTS) {
    const finalStep = Math.ceil(result.length / HEART_RATE_CHART_MAX_POINTS);
    const finalResult = result.filter((_, index) => index % finalStep === 0);

    // 确保最后一个点被包含
    if (finalResult[finalResult.length - 1] !== result[result.length - 1]) {
      finalResult.push(result[result.length - 1]);
    }

    return finalResult;
  }

  return result;
}

function renderHeartRateZone(
  zone: HeartRateZoneStat,
  t: (key: string, options?: Record<string, any>) => string
) {
  const label = t(`workoutDetail.zones.labels.${zone.key}`, {
    defaultValue: zone.label,
  });
  const range = t(`workoutDetail.zones.ranges.${zone.key}`, {
    defaultValue: zone.rangeText,
  });
  const meta = t('workoutDetail.zones.summary', {
    minutes: zone.durationMinutes,
    range,
  });

  return (
    <View key={zone.key} style={styles.zoneRow}>
      <View style={[styles.zoneBar, { backgroundColor: `${zone.color}33` }]}>
        <View
          style={[
            styles.zoneBarFill,
            {
              width: `${Math.min(zone.percentage, 100)}%`,
              backgroundColor: zone.color,
            },
          ]}
        />
      </View>
      <View style={styles.zoneInfo}>
        <Text style={styles.zoneLabel}>{label}</Text>
        <Text style={styles.zoneMeta}>{meta}</Text>
      </View>
    </View>
  );
}

// Lazy import to avoid circular dependency
let LineChart: any;

try {
  // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
  LineChart = require('react-native-chart-kit').LineChart;
} catch (error) {
  console.warn('未安装 react-native-chart-kit，心率图表将不会显示:', error);
}

const styles = StyleSheet.create({
  modalContainer: {
    flex: 1,
    justifyContent: 'flex-end',
    backgroundColor: 'transparent',
  },
  backdrop: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: '#10122599',
  },
  sheetContainer: {
    maxHeight: SHEET_MAX_HEIGHT,
    backgroundColor: '#FFFFFF',
    borderTopLeftRadius: 32,
    borderTopRightRadius: 32,
    overflow: 'hidden',
  },
  gradientBackground: {
    ...StyleSheet.absoluteFillObject,
  },
  handleWrapper: {
    alignItems: 'center',
    paddingTop: 16,
    paddingBottom: 8,
  },
  handle: {
    width: 42,
    height: 5,
    borderRadius: 3,
    backgroundColor: '#D5D9EB',
  },
  headerRow: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 20,
    paddingBottom: 12,
  },
  headerIconButton: {
    width: 40,
    height: 40,
    borderRadius: 20,
    justifyContent: 'center',
    alignItems: 'center',
  },
  headerIconFallback: {
    overflow: 'hidden',
  },
  headerIconPressed: {
    opacity: 0.75,
  },
  headerIconDisabled: {
    opacity: 0.4,
  },
  glassButtonWrapper: {
    overflow: 'hidden',
  },
  glassButton: {
    borderRadius: 20,
    width: '100%',
    height: '100%',
  },
  glassButtonInner: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    width: '100%',
    height: '100%',
    borderRadius: 20,
  },
  shareCaptureContainer: {
    position: 'absolute',
    top: -9999,
    left: 0,
    right: 0,
    opacity: 0,
    zIndex: -1,
  },
  headerTitleWrapper: {
    flex: 1,
    alignItems: 'center',
  },
  headerTitle: {
    fontSize: 20,
    fontWeight: '700',
    color: '#1E2148',
  },
  headerSubtitle: {
    marginTop: 4,
    fontSize: 12,
    color: '#7E86A7',
  },
  heroIconWrapper: {
    position: 'absolute',
    right: -20,
    top: 60,
  },
  contentContainer: {
    paddingBottom: 40,
    paddingHorizontal: 24,
    paddingTop: 8,
  },
  summaryCard: {
    backgroundColor: '#FFFFFF',
    borderRadius: 28,
    padding: 20,
    marginBottom: 22,
    shadowColor: '#646CFF33',
    shadowOffset: { width: 0, height: 10 },
    shadowOpacity: 0.18,
    shadowRadius: 22,
    elevation: 8,
  },
  summaryCardLoading: {
    minHeight: 240,
  },
  summaryHeader: {
    flexDirection: 'row',
    alignItems: 'flex-start',
    flexWrap: 'wrap',
    gap: 10,
  },
  activityName: {
    fontSize: 24,
    fontWeight: '700',
    color: '#1E2148',
    flex: 1,
    flexShrink: 1,
    lineHeight: 30,
  },
  intensityPill: {
    paddingHorizontal: 12,
    paddingVertical: 4,
    borderRadius: 999,
    alignSelf: 'flex-start',
  },
  intensityPillText: {
    fontSize: 12,
    fontWeight: '600',
  },
  summarySubtitle: {
    marginTop: 8,
    fontSize: 13,
    color: '#848BA9',
  },
  metricsRow: {
    flexDirection: 'row',
    marginTop: 20,
    gap: 12,
  },
  metricItem: {
    flex: 1,
    borderRadius: 18,
    backgroundColor: '#F5F6FF',
    paddingVertical: 14,
    paddingHorizontal: 12,
  },
  metricTitle: {
    fontSize: 12,
    color: '#7A81A3',
    marginBottom: 6,
  },
  metricTitleRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 4,
    marginBottom: 6,
  },
  metricInfoButton: {
    padding: 2,
  },
  metricValue: {
    fontSize: 18,
    fontWeight: '700',
    color: '#1E2148',
  },
  monthOccurrenceText: {
    marginTop: 16,
    fontSize: 13,
    color: '#4B4F75',
  },
  loadingBlock: {
    marginTop: 32,
    alignItems: 'center',
    gap: 10,
  },
  loadingLabel: {
    fontSize: 13,
    color: '#7E86A7',
  },
  errorBlock: {
    marginTop: 24,
    alignItems: 'center',
    gap: 12,
  },
  errorText: {
    fontSize: 13,
    color: '#F65858',
  },
  retryButton: {
    paddingHorizontal: 18,
    paddingVertical: 8,
    backgroundColor: '#5C55FF',
    borderRadius: 16,
  },
  retryButtonDisabled: {
    opacity: 0.4,
  },
  retryButtonText: {
    color: '#FFFFFF',
    fontWeight: '600',
    fontSize: 13,
  },
  section: {
    backgroundColor: '#FFFFFF',
    borderRadius: 24,
    padding: 20,
    marginBottom: 20,
    shadowColor: '#10122514',
    shadowOffset: { width: 0, height: 12 },
    shadowOpacity: 0.08,
    shadowRadius: 20,
    elevation: 4,
  },
  sectionHeartRateLoading: {
    minHeight: 360,
  },
  sectionZonesLoading: {
    minHeight: 200,
  },
  sectionHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
    marginBottom: 16,
  },
  sectionTitle: {
    fontSize: 18,
    fontWeight: '700',
    color: '#1E2148',
  },
  sectionLoading: {
    paddingVertical: 40,
    alignItems: 'center',
  },
  sectionError: {
    alignItems: 'center',
    paddingVertical: 18,
  },
  errorTextSmall: {
    fontSize: 12,
    color: '#7E86A7',
  },
  heartRateSummaryRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 18,
  },
  heartRateStat: {
    flex: 1,
    alignItems: 'center',
  },
  statLabel: {
    fontSize: 12,
    color: '#7E86A7',
    marginBottom: 4,
  },
  statValue: {
    fontSize: 18,
    fontWeight: '700',
    color: '#1E2148',
  },
  chartWrapper: {
    alignItems: 'flex-start',
    overflow: 'visible',
  },
  chartLoading: {
    height: 220,
    alignItems: 'center',
    justifyContent: 'center',
  },
  chartLoadingText: {
    marginTop: 8,
    fontSize: 12,
    color: '#7E86A7',
  },
  chartStyle: {
    marginLeft: 0,
    marginRight: 0,
  },
  chartEmpty: {
    paddingVertical: 32,
    alignItems: 'center',
    gap: 8,
  },
  chartEmptyText: {
    fontSize: 13,
    color: '#9CA3C6',
  },
  zoneRow: {
    flexDirection: 'row',
    alignItems: 'center',
    marginBottom: 14,
    gap: 12,
  },
  zoneBar: {
    width: 110,
    height: 12,
    borderRadius: 999,
    overflow: 'hidden',
  },
  zoneBarFill: {
    height: '100%',
    borderRadius: 999,
  },
  zoneInfo: {
    flex: 1,
  },
  zoneLabel: {
    fontSize: 14,
    fontWeight: '600',
    color: '#1E2148',
  },
  zoneMeta: {
    marginTop: 4,
    fontSize: 12,
    color: '#7E86A7',
  },
  homeIndicatorSpacer: {
    height: 28,
  },
  infoBackdrop: {
    flex: 1,
    backgroundColor: '#0F122080',
    justifyContent: 'flex-end',
  },
  intensityInfoSheet: {
    margin: 20,
    marginBottom: 34,
    backgroundColor: '#FFFFFF',
    borderRadius: 28,
    paddingHorizontal: 24,
    paddingTop: 20,
    paddingBottom: 28,
    shadowColor: '#1F265933',
    shadowOffset: { width: 0, height: 16 },
    shadowOpacity: 0.25,
    shadowRadius: 24,
  },
  intensityHandle: {
    alignSelf: 'center',
    width: 44,
    height: 4,
    borderRadius: 999,
    backgroundColor: '#E1E4F3',
    marginBottom: 16,
  },
  intensityInfoTitle: {
    fontSize: 20,
    fontWeight: '700',
    color: '#1E2148',
    marginBottom: 12,
  },
  intensityInfoText: {
    fontSize: 13,
    color: '#4C5074',
    lineHeight: 20,
    marginBottom: 10,
  },
  intensityFormula: {
    marginTop: 12,
    marginBottom: 18,
    backgroundColor: '#F4F6FE',
    borderRadius: 18,
    paddingVertical: 14,
    paddingHorizontal: 16,
  },
  intensityFormulaLabel: {
    fontSize: 12,
    color: '#7E86A7',
    marginBottom: 6,
  },
  intensityFormulaValue: {
    fontSize: 14,
    fontWeight: '600',
    color: '#1F2355',
    lineHeight: 20,
  },
  intensityLegend: {
    borderTopWidth: StyleSheet.hairlineWidth,
    borderTopColor: '#E3E6F4',
    paddingTop: 16,
    gap: 14,
  },
  intensityLegendRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  intensityLegendRange: {
    fontSize: 16,
    fontWeight: '600',
    color: '#1E2148',
  },
  intensityLegendLabel: {
    fontSize: 14,
    fontWeight: '600',
  },
  intensityLow: {
    color: '#5C84FF',
  },
  intensityMedium: {
    color: '#2CCAA0',
  },
  intensityHigh: {
    color: '#FF6767',
  },
});
