import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {Pressable, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import Animated, {
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';
import i18next from 'i18next';
import {isSameDay} from 'date-fns';
import {IconCalendarEvent, IconChevronDown} from '@tabler/icons-react-native';
import {Typography} from '@components';
import useGetMeasurements from '@hooks/useGetMeasurements';
import {
  getDataFromEntries,
  getFormattedScheduledTime,
} from '@modules/timeTracking/utils';
import {DaySummary, ScheduleSource} from '@modules/timeTracking/interfaces';
import Clock from '@modules/timeTracking/components/Clock';
import DescriptionDialog, {
  DescriptionConfig,
} from '@modules/timeTracking/components/DescriptionDialog';
import {getPolicyIcon} from '@modules/timeOff/utils';
import {parse} from '@shared/utils';
import {useTheme} from '@shared/theme';
import {TO_SECONDS} from '@shared/constants';

import DaySummaryItemDetail from './components/DaySummaryItemDetail';
import {styles} from './styles';

interface Props {
  daySummary: DaySummary;
  onPress: () => void;
  isOpened: boolean;
}

function DaySummaryItem({
  daySummary: {
    dateString,
    estimatedHours,
    holidays,
    isWorkday,
    scheduleSource,
    timeOffRequests,
    timeSlots,
    timeTrackingEntries,
    workedHours,
  },
  onPress,
  isOpened,
}: Props) {
  const {iconSizes, theme} = useTheme();
  const {t} = useTranslation();
  const [onLayout, measurements] = useGetMeasurements();
  const animatedValue = useSharedValue(0);
  const [descriptionConfig, setDescriptionConfig] =
    useState<DescriptionConfig>(null);
  const hasWorkSchedule = scheduleSource !== ScheduleSource.NO_SCHEDULE;
  const isFreeDay = hasWorkSchedule && !isWorkday;
  const holiday = holidays?.[0];
  const timeOffRequest = timeOffRequests?.[0];
  const TimeOffPolicyIcon = timeOffRequest
    ? getPolicyIcon(timeOffRequest.timeOffPolicyTypeIcon)
    : null;
  const scheduledSeconds = isFreeDay ? 0 : estimatedHours * TO_SECONDS;

  useEffect(() => {
    animatedValue.value = withTiming(isOpened ? 1 : 0, {duration: 300});
  }, [animatedValue, isOpened]);

  const containerStyle = useAnimatedStyle(() => ({
    height: measurements.height * animatedValue.value,
  }));

  const arrowStyle = useAnimatedStyle(() => ({
    transform: [{rotateZ: `${animatedValue.value * 180}deg`}],
  }));

  const date = useMemo(
    () => parse(dateString, 'yyyy-MM-dd', new Date()),
    [dateString],
  );
  const isToday = isSameDay(date, new Date());
  const dateTextColor = isToday
    ? theme.text.neutral.brand
    : theme.text.neutral.default;

  const labelData = useMemo(() => {
    const weekDay = date
      .toLocaleString(i18next.language, {weekday: 'short'})
      .toUpperCase();
    const twoDigitDay = date
      .toLocaleString(i18next.language, {day: '2-digit'})
      .toUpperCase();
    return {weekDay, day: twoDigitDay};
  }, [date]);

  const {currentRegister, totalSeconds, workedSeconds} = useMemo(
    () => getDataFromEntries(timeTrackingEntries, workedHours),
    [timeTrackingEntries, workedHours],
  );

  const excessTime = useMemo(
    () => Math.max(totalSeconds - scheduledSeconds, 0),
    [totalSeconds, scheduledSeconds],
  );

  const onOpenFreeDayDialog = useCallback(() => {
    setDescriptionConfig({
      title: t('time_tracker.free_day'),
      description: `${t('time_tracker.free_day_description')}\n\n${t(
        'time_tracker.extra_time_hint',
      )}`,
    });
  }, [t]);

  const onCloseDescriptionDialog = useCallback(() => {
    setDescriptionConfig(null);
  }, []);

  return (
    <View>
      <Pressable style={styles.itemContainer} onPress={onPress}>
        <View
          style={[
            styles.dateContainer,
            {
              backgroundColor: isToday
                ? theme.background.layout.brand
                : theme.background.layout.tertiary,
              borderColor: theme.border.neutral.default,
            },
          ]}>
          <Typography color={dateTextColor} variant="xxs" weight="semiBold">
            {labelData.weekDay}
          </Typography>
          <Typography color={dateTextColor} variant="m" weight="semiBold">
            {labelData.day}
          </Typography>
        </View>
        <View style={styles.descriptorContainer}>
          <View>
            <Clock
              accumulatedSeconds={workedSeconds}
              currentRegisterStartTime={currentRegister?.time || null}
              excessTime={hasWorkSchedule || isFreeDay ? excessTime : null}
              isActive={!!currentRegister}
              variant="m"
            />
            <Typography color={theme.text.neutral.lighter} variant="xs">
              {isFreeDay
                ? t('time_tracker.free_day')
                : getFormattedScheduledTime(scheduledSeconds)}
            </Typography>
          </View>
          <View style={styles.iconsContainer}>
            {holiday ? (
              <IconCalendarEvent
                color={theme.text.neutral.default}
                size={iconSizes.x5}
              />
            ) : TimeOffPolicyIcon ? (
              <TimeOffPolicyIcon
                color={theme.text.neutral.default}
                size={iconSizes.x5}
              />
            ) : null}
            <Animated.View style={[styles.arrowAnimatedContainer, arrowStyle]}>
              <IconChevronDown
                color={theme.text.neutral.lighter}
                size={iconSizes.x5}
              />
            </Animated.View>
          </View>
        </View>
      </Pressable>
      <Animated.View
        style={[containerStyle, styles.detailViewAnimatedContainer]}>
        <DaySummaryItemDetail
          isFreeDay={isFreeDay}
          holiday={holiday}
          onOpenFreeDayDialog={onOpenFreeDayDialog}
          timeOffRequest={timeOffRequest}
          timeTrackingEntries={timeTrackingEntries}
          timeSlots={timeSlots}
        />
      </Animated.View>
      {!measurements.height && (
        <View onLayout={onLayout} style={styles.hiddenDetailViewContainer}>
          <DaySummaryItemDetail
            isFreeDay={isFreeDay}
            holiday={holiday}
            onOpenFreeDayDialog={onOpenFreeDayDialog}
            timeOffRequest={timeOffRequest}
            timeTrackingEntries={timeTrackingEntries}
            timeSlots={timeSlots}
          />
        </View>
      )}
      <DescriptionDialog
        descriptionConfig={descriptionConfig}
        onClose={onCloseDescriptionDialog}
      />
    </View>
  );
}

export default DaySummaryItem;
