import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { Badge } from '@rocket.chat/fuselage';

export type TabOrientation = 'horizontal' | 'vertical';

/**
 * Fill shared by the selected tab, tab hover, dividers and the strip border.
 *
 * Over the opaque window it uses the solid sidebar surface. Over a transparent
 * window it becomes a translucent overlay that inverts with the palette — a
 * subtle darkening in light mode and a subtle brightening in dark mode — so the
 * selected tab always contrasts with whatever shows through.
 */

const resolveChromeFill = (
  paletteTheme: 'light' | 'dark',
  isTransparentWindowEnabled: boolean
): string => {
  const CHROME_FILL_OVERLAY_LIGHT = isTransparentWindowEnabled
    ? 'rgba(255, 255, 255, 0.8)'
    : 'rgba(255, 255, 255, 1)';
  const CHROME_FILL_OVERLAY_DARK = 'rgba(255, 255, 255, 0.1)';

  return paletteTheme === 'dark'
    ? CHROME_FILL_OVERLAY_DARK
    : CHROME_FILL_OVERLAY_LIGHT;
};

const resolveDividerFill = (
  paletteTheme: 'light' | 'dark',
  _isTransparentWindowEnabled: boolean
): string => {
  return paletteTheme === 'dark'
    ? 'rgba(255, 255, 255, 1)'
    : 'rgba(0, 0, 0, 1)';
};

type StripProps = {
  isTransparentWindowEnabled: boolean;
  paletteTheme: 'light' | 'dark';
  orientation?: TabOrientation;
  height: string;
};

export const Strip = styled.div<StripProps>`
  --tab-chrome-fill: ${({ paletteTheme, isTransparentWindowEnabled }) =>
    resolveChromeFill(paletteTheme, isTransparentWindowEnabled)};

  --tab-divider-fill: ${({ paletteTheme, isTransparentWindowEnabled }) =>
    resolveDividerFill(paletteTheme, isTransparentWindowEnabled)};

  display: flex;
  flex-direction: row;
  align-items: center;
  padding: ${process.platform === 'darwin' ? '0px 6px' : '1px 0 0 4px'};
  padding-top: ${process.platform === 'darwin' ? '2px' : '1px'};
  flex: 0 0 auto;
  width: 100%;
  height: ${({ height = '40px' }) => height};
  gap: 3px;
  -webkit-app-region: drag;
  user-select: none;

  ${({ orientation }) =>
    orientation === 'vertical' &&
    css`
      flex-direction: column;
      align-items: center;
      width: 48px;
      height: 100%;
      padding: ${process.platform === 'darwin' ? '8px 0px' : '4px 0 8px 0'};
      padding-left: 2px;
    `}
`;

type TrafficLightSpacerProps = {
  collapsed: boolean;
};

export const TrafficLightSpacer = styled.div<TrafficLightSpacerProps>`
  flex: 0 0 auto;
  width: ${({ collapsed }) => (collapsed ? '0px' : '76px')};
  -webkit-app-region: drag;
  transition: width var(--transitions-duration, 100ms);
`;

type TabListProps = {
  orientation?: TabOrientation;
};

export const TabList = styled.div<TabListProps>`
  display: flex;
  flex-direction: row;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  gap: 1px;
  -webkit-app-region: drag;

  ${({ orientation }) =>
    orientation === 'vertical' &&
    css`
      flex-direction: column;
      align-items: center;
      width: 100%;
      gap: 4px;
      /* Content-sized so the DragSpacer below can push the trailing slot (the
         settings menu) to the bottom. 'visible' keeps the floating badges,
         which translate past the tab edge, from being clipped. */
      flex: 0 1 auto;
      overflow: visible;
    `}
`;

type DragSpacerProps = {
  orientation?: TabOrientation;
};

export const DragSpacer = styled.div<DragSpacerProps>`
  flex: 0 0 44px;
  -webkit-app-region: drag;

  ${({ orientation }) =>
    orientation === 'vertical' &&
    css`
      flex: 1 1 auto;
    `}
`;

export const TabBarButtonWrapper = styled.div`
  -webkit-app-region: no-drag;

  & button {
    opacity: 0.6;
    border-radius: ${process.platform === 'darwin' ? '8px' : '4px'};
    transition: background-color 150ms ease;
  }

  & button:hover {
    background-color: var(--tab-chrome-fill);
    border: none;
    opacity: 1;
  }

  & button:focus-visible {
    opacity: 1;
    background-color: var(--tab-chrome-fill);
  }
`;

