import React, { useMemo, useContext, useEffect } from "react";
import { ImageStyle, StyleSheet, View, ViewStyle } from "react-native";
import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
import { MeasurementPortalContext } from "../../../MeasurmentsPortal/MeasurementsPortal";

type BorderPosition = "inside" | "outside" | "center";

interface Props {
  hasFocusableInside: (entry: ZappEntry) => boolean;
  entry: ZappEntry;
  state: CellState;
  hasTextLabels: boolean;
  style: ImageStyle | ViewStyle;
  borderPosition: BorderPosition;
  borderPaddingTop: number;
  borderPaddingRight: number;
  borderPaddingBottom: number;
  borderPaddingLeft: number;
  children: React.ReactNode;
}

const COLOR_TRANSPARENT = "transparent";

const styles = StyleSheet.create({
  container: {
    overflow: "visible",
    borderWidth: 0,
    borderColor: COLOR_TRANSPARENT,
  },
  border: {
    ...StyleSheet.absoluteFillObject,
    zIndex: 1,
  },
});

export const getBorderPadding = (
  borderPosition: BorderPosition,
  borderWidth: number
) => {
  switch (borderPosition) {
    case "inside":
      return 0;
    case "center":
      return borderWidth / 2;
    case "outside":
      return borderWidth;
    default:
      return borderWidth;
  }
};

const Border = ({
  style,
  padding,
  borderPosition,
}: {
  style: ViewStyle;
  padding: ViewStyle;
  borderPosition: BorderPosition;
}) => {
  if (!borderPosition) {
    return null;
  }

  const borderWidth = toNumberWithDefaultZero(style.borderWidth);
  const containerPadding = getBorderPadding(borderPosition, borderWidth);

  const initialBorderRadius = toNumberWithDefaultZero(style.borderRadius);
  const paddingTop = toNumberWithDefaultZero(padding.paddingTop);
  const paddingRight = toNumberWithDefaultZero(padding.paddingRight);
  const paddingBottom = toNumberWithDefaultZero(padding.paddingBottom);
  const paddingLeft = toNumberWithDefaultZero(padding.paddingLeft);

  const borderRadiusStyle = initialBorderRadius
    ? {
        borderTopLeftRadius:
          initialBorderRadius +
          containerPadding +
          Math.min(paddingTop, paddingLeft),
        borderTopRightRadius:
          initialBorderRadius +
          containerPadding +
          Math.min(paddingTop, paddingRight),
        borderBottomLeftRadius:
          initialBorderRadius +
          containerPadding +
          Math.min(paddingBottom, paddingLeft),
        borderBottomRightRadius:
          initialBorderRadius +
          containerPadding +
          Math.min(paddingBottom, paddingRight),
      }
    : {
        borderTopLeftRadius: 0,
        borderTopRightRadius: 0,
        borderBottomLeftRadius: 0,
        borderBottomRightRadius: 0,
      };

  return (
    <View
      pointerEvents="none"
      style={{
        ...styles.border,
        right: -containerPadding - paddingRight,
        bottom: -containerPadding - paddingBottom,
        left: -containerPadding - paddingLeft,
        top: -containerPadding - paddingTop,
        borderWidth,
        borderColor: style.borderColor,
        ...borderRadiusStyle,
      }}
    />
  );
};

export const BorderContainerView = (props: Props) => {
  const {
    borderPosition,
    borderPaddingTop,
    borderPaddingRight,
    borderPaddingBottom,
    borderPaddingLeft,
    style,
    children,
    hasFocusableInside,
    entry,
    state,
    hasTextLabels,
  } = props;

  const accessibilityManager = useAccessibilityManager();
  const isMeasurement = useContext(MeasurementPortalContext);

  const isImageOnlyCell = useMemo(
    () =>
      !hasFocusableInside(entry) &&
      !hasTextLabels &&
      state === "focused" &&
      !isMeasurement?.measuringInProgress,
    [
      hasFocusableInside,
      entry,
      hasTextLabels,
      state,
      isMeasurement?.measuringInProgress,
    ]
  );

  useEffect(() => {
    if (isImageOnlyCell && entry?.title) {
      accessibilityManager.addHeading(String(entry.title));
    }
  }, [isImageOnlyCell, entry?.title]);

  const padding =
    borderPosition === "outside"
      ? {
          paddingTop: borderPaddingTop,
          paddingRight: borderPaddingRight,
          paddingBottom: borderPaddingBottom,
          paddingLeft: borderPaddingLeft,
        }
      : {};

  return (
    <View pointerEvents="box-none" {...props} style={[style, styles.container]}>
      <Border style={style} padding={padding} borderPosition={borderPosition} />
      {children}
    </View>
  );
};
