/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/paper-button/paper-button';
import '@polymer/paper-tooltip/paper-tooltip';
import {EMPTY, of, Subject} from 'rxjs';
import {delay, switchMap} from 'rxjs/operators';
import '../../../elements/shared/gr-button/gr-button';
import {pluralize} from '../../../utils/string-util';
import {fire} from '../../../utils/event-util';
import {assertIsDefined} from '../../../utils/common-util';
import {
  css,
  html,
  LitElement,
  nothing,
  PropertyValues,
  TemplateResult,
} from 'lit';
import {property, state} from 'lit/decorators.js';
import {subscribe} from '../../../elements/lit/subscription-controller';
import {
  ContextButtonType,
  DiffContextButtonHoveredDetail,
  RenderPreferences,
  SyntaxBlock,
} from '../../../api/diff';
import {
  GrDiffGroup,
  GrDiffGroupType,
  hideInContextControl,
} from '../gr-diff/gr-diff-group';
import {resolve} from '../../../models/dependency';
import {diffModelToken} from '../gr-diff-model/gr-diff-model';

declare global {
  interface HTMLElementEventMap {
    'diff-context-button-hovered': CustomEvent<DiffContextButtonHoveredDetail>;
  }
}

const PARTIAL_CONTEXT_AMOUNT = 10;

/**
 * Traverses a hierarchical structure of syntax blocks and
 * finds the most local/nested block that can be associated line.
 * It finds the closest block that contains the whole line and
 * returns the whole path from the syntax layer (blocks) sent as parameter
 * to the most nested block - the complete path from the top to bottom layer of
 * a syntax tree. Example: [myNamespace, MyClass, myMethod1, aLocalFunctionInsideMethod1]
 *
 * @param lineNum line number for the targeted line.
 * @param blocks Blocks for a specific syntax level in the file (to allow recursive calls)
 */
function findBlockTreePathForLine(
  lineNum: number,
  blocks?: SyntaxBlock[]
): SyntaxBlock[] {
  const containingBlock = blocks?.find(
    ({range}) => range.start_line < lineNum && range.end_line > lineNum
  );
  if (!containingBlock) return [];
  const innerPathInChild = findBlockTreePathForLine(
    lineNum,
    containingBlock?.children
  );
  return [containingBlock].concat(innerPathInChild);
}

/**
 * 'above': Typically only for the context controls at the end of a file. So
 *          only show buttons "above" the middle line of the context control
 *          section.
 * 'below': Typically only for the context controls at the beginning of a file.
 *          So only show buttons "below" the middle line of the context control
 *          section.
 * 'both': Typically for the context controls in the middle of a file. So show
 *         two buttons, one for expanding from the top and one for expanding
 *         from the bottom.
 */
export type GrContextControlsShowConfig = 'above' | 'below' | 'both';

export function getShowConfig(group?: GrDiffGroup, lineCountLeft = 0) {
  const above = showAbove(group, lineCountLeft);
  const below = showBelow(group, lineCountLeft);

  if (above && !below) return 'above';
  if (!above && below) return 'below';

  // Note that !showAbove && !showBelow also intentionally returns 'both'.
  // This means the file is completely collapsed, which is unusual, but at least
  // happens in one test.
  return 'both';
}

/** See GrContextControlsShowConfig for explanation of "above". */
export function showAbove(group?: GrDiffGroup, lineCountLeft = 0) {
  if (group?.type !== GrDiffGroupType.CONTEXT_CONTROL) return false;

  // Note that we could as well use `right.start_line` here. And below we only
  // use `left`, because we are comparing with `lineCountLeft`. But that is
  // just an arbitrary choice.
  const leftStart = group.lineRange.left.start_line;
  const firstGroupIsSkipped = !!group.contextGroups[0].skip;
  if (leftStart > 1 && !firstGroupIsSkipped) return true;

  const leftEnd = group.lineRange.left.end_line;
  const containsWholeFile = lineCountLeft === leftEnd - leftStart + 1;
  return containsWholeFile;
}

/** See GrContextControlsShowConfig for explanation of "below". */
export function showBelow(group?: GrDiffGroup, lineCountLeft = 0) {
  if (group?.type !== GrDiffGroupType.CONTEXT_CONTROL) return false;

  // Note that we could as well use `right.start_line` here. But we would then
  // require a `lineCountRight` parameter for making the comparison.
  const leftEnd = group.lineRange.left.end_line;
  const lastGroupIsSkipped =
    !!group.contextGroups[group.contextGroups.length - 1].skip;

  return leftEnd < lineCountLeft && !lastGroupIsSkipped;
}

/**
 * Renders context control buttons such as "+23 lines" or "+Block". It is only
 * meant to be used to be rendered into a diff table cell of its parent
 * component <gr-context-controls-section>.
 */