type TabProps = {
  isSelected: boolean;
  isCompact: boolean;
  orientation?: TabOrientation;
};

export const Tab = styled.button<TabProps>`
  appearance: none;
  border: none;
  outline: none;
  background: transparent;
  font-family: inherit;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 4px;
  flex: 0 1 auto;
  width: 235px;
  max-width: 235px;
  min-width: 52px;
  height: 32px;
  position: relative;
  padding: ${({ isCompact }) => (isCompact ? '0 10px' : '0 10px')};
  cursor: pointer;
  -webkit-app-region: no-drag;
  color: var(--rcx-color-font-titles-labels, #f2f3f5);
  border-radius: ${process.platform === 'darwin' ? '8px' : '4px'};
  opacity: 0.6;
  outline: 0px solid
    color-mix(in srgb, var(--tab-divider-fill) 30%, transparent);
  outline-offset: 1px;
  transition:
    background-color 150ms ease,
    opacity 150ms ease,
    outline 150ms ease,
    box-shadow 150ms ease;

  ${({ isSelected }) =>
    isSelected
      ? css`
          background-color: var(--tab-chrome-fill);
          box-shadow: 0 0 4px 0px rgba(0, 0, 0, 0.1);
          opacity: 1;
          z-index: 1;
        `
      : css`
          &:hover {
            background-color: rgb(from var(--tab-chrome-fill) r g b / 0.56);
            background-color: var(--tab-chrome-fill);
            box-shadow: 0 0 4px 0px rgba(0, 0, 0, 0.1);
            opacity: 0.8;
          }
        `}

  ${({ orientation, isSelected }) =>
    orientation === 'vertical' &&
    css`
      /* Square tab: same height as the horizontal tab, width equal to height,
         icon centered so it keeps the same breathing room as horizontal. */
      width: 32px;
      min-width: 32px;
      max-width: 32px;
      height: 32px;
      padding: 0;
      justify-content: center;
      overflow: visible;
      background-color: var(--tab-chrome-fill);

      /* Vertical tabs are icon-only, so keep them at full opacity (sidebar-like)
         rather than dimming idle tabs the way the horizontal strip does. */
      opacity: 1;

      &:hover {
        outline-color: color-mix(
          in srgb,
          var(--tab-divider-fill) 10%,
          transparent
        );
        outline-width: 2px;
        opacity: 1;
      }

      ${isSelected &&
      css`
        outline-width: 2px;
      `}
    `}

  &:focus-visible {
    opacity: 1;
    border: 1px solid
      var(
        --rcx-color-button-icon-focus-border-color,
        var(
          --rcx-button-secondary-focus-border-color,
          var(
            --rcx-color-stroke-extra-dark,
            var(--rcx-color-neutral-800, #2f343d)
          )
        )
      );
    box-shadow: 0 0 0 2px
      var(
        --rcx-color-button-icon-focus-shadow-color,
        var(
          --rcx-button-secondary-focus-shadow-color,
          var(--rcx-color-shadow-highlight, var(--rcx-color-blue-200, #d1ebfe))
        )
      );
  }
`;

type DividerProps = {
  orientation?: TabOrientation;
};

export const Divider = styled.div<DividerProps>`
  width: 1px;
  height: 26px;
  background-color: var(--tab-divider-fill);
  opacity: 0.1;
  transition: opacity 150ms ease;

  ${({ orientation }) =>
    orientation === 'vertical' &&
    css`
      opacity: 0;
      width: 26px;
      height: 1px;
    `}

  /* Each tab renders a trailing divider, so one sits between the last tab and
     the add button automatically. Hide the dangling divider at the strip's
     trailing edge (no add button) and the ones flanking the active or hovered
     tab (its previous sibling via :has, its next sibling via +). Targets
     aria-selected / role='tab' rather than the Tab component selector, which
     needs @emotion/babel-plugin (not enabled). The '+ div button:hover' rule
     hides the divider before the add button (wrapped in a div) when that button
     is hovered. */
  &:last-child,
  &:has(+ [aria-selected='true']),
  [aria-selected='true'] + &,
  &:has(+ [role='tab']:hover),
  [role='tab']:hover + &,
  &:has(+ div button:hover) {
    opacity: 0;
  }
`;

type FaviconProps = {
  visible: boolean;
  orientation?: TabOrientation;
};

export const Favicon = styled.img<FaviconProps>`
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  object-fit: contain;
  display: ${({ visible }) => (visible ? 'initial' : 'none')};

  ${({ orientation }) =>
    orientation === 'vertical' &&
    css`
      width: 28px;
      height: 28px;
    `}
`;

