/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/paper-button/paper-button';
import '@polymer/paper-card/paper-card';
import '@polymer/paper-checkbox/paper-checkbox';
import '@polymer/paper-dropdown-menu/paper-dropdown-menu';
import '@polymer/paper-fab/paper-fab';
import '@polymer/paper-icon-button/paper-icon-button';
import '@polymer/paper-item/paper-item';
import '@polymer/paper-listbox/paper-listbox';
import '@polymer/paper-tooltip/paper-tooltip';
import {of, EMPTY, Subject} from 'rxjs';
import {switchMap, delay} 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;
  }
}
