import { createVar, globalStyle, keyframes, style, styleVariants } from '@vanilla-extract/css';
import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
import { DefaultReset, color, config, toRem } from 'folds';
import * as htmlCss from '../../../styles/CustomHtml.css';

export const StickySection = style({
  position: 'sticky',
  top: config.space.S100,
});

const SpacingVar = createVar();
const SpacingVariant = styleVariants({
  '0': {
    vars: {
      [SpacingVar]: config.space.S0,
    },
  },
  '100': {
    vars: {
      [SpacingVar]: config.space.S100,
    },
  },
  '200': {
    vars: {
      [SpacingVar]: config.space.S200,
    },
  },
  '300': {
    vars: {
      [SpacingVar]: config.space.S300,
    },
  },
  '400': {
    vars: {
      [SpacingVar]: config.space.S400,
    },
  },
  '500': {
    vars: {
      [SpacingVar]: config.space.S500,
    },
  },
});

const highlightAnime = keyframes({
  '0%': {
    backgroundColor: color.Primary.Container,
  },
  '25%': {
    backgroundColor: color.Primary.ContainerActive,
  },
  '50%': {
    backgroundColor: color.Primary.Container,
  },
  '75%': {
    backgroundColor: color.Primary.ContainerActive,
  },
  '100%': {
    backgroundColor: color.Primary.Container,
  },
});

export const newMessageAnime = keyframes({
  '0%': {
    opacity: 0,
    transform: 'translateY(8px)',
  },
  '100%': {
    opacity: 1,
    transform: 'translateY(0)',
  },
});
const HighlightVariant = styleVariants({
  true: {
    animation: `${highlightAnime} 2000ms ease-in-out`,
    animationIterationCount: 'infinite',
  },
});

const SelectedVariant = styleVariants({
  true: {
    backgroundColor: color.Surface.ContainerActive,
  },
});

const NewMessageVariant = styleVariants({
  true: {
    animation: `${newMessageAnime} 300ms ease-out`,
    animationFillMode: 'backwards',
  },
});

const AutoCollapse = style({
  selectors: {
    [`&+&`]: {
      marginTop: 0,
    },
  },
});

export const MessageBase = recipe({
  base: [
    DefaultReset,
    {
      marginTop: SpacingVar,
      padding: `${config.space.S100} ${config.space.S200} ${config.space.S100} ${config.space.S400}`,
      borderRadius: `0 ${config.radii.R400} ${config.radii.R400} 0`,
      transition: 'background-color 150ms ease-out',
      selectors: {
        '&:hover': {
          backgroundColor: color.Surface.ContainerHover,
        },
      },
    },
  ],
  variants: {
    space: SpacingVariant,
    collapse: {
      true: {
        marginTop: 0,
      },
    },
    autoCollapse: {
      true: AutoCollapse,
    },
    highlight: HighlightVariant,
    selected: SelectedVariant,
    newMessage: NewMessageVariant,
  },
  defaultVariants: {
    space: '400',
  },
});

export type MessageBaseVariants = RecipeVariants<typeof MessageBase>;

export const CompactHeader = style([
  DefaultReset,
  StickySection,
  {
    maxWidth: toRem(170),
    width: '100%',
  },
]);

export const AvatarBase = style({
  paddingTop: toRem(4),
  transition: 'transform 200ms cubic-bezier(0, 0.8, 0.67, 0.97)',
  display: 'flex',
  alignSelf: 'start',

  selectors: {
    '&:hover': {
      transform: `translateY(${toRem(-2)})`,
    },
  },
});

export const ModernBefore = style({
  minWidth: toRem(36),
});

export const BubbleBefore = style({
  minWidth: toRem(36),
});

export const BubbleContent = style({
  maxWidth: toRem(800),
  padding: config.space.S200,
  backgroundColor: color.SurfaceVariant.Container,
  color: color.SurfaceVariant.OnContainer,
  borderRadius: config.radii.R500,
  position: 'relative',
});

export const BubbleContentArrowLeft = style({
  borderTopLeftRadius: 0,
});

export const BubbleLeftArrow = style({
  width: toRem(9),
  height: toRem(8),

  position: 'absolute',
  top: 0,
  left: toRem(-8),
  zIndex: 1,
});

export const Username = style({
  overflow: 'hidden',
  overflowY: 'clip',
  whiteSpace: 'nowrap',
  textOverflow: 'ellipsis',
  lineHeight: '1.5',
  // Allow text selection while keeping button clickable
  userSelect: 'text',
  WebkitUserSelect: 'text',
  selectors: {
    'button&': {
      cursor: 'pointer',
    },
    'button&:hover, button&:focus-visible': {
      textDecoration: 'underline',
    },
  },
});