export class GrContextControls extends LitElement {
  @property({type: Object}) group?: GrDiffGroup;

  // This is just a property (and not a state), because we want to "reflect".
  @property({type: String, reflect: true})
  showConfig: GrContextControlsShowConfig = 'both';

  @state() syntaxTreeRight?: SyntaxBlock[];

  @state() renderPreferences?: RenderPreferences;

  @state() lineCountLeft = 0;

  private readonly getDiffModel = resolve(this, diffModelToken);

  private expandButtonsHover = new Subject<{
    eventType: 'enter' | 'leave';
    buttonType: ContextButtonType;
    linesToExpand: number;
  }>();

  static override get styles() {
    return [
      css`
        :host {
          display: flex;
          justify-content: center;
          flex-direction: column;
          position: relative;
        }

        :host([showConfig='above']) {
          justify-content: flex-end;
          margin-top: calc(-1px - var(--line-height-normal) - var(--spacing-s));
          margin-bottom: var(--gr-context-controls-margin-bottom);
          height: calc(var(--line-height-normal) + var(--spacing-s));
          .horizontalFlex {
            align-items: end;
          }
        }

        :host([showConfig='below']) {
          justify-content: flex-start;
          margin-top: 1px;
          margin-bottom: calc(
            0px - var(--line-height-normal) - var(--spacing-s)
          );
          .horizontalFlex {
            align-items: start;
          }
        }

        :host([showConfig='both']) {
          margin-top: calc(0px - var(--line-height-normal) - var(--spacing-s));
          margin-bottom: calc(
            0px - var(--line-height-normal) - var(--spacing-s)
          );
          height: calc(
            2 * var(--line-height-normal) + 2 * var(--spacing-s) +
              var(--divider-height)
          );
          .horizontalFlex {
            align-items: center;
          }
        }

        .contextControlButton {
          background-color: var(--default-button-background-color);
          font: var(--context-control-button-font, inherit);
        }

        paper-button {
          text-transform: none;
          align-items: center;
          background-color: var(--background-color);
          font-family: inherit;
          margin: var(--margin, 0);
          min-width: var(--border, 0);
          color: var(--diff-context-control-color);
          border: solid var(--border-color);
          border-width: 1px;
          border-radius: var(--border-radius);
          padding: var(--spacing-s) var(--spacing-l);
        }

        paper-button:hover {
          /* same as defined in gr-button */
          background: rgba(0, 0, 0, 0.12);
        }
        paper-button:focus-visible {
          /* paper-button sets this to 0, thus preventing focus-based styling. */
          outline-width: 1px;
        }

        .aboveBelowButtons {
          display: flex;
          flex-direction: column;
          justify-content: center;
          margin-left: var(--spacing-m);
          position: relative;
        }
        .aboveBelowButtons:first-child {
          margin-left: 0;
          /* Places a default background layer behind the "all button" that can have opacity */
          background-color: var(--default-button-background-color);
        }

        .horizontalFlex {
          display: flex;
          justify-content: center;
          align-items: var(
            --gr-context-controls-horizontal-align-items,
            center
          );
        }

        .aboveButton {
          border-bottom-width: 0;
          border-bottom-right-radius: 0;
          border-bottom-left-radius: 0;
          padding: var(--spacing-xxs) var(--spacing-l);
        }
        .belowButton {
          border-top-width: 0;
          border-top-left-radius: 0;
          border-top-right-radius: 0;
          padding: var(--spacing-xxs) var(--spacing-l);
          margin-top: calc(var(--divider-height) + 2 * var(--spacing-xxs));
        }
        .belowButton:first-child {
          margin-top: 0;
        }
        .breadcrumbTooltip {
          white-space: nowrap;
        }
        .unrelatedChanges {
          color: var(--primary-button-text-color);
          background-color: var(--primary-button-background-color);

          &:hover {
            // TODO(anuragpathak): Update hover colors as per specification.
            color: var(--primary-button-text-color);
            background-color: var(--primary-button-background-color);
          }
        }
      `,
    ];
  }

