/*
 * This file belongs to Hoist, an application development toolkit
 * developed by Extremely Heavy Industries (www.xh.io | info@xh.io)
 *
 * Copyright © 2026 Extremely Heavy Industries Inc.
 */

@use 'sass:math';
@use '../ag-grid/AgGrid';

.xh-grid:not(.xh-data-view) {
  //------------------------
  // Core Header Classes
  //------------------------
  .xh-grid-group-header {
    display: flex;
    flex-direction: row;
    align-items: center;
    min-height: 32px;
    width: 100%;

    &--expandable {
      cursor: pointer;
    }

    span {
      flex: 1;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    svg {
      color: var(--xh-grid-header-icon-color);
    }
  }

  .xh-grid-header {
    display: flex;
    flex-direction: row;
    align-items: center;
    cursor: pointer;
    width: 100%;

    span {
      flex: 1;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .xh-grid-header-sort-icon,
    .xh-grid-header-menu-icon,
    .xh-grid-header-expand-collapse-icon {
      color: var(--xh-grid-header-icon-color);
      width: var(--xh-grid-header-icon-width);
    }

    &.xh-grid-header-multisort .xh-grid-header-sort-icon svg {
      opacity: 0.5;
    }

    .xh-grid-header-menu-icon {
      cursor: pointer;
    }

    // Prevent sticky hover effects on touch screens
    @media (hover: hover) {
      .xh-grid-header-expand-collapse-icon:hover {
        color: var(--xh-text-color-highlight);
      }
    }
  }

  .xh-column-header-align-right {
    .xh-grid-header,
    .xh-grid-group-header {
      text-align: right;
    }
  }

  .xh-column-header-align-center {
    .xh-grid-header,
    .xh-grid-group-header {
      text-align: center;
    }
  }

  // Floating viewports host total rows.
  .ag-floating-bottom,
  .ag-floating-top {
    // Background on viewport itself covers area left blank by presence of a flex column.
    background-color: var(--xh-grid-total-row-bg);

    .ag-row-pinned.ag-row-first {
      background-color: var(--xh-grid-total-row-bg);
    }
  }

  //------------------------
  // Core Cell Classes
  //------------------------
  // No LR padding when center aligned - not relevant / allows narrow cols (icons) to center align.
  .ag-cell.xh-align-center {
    padding-left: 0;
    padding-right: 0;
  }

  // Render badge on cells with validation issues
  .ag-cell.xh-cell--invalid,
  .ag-cell.xh-cell--warning,
  .ag-cell.xh-cell--info {
    &::before {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      border-color: transparent;
      border-style: solid;
    }

    // Render badge on top of nested editor, and move to account for padding while editing
    &.ag-cell-inline-editing::before {
      z-index: 1;
      margin-top: 1px;
      margin-right: 3px;
    }
  }

  .ag-cell.xh-cell--invalid::before {
    border-right-color: var(--xh-intent-danger);
    border-top-color: var(--xh-intent-danger);
  }

  .ag-cell.xh-cell--warning::before {
    border-right-color: var(--xh-intent-warning);
    border-top-color: var(--xh-intent-warning);
  }

  .ag-cell.xh-cell--info::before {
    border-right-color: var(--xh-intent-primary);
    border-top-color: var(--xh-intent-primary);
  }

  // Render left / right group borders
  .ag-cell.xh-cell--group-border-left {
    @include AgGrid.group-border(left);
  }

  .ag-cell.xh-cell--group-border-right {
    @include AgGrid.group-border(right);
  }

  .xh-ag-grid {
    &--tiny {
      .ag-cell.xh-cell--invalid::before,
      .ag-cell.xh-cell--warning::before,
      .ag-cell.xh-cell--info::before {
        border-width: 3px;
      }
    }

    &--compact {
      .ag-cell.xh-cell--invalid::before,
      .ag-cell.xh-cell--warning::before,
      .ag-cell.xh-cell--info::before {
        border-width: 4px;
      }
    }

    &--standard {
      .ag-cell.xh-cell--invalid::before,
      .ag-cell.xh-cell--warning::before,
      .ag-cell.xh-cell--info::before {
        border-width: 5px;
      }
    }

    &--large {
      .ag-cell.xh-cell--invalid::before,
      .ag-cell.xh-cell--warning::before,
      .ag-cell.xh-cell--info::before {
        border-width: 6px;
      }
    }
  }
}

//------------------------
// Trees and Grouping
//------------------------
.xh-grid--hierarchical:not(.xh-data-view) {
  // Generate indentations for tree grids with hierarchical data.
  .ag-ltr {
    @for $i from 0 to 10 {
      .ag-row-group-indent-#{$i} {
        padding-left: calc(#{$i} * var(--xh-grid-tree-indent));
      }

      .ag-row-level-#{$i} {
        .ag-row-group-leaf-indent {
          margin-left: var(--xh-grid-tree-indent);
        }
      }
    }
  }

  .ag-group-contracted + .ag-group-value:not(:empty) {
    margin-left: 0;
  }

  // Adjust left padding for tree columns.
  .ag-cell.xh-tree-column {
    padding-left: calc(var(--xh-grid-tree-indent) - var(--xh-grid-tree-icon-px));
  }

  // Suppress (almost all) left padding in tree column header when actively showing expand/collapse
  // affordance - this allows space for the icon without clipping.
  .ag-header-cell.xh-column-header--with-expand-collapse {
    padding-left: 2px;
  }

  //------------------------
  // Tree grid styling modes
  //------------------------
  // Generate a set of selectors targeting all expected max-depth levels, then style all rows
  // *not* at that max depth with parent/group row highlights or colors. For trees with mixed-depth
  // branches, some such "parent" rows might not actually have children and therefore won't be
  // identified as groups by AG-Grid row classes, but this keeps the styling consistent for all
  // rows at the same level.
  @for $i from 0 to 10 {
    // With highlights
    &.xh-grid--tree-style-highlights.xh-grid--max-depth-#{$i} {
      @for $level from 0 to 9 {
        $l: 94 + (math.div($level, ($i + 1)) * 6);

        .ag-row.ag-row-level-#{$level}:not(.ag-row-level-#{$i}) {
          &:not(.ag-row-selected),
          &.ag-row.ag-row-odd:not(.ag-full-width-row):not(.ag-row-selected) {
            background-color: hsl(205, 70%, $l * 1%);
          }
        }
      }

      .xh-ag-grid--show-hover {
        .ag-row:not(.ag-row-level-#{$i}) {
          &.ag-row.ag-row-hover:not(.ag-full-width-row):not(.ag-row-selected):not(.ag-row-pinned) {
            background-color: var(--xh-grid-bg-hover);
          }
        }
      }
    }

    // With colors
    &.xh-grid--tree-style-colors.xh-grid--max-depth-#{$i} {
      .ag-floating-bottom,
      .ag-floating-top {
        background-color: var(--xh-grid-tree-group-color-level-0);
      }

      @for $level from 0 to 9 {
        .ag-row.ag-row-level-#{$level}:not(.ag-row-level-#{$i}) {
          &:not(.ag-row-selected),
          &.ag-row.ag-row-odd:not(.ag-full-width-row):not(.ag-row-selected) {
            background-color: var(--xh-grid-tree-group-color-level-#{$level});
          }
        }
      }
    }
  }

  &.xh-grid--tree-style-borders {
    .ag-row-level-0 {
      &:not(.ag-row-first) {
        border-top: 1px solid var(--xh-grid-tree-group-border-color);
      }
    }

    // Floating viewports host total rows.
    .ag-floating-bottom {
      border-color: var(--xh-grid-tree-group-border-color);
    }

    .ag-floating-top {
      border-color: var(--xh-grid-tree-group-border-color);
    }
  }
}