export const UsernameBold = style({
  fontWeight: 550,
});

export const MessageTextBody = recipe({
  base: {
    wordBreak: 'break-word',
    // Clip zalgo/combining marks with room so normal text + emoji aren't shaved
    overflow: 'clip',
    overflowY: 'clip',
    lineHeight: '1.5',
    padding: toRem(20),
    margin: toRem(-20),
    userSelect: 'text',
    WebkitUserSelect: 'text',
  },
  variants: {
    preWrap: {
      true: {
        whiteSpace: 'pre-wrap',
      },
    },
    jumboEmoji: {
      true: {
        display: 'flex',
        flexWrap: 'wrap',
        alignItems: 'center',
        alignContent: 'flex-start',
        gap: toRem(4),
        fontSize: toRem(56),
        lineHeight: 1,
        // Negative pad/margin is for zalgo clip — reset so jumbo doesn't overlap neighbors
        padding: 0,
        margin: 0,
        overflow: 'visible',
        overflowY: 'visible',
      },
    },
    emote: {
      true: {
        color: color.Success.Main,
        fontStyle: 'italic',
      },
    },
  },
});

export type MessageTextBodyVariants = RecipeVariants<typeof MessageTextBody>;

/** Jumbo emoji-only messages: 70×70px cells, glyph inset so fonts aren't cropped. */
const jumboEmojiSelector = '[data-jumbo-emoji="true"]';
const jumboCell = toRem(70);
const jumboGlyph = toRem(56);

globalStyle(jumboEmojiSelector, {
  fontSize: `${jumboGlyph} !important`,
  lineHeight: '1 !important',
});

/**
 * Linkify / parser wrappers are often a single child; flatten them so each
 * emoticon participates in the flex row and wrapped rows get gap spacing.
 */
globalStyle(`${jumboEmojiSelector} > *`, {
  display: 'contents',
});

/** Force <br> to wrap onto a new flex row in jumbo messages. */
globalStyle(`${jumboEmojiSelector} br`, {
  display: 'block !important',
  flexBasis: '100%',
  width: '100%',
  height: '0 !important',
});

globalStyle(`${jumboEmojiSelector} .${htmlCss.EmoticonBase}`, {
  display: 'inline-flex !important',
  alignItems: 'center',
  justifyContent: 'center',
  width: `${jumboCell} !important`,
  height: `${jumboCell} !important`,
  padding: '0 !important',
  overflow: 'hidden',
  verticalAlign: 'bottom',
  flex: '0 0 auto',
});

globalStyle(`${jumboEmojiSelector} .${htmlCss.EmoticonBaseJumbo}`, {
  display: 'inline-flex !important',
  alignItems: 'center',
  justifyContent: 'center',
  width: `${jumboCell} !important`,
  height: `${jumboCell} !important`,
  padding: '0 !important',
  overflow: 'hidden',
  verticalAlign: 'bottom',
  flex: '0 0 auto',
});

globalStyle(`${jumboEmojiSelector} .${htmlCss.Emoticon.classNames.base}`, {
  display: 'inline-flex !important',
  alignItems: 'center',
  justifyContent: 'center',
  fontSize: `${jumboGlyph} !important`,
  width: `${jumboGlyph} !important`,
  height: `${jumboGlyph} !important`,
  minWidth: `${jumboGlyph} !important`,
  lineHeight: '1 !important',
  top: '0 !important',
  overflow: 'visible',
});

globalStyle(`${jumboEmojiSelector} .${htmlCss.Emoticon.classNames.variants.jumbo.true}`, {
  display: 'inline-flex !important',
  alignItems: 'center',
  justifyContent: 'center',
  fontSize: `${jumboGlyph} !important`,
  width: `${jumboGlyph} !important`,
  height: `${jumboGlyph} !important`,
  minWidth: `${jumboGlyph} !important`,
  lineHeight: '1 !important',
  top: '0 !important',
  overflow: 'visible',
});

globalStyle(`${jumboEmojiSelector} .${htmlCss.EmoticonImg.classNames.base}`, {
  height: `${jumboGlyph} !important`,
  width: `${jumboGlyph} !important`,
  maxHeight: `${jumboGlyph} !important`,
  maxWidth: `${jumboGlyph} !important`,
  objectFit: 'contain',
});

globalStyle(`${jumboEmojiSelector} .${htmlCss.EmoticonImg.classNames.variants.jumbo.true}`, {
  height: `${jumboGlyph} !important`,
  width: `${jumboGlyph} !important`,
  maxHeight: `${jumboGlyph} !important`,
  maxWidth: `${jumboGlyph} !important`,
  objectFit: 'contain',
});