type InitialsProps = {
  visible: boolean;
  orientation?: TabOrientation;
};

export const Initials = styled.span<InitialsProps>`
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  line-height: 22px;
  text-align: center;
  font-size: 11px;
  border-radius: 4px;
  background-color: var(--rcx-color-surface-neutral, #e4e7ea);
  display: ${({ visible }) => (visible ? 'initial' : 'none')};

  ${({ orientation }) =>
    orientation === 'vertical' &&
    css`
      width: 28px;
      height: 28px;
      line-height: 28px;
      font-size: 13px;
      background-color: transparent;
    `}
`;

export const Label = styled.span`
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 500;
  line-height: 12px;
  text-align: left;
`;

export const ShortcutChip = styled.span`
  flex: 0 0 auto;
  font-size: 11px;
  opacity: 0.7;
`;

/* Colors come from the Fuselage Badge variant tokens. The ghost variant is
   deliberate: its background (stroke-dark) flips to a light gray in the dark
   palette, keeping the badge visible on the dark tab strip, where the
   server's secondary/level-1 badge color would blend in. Overriding the text
   color here once broke the badge by referencing a token that does not
   exist. */
export const TabBadge = styled(Badge)`
  flex-shrink: 0;
  box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2);
`;

/* Unread-without-mentions indicator for vertical (sidebar) tabs: same
   footprint as the count badge, with a drawn dot instead of a text glyph.
   The dot matches the macOS dock badge (dock.setBadge('•') renders its
   bullet at ~1/8 of the badge diameter → 2px inside the 16px badge) and
   uses currentColor so it follows the variant's font token. */
export const UnreadDotBadge = styled(TabBadge)`
  align-items: center;

  &::before {
    content: '';
    display: block;
    width: 2px;
    height: 2px;
    border-radius: 50%;
    background: currentColor;
  }
`;

/* Unread-without-mentions indicator for horizontal tabs: a plain 8px ball.
   Badge ships min-width/min-height of 1rem plus 2px/4px padding; without
   resetting the padding and the fixed box, an 8px dot renders as a 16x8
   pill. */
export const UnreadDot = styled(TabBadge)`
  width: 8px;
  min-width: 8px;
  height: 8px;
  min-height: 8px;
  padding: 0;
`;

/* Floats the mention/warning badges over the top-right corner of a vertical
   tab, matching the sidebar's ServerButton badge placement.

   Anchors the badge's CENTRE to a fixed point on the tab, so a badge of any
   size or variant lands in the same visual spot. The anchor is the centre of
   the standard 16px badge sitting on the corner, which is the reference
   placement; a wider mention count then grows outward from that same centre
   rather than shifting position.

   Anchoring an edge instead (e.g. right: 0) pins the wrapper's right edge and
   lets content grow leftward, so badge width leaks into placement and a
   narrower badge lands off-centre from a wider one. */
const BADGE_ANCHOR_X = '28px';
const BADGE_ANCHOR_Y = '4px';

export const BadgeWrapper = styled.div`
  position: absolute;
  top: ${BADGE_ANCHOR_Y};
  left: ${BADGE_ANCHOR_X};
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  transform: translate(-50%, -50%);
  pointer-events: none;
`;

export const WindowControlsGroup = styled.div`
  display: flex;
  flex-direction: row;
  align-items: stretch;
  flex: 0 0 auto;
  height: 100%;
  -webkit-app-region: no-drag;
`;

type WindowControlButtonProps = {
  isCloseButton?: boolean;
};

export const WindowControlButton = styled.button<WindowControlButtonProps>`
  appearance: none;
  border: none;
  outline: none;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 46px;
  height: 100%;
  cursor: pointer;
  -webkit-app-region: no-drag;
  color: var(--rcx-color-font-titles-labels, #f2f3f5);
  transition:
    background-color 150ms ease,
    color 150ms ease;

  &:hover {
    background-color: ${({ isCloseButton }) =>
      isCloseButton
        ? '#c42b1c'
        : 'var(--tab-chrome-fill, var(--rcx-color-surface-hover, rgba(0, 0, 0, 0.06)))'};
    color: ${({ isCloseButton }) =>
      isCloseButton
        ? '#ffffff'
        : 'var(--rcx-color-font-titles-labels, #f2f3f5)'};
  }

  &:focus-visible {
    box-shadow: inset 0 0 0 2px var(--rcx-color-stroke-highlight, #1d74f5);
  }
`;