// TODO find better place to put this
.xh-grid-clear-background-color:not(.ag-row-selected) {
  background-color: unset !important;
}

// Suppress default indenting when grid is in tree mode but no root records have children.
.xh-grid--flat:not(.xh-data-view) {
  .ag-ltr .ag-row-group-leaf-indent {
    margin-left: 0;
  }
}

.xh-dark .xh-grid--hierarchical:not(.xh-data-view) {
  @for $i from 0 to 10 {
    // With highlights
    &.xh-grid--tree-style-highlights.xh-grid--max-depth-#{$i} {
      @for $level from 0 to 9 {
        $l: 18 - (math.div($level, ($i + 1)) * 11);

        .ag-row.ag-row-level-#{$level}:not(.ag-row-level-#{$i}) {
          &:not(.ag-row-selected),
          &.ag-row.ag-row-odd:not(.ag-full-width-row):not(.ag-row-selected) {
            background-color: hsl(200, 50%, $l * 1%);
          }
        }
      }

      .xh-ag-grid--show-hover {
        .ag-row:not(.ag-row-level-#{$i}) {
          &.ag-row.ag-row-hover:not(.ag-full-width-row):not(.ag-row-selected):not(.ag-row-pinned) {
            background-color: var(--xh-grid-bg-hover);
          }
        }
      }
    }

    // With colors
    &.xh-grid--tree-style-colors.xh-grid--max-depth-#{$i} {
      .ag-floating-bottom,
      .ag-floating-top {
        background-color: var(--xh-grid-tree-group-color-level-0);
      }

      @for $level from 0 to 9 {
        .ag-row.ag-row-level-#{$level}:not(.ag-row-level-#{$i}) {
          &:not(.ag-row-selected),
          &.ag-row.ag-row-odd:not(.ag-full-width-row):not(.ag-row-selected) {
            background-color: var(--xh-grid-tree-group-color-level-#{$level});
          }
        }
      }
    }
  }
}

