import { css } from '@emotion/css';
import memoizeOne from 'memoize-one';
import tinycolor from 'tinycolor2';

import { colorManipulator, GrafanaTheme2, LogLevel } from '@grafana/data';
import { styleMixins } from '@grafana/ui';

export const getLogLevelStyles = (theme: GrafanaTheme2, logLevel?: LogLevel) => {
  let logColor = theme.isLight ? theme.v1.palette.gray5 : theme.v1.palette.gray2;
  switch (logLevel) {
    case LogLevel.crit:
    case LogLevel.critical:
      logColor = '#705da0';
      break;
    case LogLevel.error:
    case LogLevel.err:
      logColor = '#e24d42';
      break;
    case LogLevel.warning:
    case LogLevel.warn:
      logColor = theme.colors.warning.main;
      break;
    case LogLevel.info:
      logColor = '#7eb26d';
      break;
    case LogLevel.debug:
      logColor = '#1f78c1';
      break;
    case LogLevel.trace:
      logColor = '#6ed0e0';
      break;
  }

  return {
    logsRowLevelColor: css({
      '&::after': {
        backgroundColor: logColor,
      },
    }),
  };
};

export const getLogRowStyles = memoizeOne((theme: GrafanaTheme2) => {
  const hoverBgColor = styleMixins.hoverColor(theme.colors.background.secondary, theme);
  const contextOutlineColor = tinycolor(theme.components.dashboard.background).setAlpha(0.7).toRgbString();
  return {
    logsRowLevel: css({
      label: 'logs-row__level',
      maxWidth: theme.spacing(1.25),
      cursor: 'default',
      '&::after': {
        content: "''",
        display: 'block',
        position: 'absolute',
        top: '1px',
        bottom: '1px',
        width: '3px',
        left: theme.spacing(0.5),
      },
    }),
    // Compared to logsRowLevel we need to make error logs wider to accommodate the icon
    logsRowWithError: css({
      maxWidth: `${theme.spacing(1.5)}`,
    }),
    logsRowMatchHighLight: css({
      label: 'logs-row__match-highlight',
      background: 'inherit',
      padding: 'inherit',
      color: theme.components.textHighlight.text,
      backgroundColor: theme.components.textHighlight.background,
    }),
    logRows: css({
      position: 'relative',
    }),
    shortcut: css({
      display: 'inline-flex',
      alignItems: 'center',
      gap: theme.spacing(1),
      color: theme.colors.text.secondary,
      opacity: 0.7,
      fontSize: theme.typography.bodySmall.fontSize,
      marginTop: theme.spacing(1),
    }),
    logsRowsTable: css({
      label: 'logs-rows',
      fontFamily: theme.typography.fontFamilyMonospace,
      fontSize: theme.typography.bodySmall.fontSize,
      width: '100%',
      position: 'relative',
    }),
    logsRowsTableContain: css({
      contain: 'strict',
    }),
    highlightBackground: css({
      backgroundColor: tinycolor(theme.colors.info.transparent).setAlpha(0.25).toString(),
    }),
    logsRow: css({
      label: 'logs-row',
      width: '100%',
      cursor: 'pointer',
      verticalAlign: 'top',

      '&:focus-within': {
        outline: `2px solid ${theme.colors.primary.border}`,
        outlineOffset: '-2px',
      },

      '&:hover': {
        '.log-row-menu': {
          zIndex: 1,
        },

        background: hoverBgColor,
      },

      'td:not(.log-row-menu-cell):last-child': {
        width: '100%',
      },

      '> td:not(.log-row-menu-cell)': {
        position: 'relative',
        paddingRight: theme.spacing(1),
        borderTop: '1px solid transparent',
        borderBottom: '1px solid transparent',
        height: '100%',
      },
    }),
    logsRowDuplicates: css({
      label: 'logs-row__duplicates',
      textAlign: 'right',
      width: '4em',
      cursor: 'default',
    }),
    logIconError: css({
      color: theme.colors.warning.main,
      position: 'relative',
      top: '-2px',
    }),
    logIconInfo: css({
      color: theme.colors.info.main,
      position: 'relative',
      top: '-2px',
    }),
    logsRowToggleDetails: css({
      label: 'logs-row-toggle-details__level',
      fontSize: '9px',
      maxWidth: '15px',
    }),
    logsRowLocalTime: css({
      label: 'logs-row__localtime',
      whiteSpace: 'nowrap',
    }),
    logsRowLabels: css({
      label: 'logs-row__labels',
      whiteSpace: 'nowrap',
      maxWidth: '22em',

      /* This is to make the labels vertical align */
      '> span': {
        marginTop: '0.75px',
      },
    }),
    logsRowMessage: css({
      label: 'logs-row__message',
      whiteSpace: 'pre-wrap',
      wordBreak: 'break-all',
      overflowWrap: 'anywhere',
      width: '100%',
      textAlign: 'left',
    }),
    copyLogButton: css({
      padding: theme.spacing(0, 0, 0, 0.5),
      height: theme.spacing(3),
      width: theme.spacing(3.25),
      lineHeight: theme.spacing(2.5),
      overflow: 'hidden',
      '&:hover': {
        backgroundColor: colorManipulator.alpha(theme.colors.text.primary, 0.12),
      },
    }),
    //Log details specific CSS
    logDetailsContainer: css({
      label: 'logs-row-details-table',
      border: `1px solid ${theme.colors.border.medium}`,
      padding: theme.spacing(0, 1, 1),
      borderRadius: theme.shape.radius.default,
      margin: theme.spacing(2.5, 1, 2.5, 2),
      cursor: 'default',
    }),
    logDetailsTable: css({
      label: 'logs-row-details-table',
      lineHeight: '18px',
      width: '100%',
      'td:last-child': {
        width: '100%',
      },
    }),
    logsDetailsIcon: css({
      label: 'logs-row-details__icon',
      position: 'relative',
      color: theme.v1.palette.gray3,
      paddingTop: '1px',
      paddingBottom: '1px',
      paddingRight: theme.spacing(0.75),
    }),
    logDetailsLabel: css({
      label: 'logs-row-details__label',
      maxWidth: '30em',
      minMidth: '20em',
      padding: theme.spacing(0, 1),
      overflowWrap: 'break-word',
    }),
    logDetailsHeading: css({
      label: 'logs-row-details__heading',
      fontWeight: theme.typography.fontWeightBold,
      padding: theme.spacing(1, 0, 0.5),
    }),
    logDetailsValue: css({
      label: 'logs-row-details__row',
      position: 'relative',
      verticalAlign: 'middle',
      cursor: 'default',

      '&:hover': {
        backgroundColor: hoverBgColor,
      },
    }),
    detailsToggle: css({
      appearance: 'none',
      background: 'none',
      border: 'none',
      padding: 0,
      // Don't increase the height of the row
      maxHeight: '19px',

      // Don't show default button box-shadow on focus, we apply outline to the entire row instead
      '&:focus-visible': {
        boxShadow: 'none',
      },

      '&:focus': {
        outline: 0,
      },
      '&:after': {
        content: '""',
        inset: 0,
        position: 'absolute',
      },
    }),

    // Log row
    topVerticalAlign: css({
      label: 'topVerticalAlign',
      marginTop: theme.spacing(-0.9),
      marginLeft: theme.spacing(-0.25),
    }),
    detailsOpen: css({
      '&:hover': {
        backgroundColor: styleMixins.hoverColor(theme.colors.background.primary, theme),
      },
    }),
    errorLogRow: css({
      label: 'erroredLogRow',
      color: theme.colors.text.secondary,
    }),
    // Log Row Message
    positionRelative: css({
      label: 'positionRelative',
      position: 'relative',
    }),
    rowWithContext: css({
      label: 'rowWithContext',
      zIndex: 1,
      outline: `9999px solid ${contextOutlineColor}`,
      display: 'inherit',
    }),
    horizontalScroll: css({
      label: 'horizontalScroll',
      whiteSpace: 'pre',
    }),
    contextNewline: css({
      display: 'block',
      marginLeft: '0px',
    }),
    rowMenu: css({
      label: 'rowMenu',
      display: 'flex',
      flexWrap: 'nowrap',
      flexDirection: 'row',
      alignContent: 'flex-end',
      justifyContent: 'space-evenly',
      alignItems: 'center',
      position: 'absolute',
      top: 0,
      bottom: 'auto',
      background: theme.colors.background.primary,
      boxShadow: theme.shadows.z3,
      padding: theme.spacing(0.5, 1, 0.5, 1),
      zIndex: 100,
      gap: theme.spacing(0.5),

      '& > button': {
        margin: 0,
      },
    }),
    logRowMenuCell: css({
      position: 'sticky',
      zIndex: theme.zIndex.dropdown,
      marginTop: theme.spacing(-0.125),
      right: 0,

      '& > span': {
        transform: 'translateX(-100%)',
      },
    }),
    logLine: css({
      fontFamily: theme.typography.fontFamilyMonospace,
      fontSize: theme.typography.bodySmall.fontSize,
      letterSpacing: theme.typography.bodySmall.letterSpacing,
      textAlign: 'left',
      padding: 0,
      userSelect: 'text',
    }),
    // Log details
    logsRowLevelDetails: css({
      label: 'logs-row__level_details',
      '&::after': {
        top: '-3px',
      },
    }),
    logDetails: css({
      label: 'logDetailsDefaultCursor',
      cursor: 'default',

      '&:hover': {
        backgroundColor: theme.colors.background.primary,
      },
    }),
    visibleRowMenu: css({
      label: 'visibleRowMenu',
      aspectRatio: '1/1',
      zIndex: 90,
    }),
    linkButton: css({
      label: 'linkButton',
      '> button': {
        paddingTop: theme.spacing(0.5),
      },
    }),
    hidden: css({
      label: 'hidden',
      visibility: 'hidden',
    }),
    unPinButton: css({
      height: theme.spacing(3),
      lineHeight: theme.spacing(2.5),
    }),
  };
});

export type LogRowStyles = ReturnType<typeof getLogRowStyles>;