  constructor() {
    super();
    this.setupButtonHoverHandler();
    subscribe(
      this,
      () => this.getDiffModel().syntaxTreeRight$,
      syntaxTree => (this.syntaxTreeRight = syntaxTree)
    );
    subscribe(
      this,
      () => this.getDiffModel().renderPrefs$,
      renderPrefs => (this.renderPreferences = renderPrefs)
    );
    subscribe(
      this,
      () => this.getDiffModel().lineCountLeft$,
      lineCountLeft => {
        this.lineCountLeft = lineCountLeft;
        this.updateShowConfig();
      }
    );
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('group')) this.updateShowConfig();
  }

  private updateShowConfig() {
    this.showConfig = getShowConfig(this.group, this.lineCountLeft);
  }

  private showBoth() {
    return this.showConfig === 'both';
  }

  private showAbove() {
    return this.showBoth() || this.showConfig === 'above';
  }

  private showBelow() {
    return this.showBoth() || this.showConfig === 'below';
  }

  private setupButtonHoverHandler() {
    subscribe(
      this,
      () =>
        this.expandButtonsHover.pipe(
          switchMap(e => {
            if (e.eventType === 'leave') {
              // cancel any previous delay
              // for mouse enter
              return EMPTY;
            }
            return of(e).pipe(delay(500));
          })
        ),
      ({buttonType, linesToExpand}) => {
        fire(this, 'diff-context-button-hovered', {
          buttonType,
          linesToExpand,
        });
      }
    );
  }

  private numLines() {
    assertIsDefined(this.group);
    // In context groups, there is the same number of lines left and right
    const left = this.group.lineRange.left;
    // Both start and end inclusive, so we need to add 1.
    return left.end_line - left.start_line + 1;
  }

  private createExpandAllButtonContainer() {
    return html` <div class="aboveBelowButtons fullExpansion">
      ${this.createContextButton(ContextButtonType.ALL, this.numLines())}
    </div>`;
  }

  /**
   * Creates a specific expansion button (e.g. +X common lines, +10, +Block).
   */
  private createContextButton(
    type: ContextButtonType,
    linesToExpand: number,
    tooltip?: TemplateResult
  ) {
    if (!this.group) return;
    let text = '';
    let groups: GrDiffGroup[] = []; // The groups that replace this one if tapped.
    let ariaLabel = '';
    let classes = 'contextControlButton showContext ';

    if (type === ContextButtonType.ALL) {
      if (this.group.hasNonCommonDeltaGroup()) {
        text = '+ Unrelated changes';
        ariaLabel = 'Show unrelated changes';
        classes += ' unrelatedChanges ';
      } else {
        text = `+${pluralize(linesToExpand, 'common line')}`;
        ariaLabel = `Show ${pluralize(linesToExpand, 'common line')}`;
      }
      classes += this.showBoth()
        ? 'centeredButton'
        : this.showAbove()
        ? 'aboveButton'
        : 'belowButton';
      if (this.group?.hasSkipGroup()) {
        // Expanding content would require load of more data
        text += ' (too large)';
      }
      groups.push(...this.group.contextGroups);
    } else if (type === ContextButtonType.ABOVE) {
      groups = hideInContextControl(
        this.group.contextGroups,
        linesToExpand,
        this.numLines()
      );
      text = `+${linesToExpand}`;
      classes += 'aboveButton';
      ariaLabel = `Show ${pluralize(linesToExpand, 'line')} above`;
    } else if (type === ContextButtonType.BELOW) {
      groups = hideInContextControl(
        this.group.contextGroups,
        0,
        this.numLines() - linesToExpand
      );
      text = `+${linesToExpand}`;
      classes += 'belowButton';
      ariaLabel = `Show ${pluralize(linesToExpand, 'line')} below`;
    } else if (type === ContextButtonType.BLOCK_ABOVE) {
      groups = hideInContextControl(
        this.group.contextGroups,
        linesToExpand,
        this.numLines()
      );
      text = '+Block';
      classes += 'aboveButton';
      ariaLabel = 'Show block above';
    } else if (type === ContextButtonType.BLOCK_BELOW) {
      groups = hideInContextControl(
        this.group.contextGroups,
        0,
        this.numLines() - linesToExpand
      );
      text = '+Block';
      classes += 'belowButton';
      ariaLabel = 'Show block below';
    }
    const expandHandler = this.createExpansionHandler(
      linesToExpand,
      type,
      groups
    );

    const mouseHandler = (eventType: 'enter' | 'leave') => {
      this.expandButtonsHover.next({
        eventType,
        buttonType: type,
        linesToExpand,
      });
    };

    const button = html` <paper-button
      class=${classes}
      aria-label=${ariaLabel}
      @click=${expandHandler}
      @mouseenter=${() => mouseHandler('enter')}
      @mouseleave=${() => mouseHandler('leave')}
    >
      <span class="showContext">${text}</span>
      ${tooltip}
    </paper-button>`;
    return button;
  }

  private createExpansionHandler(
    linesToExpand: number,
    type: ContextButtonType,
    groups: GrDiffGroup[]
  ) {
    return (e: Event) => {
      assertIsDefined(this.group);
      e.stopPropagation();
      if (type === ContextButtonType.ALL && this.group?.hasSkipGroup()) {
        fire(this, 'content-load-needed', {
          lineRange: this.group.lineRange,
        });
      } else {
        fire(this, 'diff-context-expanded', {
          numLines: this.numLines(),
          buttonType: type,
          expandedLines: linesToExpand,
        });
        fire(this, 'diff-context-expanded-internal-new', {
          contextGroup: this.group,
          groups,
          numLines: this.numLines(),
          buttonType: type,
          expandedLines: linesToExpand,
        });
      }
    };
  }

  private showPartialLinks() {
    return this.numLines() > PARTIAL_CONTEXT_AMOUNT;
  }

  /**
   * Creates a container div with partial (+10) expansion buttons (above and/or below).
   */
  private createPartialExpansionButtons() {
    if (!this.showPartialLinks() || this.group?.hasNonCommonDeltaGroup()) {
      return undefined;
    }
    let aboveButton;
    let belowButton;
    if (this.showAbove()) {
      aboveButton = this.createContextButton(
        ContextButtonType.ABOVE,
        PARTIAL_CONTEXT_AMOUNT
      );
    }
    if (this.showBelow()) {
      belowButton = this.createContextButton(
        ContextButtonType.BELOW,
        PARTIAL_CONTEXT_AMOUNT
      );
    }
    return aboveButton || belowButton
      ? html` <div class="aboveBelowButtons partialExpansion">
          ${aboveButton} ${belowButton}
        </div>`
      : undefined;
  }

  /**
   * Creates a container div with block expansion buttons (above and/or below).
   */
  private createBlockExpansionButtons() {
    assertIsDefined(this.group, 'group');
    if (
      !this.showPartialLinks() ||
      !this.renderPreferences?.use_block_expansion ||
      this.group?.hasSkipGroup() ||
      this.group?.hasNonCommonDeltaGroup()
    ) {
      return undefined;
    }
    let aboveBlockButton;
    let belowBlockButton;
    if (this.showAbove()) {
      aboveBlockButton = this.createBlockButton(
        ContextButtonType.BLOCK_ABOVE,
        this.group.lineRange.right.start_line - 1
      );
    }
    if (this.showBelow()) {
      belowBlockButton = this.createBlockButton(
        ContextButtonType.BLOCK_BELOW,
        this.group.lineRange.right.end_line + 1
      );
    }
    if (aboveBlockButton || belowBlockButton) {
      return html` <div class="aboveBelowButtons blockExpansion">
        ${aboveBlockButton} ${belowBlockButton}
      </div>`;
    }
    return undefined;
  }

  private createBlockButtonTooltip(
    buttonType: ContextButtonType,
    syntaxPath: SyntaxBlock[],
    linesToExpand: number
  ) {
    // Create breadcrumb string:
    // myNamespace > MyClass > myMethod1 > aLocalFunctionInsideMethod1 > (anonymous)
    const tooltipText = syntaxPath.length
      ? syntaxPath.map(b => b.name || '(anonymous)').join(' > ')
      : `${linesToExpand} common lines`;

    const position =
      buttonType === ContextButtonType.BLOCK_ABOVE ? 'top' : 'bottom';
    return html`<paper-tooltip offset="10" position=${position}
      ><div class="breadcrumbTooltip">${tooltipText}</div></paper-tooltip
    >`;
  }

  /**
   * Creates a "expand until end of block" button. This is based on syntax tree
   * information for the *right* side of the diff.
   */
  private createBlockButton(
    buttonType: ContextButtonType,
    referenceLineRight: number
  ) {
    if (this.syntaxTreeRight === undefined) return;
    const outlineSyntaxPath = findBlockTreePathForLine(
      referenceLineRight,
      this.syntaxTreeRight
    );
    let linesToExpand = this.numLines();
    if (outlineSyntaxPath.length) {
      const {range} = outlineSyntaxPath[outlineSyntaxPath.length - 1];
      const targetLine =
        buttonType === ContextButtonType.BLOCK_ABOVE
          ? range.end_line
          : range.start_line;
      const distanceToTargetLine = Math.abs(targetLine - referenceLineRight);
      if (distanceToTargetLine < this.numLines()) {
        linesToExpand = distanceToTargetLine;
      }
    }
    const tooltip = this.createBlockButtonTooltip(
      buttonType,
      outlineSyntaxPath,
      linesToExpand
    );
    return this.createContextButton(buttonType, linesToExpand, tooltip);
  }

  override render() {
    if (!this.group) return nothing;
    return html`
      <div class="horizontalFlex">
        ${this.createExpandAllButtonContainer()}
        ${this.createPartialExpansionButtons()}
        ${this.createBlockExpansionButtons()}
      </div>
    `;
  }
}

customElements.define('gr-context-controls', GrContextControls);

declare global {
  interface HTMLElementTagNameMap {
    'gr-context-controls': GrContextControls;
  }
}
