import { Text } from '@/aesthetics/Text';
import { font, getScoreColor, radius, spacing, useColors, weight } from '@/aesthetics/styles';
import { useStrings } from '@/common/hooks/useStrings';
import { isSameDay } from '@/common/utils/format';
import type { Strings } from '@/common/strings';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { Pressable, ScrollView, StyleSheet, View, useWindowDimensions } from 'react-native';
import type { DayScore } from './useNutritionView';

const getDayName = (dayIndex: number, time: Strings['time']) => {
  const days = [
    time.days.sun,
    time.days.mon,
    time.days.tue,
    time.days.wed,
    time.days.thu,
    time.days.fri,
    time.days.sat,
  ];
  return days[dayIndex];
};

const getMonthName = (monthIndex: number, time: Strings['time']) => {
  const months = [
    time.months.january,
    time.months.february,
    time.months.march,
    time.months.april,
    time.months.may,
    time.months.june,
    time.months.july,
    time.months.august,
    time.months.september,
    time.months.october,
    time.months.november,
    time.months.december,
  ];
  return months[monthIndex];
};

const BAR_BASE_HEIGHT = 24;
const BAR_SCORE_HEIGHT = 16;
const BAR_WIDTH = 28;

function DayBar({
  day,
  isSelected,
  isToday,
  isFuture,
  onPress,
}: {
  day: DayScore;
  isSelected: boolean;
  isToday: boolean;
  isFuture: boolean;
  onPress: () => void;
}) {
  const c = useColors();
  const scoreHeight = (day.score / 100) * BAR_SCORE_HEIGHT;
  const totalHeight = BAR_BASE_HEIGHT + scoreHeight;

  const barColor = isFuture
    ? c.borderSubtle
    : day.score === 0
      ? c.progressBg
      : getScoreColor(day.score, c);

  return (
    <Pressable onPress={onPress} style={styles.barWrapper}>
      {isToday && <View style={[styles.todayDot, { backgroundColor: c.accent }]} />}
      <View style={[styles.barOuter, isSelected && { backgroundColor: c.accentSubtle }]}>
        <View style={[styles.bar, { height: totalHeight, backgroundColor: barColor }]} />
      </View>
    </Pressable>
  );
}

type DayBarScrollProps = {
  date: Date;
  dayScores: DayScore[];
  onSelectDate: (date: Date) => void;
  onLoadMore: () => void;
};

export function DayBarScroll({ date, dayScores, onSelectDate, onLoadMore }: DayBarScrollProps) {
  const c = useColors();
  const strings = useStrings();
  const { width: screenWidth } = useWindowDimensions();
  const barPadding = (screenWidth - BAR_WIDTH) / 2;
  const scrollRef = useRef<ScrollView>(null);
  const today = useMemo(() => new Date(), []);
  const lastSelectedIndex = useRef(-1);
  const initialScrollDone = useRef(false);

  const scrollToIndex = useCallback((index: number, animated = true) => {
    scrollRef.current?.scrollTo({ x: index * BAR_WIDTH, animated });
  }, []);

  useEffect(() => {
    if (initialScrollDone.current || dayScores.length === 0) return;
    const todayIndex = dayScores.findIndex(d => isSameDay(d.date, today));
    if (todayIndex >= 0) {
      const timer = setTimeout(() => {
        scrollRef.current?.scrollTo({ x: todayIndex * BAR_WIDTH, animated: false });
        lastSelectedIndex.current = todayIndex;
        initialScrollDone.current = true;
      }, 50);
      return () => clearTimeout(timer);
    }
  }, [dayScores, today]);

  const handleBarPress = useCallback((index: number) => scrollToIndex(index), [scrollToIndex]);

  const handleScroll = useCallback(
    (offsetX: number) => {
      const index = Math.round(offsetX / BAR_WIDTH);
      if (index >= 0 && index < dayScores.length && index !== lastSelectedIndex.current) {
        lastSelectedIndex.current = index;
        onSelectDate(dayScores[index].date);
      }
    },
    [dayScores, onSelectDate]
  );

  return (
    <View style={styles.container}>
      <View style={styles.dateDisplay}>
        <Text style={[styles.dateYear, { color: c.tertiaryText }]}>{date.getFullYear()}</Text>
        <Text style={[styles.dateMonth, { color: c.secondaryText }]}>
          {getMonthName(date.getMonth(), strings.time)}
        </Text>
        <View style={styles.dateDayRow}>
          <Text style={[styles.dateDayNum, { color: c.text, fontWeight: weight.semibold }]}>
            {date.getDate()}
          </Text>
          <Text style={[styles.dateDayName, { color: c.tertiaryText }]}>
            {getDayName(date.getDay(), strings.time)}
          </Text>
        </View>
      </View>

      <ScrollView
        ref={scrollRef}
        horizontal
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={[styles.barScroll, { paddingHorizontal: barPadding }]}
        style={styles.barScrollView}
        snapToInterval={BAR_WIDTH}
        decelerationRate="fast"
        onScroll={({ nativeEvent }) => {
          const { contentOffset, contentSize, layoutMeasurement } = nativeEvent;
          handleScroll(contentOffset.x);
          if (contentOffset.x + layoutMeasurement.width >= contentSize.width - 50) {
            onLoadMore();
          }
        }}
        scrollEventThrottle={16}
      >
        {dayScores.map((day, i) => (
          <DayBar
            key={i}
            day={day}
            isSelected={isSameDay(day.date, date)}
            isToday={isSameDay(day.date, today)}
            isFuture={day.date > today}
            onPress={() => handleBarPress(i)}
          />
        ))}
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    paddingTop: spacing.sm,
    paddingBottom: spacing.lg,
    marginBottom: spacing.sm,
  },
  dateDisplay: {
    alignItems: 'center',
    marginBottom: spacing.lg,
  },
  dateYear: {
    fontSize: font.sm,
    letterSpacing: 1,
    textTransform: 'uppercase',
  },
  dateMonth: {
    fontSize: font.sm,
    fontWeight: weight.medium,
    marginTop: 2,
  },
  dateDayRow: {
    alignItems: 'center',
    marginTop: spacing.xs,
  },
  dateDayNum: {
    fontSize: font.display,
    letterSpacing: -1,
  },
  dateDayName: {
    fontSize: font.sm,
    textTransform: 'uppercase',
    letterSpacing: 2,
    marginTop: 2,
  },
  barScrollView: {
    width: '100%',
  },
  barScroll: {
    alignItems: 'flex-end',
  },
  barWrapper: {
    width: BAR_WIDTH,
    alignItems: 'center',
    justifyContent: 'flex-end',
  },
  barOuter: {
    padding: 4,
    borderRadius: radius.sm,
  },
  bar: {
    width: 8,
    borderRadius: radius.pill,
  },
  todayDot: {
    width: 4,
    height: 4,
    borderRadius: 2,
    marginBottom: 4,
  },
});