//------------------------
// Row highlight
//------------------------
.xh-grid--highlight-row-on-click .xh-ag-grid .ag-row .ag-cell-data-changed {
  background-color: var(--xh-grid-selected-row-bg) !important;
}

//------------------------
// Tooltips
//------------------------
.xh-grid-tooltip {
  position: absolute;

  &.ag-tooltip-hiding,
  &:empty {
    display: none;
  }

  // Default minimal styling. Not applied when using a custom tooltip.
  // Uses pre-wrap to honor intentional \n line breaks in tooltip content
  // while still wrapping long lines at the max-width boundary.
  &--default {
    padding: var(--xh-grid-tooltip-padding);
    background: var(--xh-grid-tooltip-bg);
    border: var(--xh-grid-tooltip-border);
    border-radius: var(--xh-grid-tooltip-border-radius);
    max-width: var(--xh-grid-tooltip-max-width);
    white-space: pre-wrap;
  }

  // Validation tooltip styling. Adjust depending on if within a default or custom tooltip.
  &--validation {
    margin: 0;

    &--single {
      list-style-type: none;
    }
  }

  &--default > div > .xh-grid-tooltip--validation {
    padding: 0 var(--xh-pad-half-px) 0 2em;

    &--single {
      padding: 0 var(--xh-pad-half-px);
    }
  }

  &--custom > div > .xh-grid-tooltip--validation {
    padding: var(--xh-grid-tooltip-padding) var(--xh-grid-tooltip-padding)
      var(--xh-grid-tooltip-padding) 2em;
    background: var(--xh-grid-tooltip-bg);
    border: var(--xh-grid-tooltip-border);

    &--single {
      padding: var(--xh-grid-tooltip-padding);
    }
  }
}

//-----------
// Autosize
//-----------
.xh-grid-autosize-canvas {
  position: absolute;
  display: none;
}

.xh-grid-autosize-cell {
  padding: 0 var(--xh-grid-cell-lr-pad-px);
  font-size: var(--xh-grid-font-size-px);
  font-family: var(--xh-grid-font-family);
  visibility: hidden;
  display: none;
  white-space: nowrap;

  // This property is not actually used in rendering, but is provided here
  // for later interpretation by GridAutosizeService.getIndentation()
  left: var(--xh-grid-tree-indent);

  &--active {
    display: inline-block;
  }

  &--large {
    font-size: var(--xh-grid-large-font-size-px);
    padding: 0 var(--xh-grid-large-cell-lr-pad-px);
  }

  &--compact {
    font-size: var(--xh-grid-compact-font-size-px);
    padding: 0 var(--xh-grid-compact-cell-lr-pad-px);
  }

  &--tiny {
    font-size: var(--xh-grid-tiny-font-size-px);
    padding: 0 var(--xh-grid-tiny-cell-lr-pad-px);
  }
}

.xh-grid-autosize-header {
  padding: 0 var(--xh-grid-header-lr-pad-px);
  font-size: var(--xh-grid-header-font-size-px);
  font-weight: var(--xh-grid-header-font-weight);
  font-family: var(--xh-grid-header-font-family);
  flex-direction: row;
  visibility: hidden;
  display: none;
  white-space: nowrap;

  .xh-grid-header-sort-icon,
  .xh-grid-header-menu-icon {
    width: var(--xh-grid-header-icon-width);
    display: none;
  }

  &--active {
    display: inline-flex;
  }

  &--sort .xh-grid-header-sort-icon {
    display: block;
  }

  &--menu .xh-grid-header-menu-icon {
    display: block;
  }

  &--large {
    font-size: var(--xh-grid-large-header-font-size-px);
    padding: 0 var(--xh-grid-large-header-lr-pad-px);
  }

  &--compact {
    font-size: var(--xh-grid-compact-header-font-size-px);
    padding: 0 var(--xh-grid-compact-header-lr-pad-px);
  }

  &--tiny {
    font-size: var(--xh-grid-tiny-header-font-size-px);
    padding: 0 var(--xh-grid-tiny-header-lr-pad-px);
  }
}

.xh-grid-menu-option {
  &--intent-success {
    color: var(--xh-intent-success-darker);
  }
  &--intent-primary {
    color: var(--xh-intent-primary-darker);
  }
  &--intent-warning {
    color: var(--xh-intent-warning-darker);
  }
  &--intent-danger {
    color: var(--xh-intent-danger-darker);
  }

  // Dark theme
  .xh-dark & {
    &--intent-success {
      color: var(--xh-intent-success-lighter);
    }

    &--intent-primary {
      color: var(--xh-intent-primary-lighter);
    }

    &--intent-warning {
      color: var(--xh-intent-warning-lighter);
    }

    &--intent-danger {
      color: var(--xh-intent-danger-lighter);
    }
  }
}
