import * as React from 'react';
import type { StyleProp, TextStyle, ViewProps } from 'react-native';
import { StyleSheet } from 'react-native';
import Animated, {
  useAnimatedStyle,
  useDerivedValue,
  useSharedValue,
} from 'react-native-reanimated';

import { CandlestickChartDimensionsContext } from './Chart';
import { useCandlestickChart } from './useCandlestickChart';
import {
  CandlestickChartPriceText,
  CandlestickChartPriceTextProps,
} from './PriceText';

export type CandlestickChartCrosshairTooltipProps = ViewProps & {
  children?: React.ReactNode;
  xGutter?: number;
  yGutter?: number;
  tooltipTextProps?: CandlestickChartPriceTextProps;
  textStyle?: Animated.AnimateStyle<StyleProp<TextStyle>>;
};

export type CandlestickChartCrosshairTooltipContext = {
  position: Animated.SharedValue<'left' | 'right'>;
};

export const CandlestickChartCrosshairTooltipContext =
  React.createContext<CandlestickChartCrosshairTooltipContext>({
    position: { value: 'left' },
  });

export function CandlestickChartCrosshairTooltip({
  children,
  xGutter = 8,
  yGutter = 8,
  tooltipTextProps,
  textStyle,
  ...props
}: CandlestickChartCrosshairTooltipProps) {
  const { width, height } = React.useContext(CandlestickChartDimensionsContext);
  const { currentY } = useCandlestickChart();
  const { position } = React.useContext(
    CandlestickChartCrosshairTooltipContext
  );

  const elementHeight = useSharedValue(0);
  const elementWidth = useSharedValue(0);

  const handleLayout = React.useCallback(
    (event) => {
      elementHeight.value = event.nativeEvent.layout.height;
      elementWidth.value = event.nativeEvent.layout.width;
    },
    [elementHeight, elementWidth]
  );

  const topOffset = useDerivedValue(() => {
    let offset = 0;
    if (currentY.value < elementHeight.value / 2 + yGutter) {
      offset = currentY.value - (elementHeight.value / 2 + yGutter);
    } else if (currentY.value + elementHeight.value / 2 > height - yGutter) {
      offset = currentY.value + elementHeight.value / 2 - height + yGutter;
    }

    return offset;
  });

  const tooltip = useAnimatedStyle(() => ({
    backgroundColor: 'white',
    position: 'absolute',
    display: 'flex',
    padding: 4,
  }));
  const leftTooltip = useAnimatedStyle(() => ({
    left: xGutter,
    top: -(elementHeight.value / 2) - topOffset.value,
    opacity: position.value === 'left' ? 1 : 0,
  }));
  const rightTooltip = useAnimatedStyle(() => ({
    left: width - elementWidth.value - xGutter,
    top: -(elementHeight.value / 2) - topOffset.value,
    opacity: position.value === 'right' ? 1 : 0,
  }));

  return (
    <>
      <Animated.View
        onLayout={handleLayout}
        {...props}
        style={[tooltip, leftTooltip, props.style]}
      >
        {children || (
          <CandlestickChartPriceText
            {...tooltipTextProps}
            style={[styles.text, tooltipTextProps?.style, textStyle]}
          />
        )}
      </Animated.View>
      <Animated.View {...props} style={[tooltip, rightTooltip, props.style]}>
        {children || (
          <CandlestickChartPriceText
            {...tooltipTextProps}
            style={[styles.text, tooltipTextProps?.style, textStyle]}
          />
        )}
      </Animated.View>
    </>
  );
}

const styles = StyleSheet.create({
  text: {
    fontSize: 14,
  },
});