/* eslint-disable max-lines */

import * as LabelPrimitive from "@radix-ui/react-label";
import { css, customScrollbars, styled } from "../../theme";
import { pxToRem } from "../../utils";
import { Text, typographyVariants } from "../text";
import { Flex } from "../flex";
import { Box } from "../box";
import { INPUT_PADDING, TEXTAREA_DEFAULT_HEIGHT, TEXTAREA_MAX_HEIGHT } from "./consts";
import type { CSS } from "../../theme";
import type { SpaceTokenKey } from "../../theme/spacings";

const placeholderMgmt = {
  "&::placeholder": {
    color: "transparent",
    transition: "color 200ms cubic-bezier(0, 0, 0.2, 1)",
  },

  "&:focus": {
    "&::placeholder": {
      color: "$off-white-72",
    },
  },
};

const FIELDSET_BORDER_WIDTH = pxToRem(1);
const FIELDSET_BORDER_WIDTH_FOCUS = pxToRem(2);

/**
 * Extra space the element is pushed down, then lifted back up.
 * This is part of a workaround for Safari bug when it thinks there are things rendered on the right to the input
 * (fieldset and label are causing this) and this is causing horizontal scrolling.
 * A solution was to apply overflow, but that is cutting the top of the container too (and the raised label is rendered
 * with some px above the container). The solution is to push the contents down and lift back up the parent element
 * of the element that has overflow.
 *
 * If the workaround is no longer needed:
 * - remove every style that uses SAFARI_BUG_WORKAROUND_EXTRA_SPACE
 * - move `flexDirection` & `gap` from StyledRootContent to StyledRoot
 * - remove StyledRootContent
 * - make `StyledRoot` style Flex, not Box
 */
export const SAFARI_BUG_WORKAROUND_EXTRA_SPACE = pxToRem(20);

const raisedLabelVariant = css({
  variants: {
    raisedLabel: {
      true: {
        "&::placeholder": {
          color: "$off-white-72",
        },
      },
    },
  },
});

export const LEGEND_PADDING: SpaceTokenKey = "$1";

export const StyledFieldSetContent = styled(Box, {
  width: "100%",
  position: "relative",
  top: SAFARI_BUG_WORKAROUND_EXTRA_SPACE,
});

export const StyledFieldSet = styled("fieldset", {
  position: "relative",
  border: `${FIELDSET_BORDER_WIDTH} solid $off-white-18`,
  borderRadius: "$xs",
  height: pxToRem(TEXTAREA_DEFAULT_HEIGHT),
  maxHeight: pxToRem(TEXTAREA_MAX_HEIGHT),
  width: "100%",

  variants: {
    focus: {
      true: {
        borderWidth: FIELDSET_BORDER_WIDTH_FOCUS,
        legend: { marginLeft: `calc($4 - ${FIELDSET_BORDER_WIDTH_FOCUS} - ${LEGEND_PADDING})` },
      },
    },
  },
});

const inputBase: CSS = {
  height: pxToRem(TEXTAREA_DEFAULT_HEIGHT),
  width: "100%",
  border: `${pxToRem(INPUT_PADDING)} solid transparent`,
  color: "$light-off-white",
};

export const StyledInput = styled(
  "input",
  {
    minWidth: 0,
    position: "relative",
    "&:-webkit-autofill": {
      "-webkit-background-clip": "text",
      "-webkit-text-fill-color": "#FFF8F8",
      caretColor: "$light-off-white",
    },
    "&:-webkit-autofill:hover": {
      "-webkit-background-clip": "text",
      "-webkit-text-fill-color": "#FFF8F8",
      caretColor: "$light-off-white",
    },
    "&:-webkit-autofill:focus": {
      "-webkit-background-clip": "text",
      "-webkit-text-fill-color": "#FFF8F8",
      caretColor: "$light-off-white",
    },
    "&:-webkit-autofill:active": {
      "-webkit-background-clip": "text",
      "-webkit-text-fill-color": "#FFF8F8",
      caretColor: "$light-off-white",
    },
    "&::-webkit-inner-spin-button": {
      "-webkit-appearance": "none",
      margin: 0,
    },
    "&::-webkit-outer-spin-button": {
      "-webkit-appearance": "none",
      margin: 0,
    },
    "&[type=number]": {
      "-moz-appearance": "textfield",
    },

    ...inputBase,
    ...placeholderMgmt,
    ...typographyVariants.body3,
  },
  raisedLabelVariant
);

export const StyledTextArea = styled(
  "textarea",
  {
    maxHeight: pxToRem(TEXTAREA_MAX_HEIGHT),
    resize: "none",
    overflowWrap: "break-word",
    pt: pxToRem(2),
    ...inputBase,
    ...placeholderMgmt,
    ...typographyVariants.body3,
    ...customScrollbars,
  },
  raisedLabelVariant
);

export const StyledLabel = styled(LabelPrimitive.Root, {
  position: "absolute",
  top: "50%",
  left: "$4",
  transform: "translateY(-50%)",
  transition: `all 200ms cubic-bezier(0, 0, 0.2, 1)`,
  color: "$off-white-72",

  ...typographyVariants.body4,
});

export const StyledLegend = styled("legend", {
  visibility: "hidden",
  maxWidth: "0px",
  height: 0,
  transition: "max-width 50ms cubic-bezier(0.0, 0, 0.2, 1)",
  marginLeft: `calc($4 - ${FIELDSET_BORDER_WIDTH} - ${LEGEND_PADDING})`,
  whiteSpace: "nowrap",
  ...typographyVariants.body5,
});

export const StyledInfoText = styled(Text, {
  pl: "$4",
  color: "$off-white-72",
  overflowWrap: "anywhere",
  position: "relative",
  top: SAFARI_BUG_WORKAROUND_EXTRA_SPACE,
});

export const InputFieldContainer = styled(Flex, {
  position: "absolute",
  width: "100%",
  justifyContent: "space-between",
  alignItems: "center",
  top: SAFARI_BUG_WORKAROUND_EXTRA_SPACE,
});

export const StyledRootContent = styled(Flex, {
  flexDirection: "column",
  gap: "$2",

  position: "relative",
  width: "100%",
  overflow: "hidden",
  top: `-${SAFARI_BUG_WORKAROUND_EXTRA_SPACE}`,
  paddingBottom: SAFARI_BUG_WORKAROUND_EXTRA_SPACE,
  marginBottom: `-${SAFARI_BUG_WORKAROUND_EXTRA_SPACE}`,
});

export const StyledRoot = styled(Box, {
  position: "relative",
  width: "100%",

  ...typographyVariants.body4,

  [`${StyledLabel}`]: {
    color: "$off-white-72",
  },
  [`${StyledFieldSet}`]: {
    borderColor: "$off-white-18",
  },
  [`${StyledInfoText}`]: {
    color: "$off-white-72",
  },

  ["&:not(:where([data-disabled=true]))"]: {
    [`:where(${InputFieldContainer}:hover + div) ${StyledFieldSet}`]: {
      border: `${FIELDSET_BORDER_WIDTH} solid $off-white-36-opaque`,
    },
  },

  "&:focus-within": {
    [`& ${StyledFieldSet}`]: {
      border: `${FIELDSET_BORDER_WIDTH_FOCUS} solid $off-white-36-opaque`,
    },
    [`& ${StyledLegend}`]: {
      marginLeft: `calc($4 - ${FIELDSET_BORDER_WIDTH_FOCUS} - ${LEGEND_PADDING})`,
    },
  },

  "&[data-disabled=true]": {
    opacity: "$disabled",
    cursor: "not-allowed",
  },

  variants: {
    error: {
      true: {
        [`${StyledFieldSet}`]: {
          borderColor: "$light-red",
          borderWidth: FIELDSET_BORDER_WIDTH_FOCUS,
        },
        [`${StyledLabel}`]: {
          color: "$light-red",
        },

        [`${StyledInfoText}`]: {
          color: "$light-red",
        },
      },
    },
  },
});
