/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {html, LitElement} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {
  DiffInfo,
  DiffLayer,
  DiffViewMode,
  MovedLinkClickedEventDetail,
  RenderPreferences,
  Side,
  LineNumber,
  DiffPreferencesInfo,
} from '../../../api/diff';
import {GrDiffGroup, GrDiffGroupType} from '../gr-diff/gr-diff-group';
import {
  countLines,
  diffClasses,
  getResponsiveMode,
} from '../gr-diff/gr-diff-utils';
import {GrDiffRow} from './gr-diff-row';
import '../gr-context-controls/gr-context-controls-section';
import '../gr-context-controls/gr-context-controls';
import '../gr-range-header/gr-range-header';
import './gr-diff-row';

@customElement('gr-diff-section')
export class GrDiffSection extends LitElement {
  @property({type: Object})
  group?: GrDiffGroup;

  @property({type: Object})
  diff?: DiffInfo;

  @property({type: Object})
  renderPrefs?: RenderPreferences;

  @property({type: Object})
  diffPrefs?: DiffPreferencesInfo;

  @property({type: Object})
  layers: DiffLayer[] = [];

  /**
   * Semantic DOM diff testing does not work with just table fragments, so when
   * running such tests the render() method has to wrap the DOM in a proper
   * <table> element.
   */
  @state()
  addTableWrapperForTesting = false;

  /**
   * The browser API for handling selection does not (yet) work for selection
   * across multiple shadow DOM elements. So we are rendering gr-diff components
   * into the light DOM instead of the shadow DOM by overriding this method,
   * which was the recommended workaround by the lit team.
   * See also https://github.com/WICG/webcomponents/issues/79.
   */
  override createRenderRoot() {
    return this;
  }

  override render() {
    if (!this.group) return;
    const extras: string[] = [];
    extras.push('section');
    extras.push(this.group.type);
    if (this.group.isTotal()) extras.push('total');
    if (this.group.dueToRebase) extras.push('dueToRebase');
    if (this.group.moveDetails) extras.push('dueToMove');
    if (this.group.moveDetails?.changed) extras.push('changed');
    if (this.group.ignoredWhitespaceOnly) extras.push('ignoredWhitespaceOnly');

    const pairs = this.getLinePairs();
    const responsiveMode = getResponsiveMode(this.diffPrefs, this.renderPrefs);
    const body = html`
      <tbody class=${diffClasses(...extras)}>
        ${this.renderContextControls()} ${this.renderMoveControls()}
        ${pairs.map(pair => {
          const leftCl = `left-${pair.left.lineNumber(Side.LEFT)}`;
          const rightCl = `right-${pair.right.lineNumber(Side.RIGHT)}`;
          return html`
            <gr-diff-row
              class="${leftCl} ${rightCl}"
              .left=${pair.left}
              .right=${pair.right}
              .layers=${this.layers}
              .lineLength=${this.diffPrefs?.line_length ?? 80}
              .tabSize=${this.diffPrefs?.tab_size ?? 2}
              .unifiedDiff=${this.isUnifiedDiff()}
              .responsiveMode=${responsiveMode}
            >
            </gr-diff-row>
          `;
        })}
      </tbody>
    `;
    if (this.addTableWrapperForTesting) {
      return html`<table>
        ${body}
      </table>`;
    }
    return body;
  }

  private isUnifiedDiff() {
    return this.renderPrefs?.view_mode === DiffViewMode.UNIFIED;
  }

  getLinePairs() {
    if (!this.group) return [];
    const isControl = this.group.type === GrDiffGroupType.CONTEXT_CONTROL;
    if (isControl) return [];
    return this.isUnifiedDiff()
      ? this.group.getUnifiedPairs()
      : this.group.getSideBySidePairs();
  }

  getDiffRows(): GrDiffRow[] {
    return [...this.querySelectorAll<GrDiffRow>('gr-diff-row')];
  }

  private renderContextControls() {
    if (this.group?.type !== GrDiffGroupType.CONTEXT_CONTROL) return;

    const leftStart = this.group.lineRange.left.start_line;
    const leftEnd = this.group.lineRange.left.end_line;
    const firstGroupIsSkipped = !!this.group.contextGroups[0].skip;
    const lastGroupIsSkipped =
      !!this.group.contextGroups[this.group.contextGroups.length - 1].skip;
    const lineCountLeft = countLines(this.diff, Side.LEFT);
    const containsWholeFile = lineCountLeft === leftEnd - leftStart + 1;
    const showAbove =
      (leftStart > 1 && !firstGroupIsSkipped) || containsWholeFile;
    const showBelow = leftEnd < lineCountLeft && !lastGroupIsSkipped;

    return html`
      <gr-context-controls-section
        .showAbove=${showAbove}
        .showBelow=${showBelow}
        .group=${this.group}
        .diff=${this.diff}
        .renderPrefs=${this.renderPrefs}
      >
      </gr-context-controls-section>
    `;
  }

  findRow(side: Side, lineNumber: LineNumber): GrDiffRow | undefined {
    return (
      this.querySelector<GrDiffRow>(`gr-diff-row.${side}-${lineNumber}`) ??
      undefined
    );
  }

  private renderMoveControls() {
    if (!this.group?.moveDetails) return;
    const movedIn = this.group.adds.length > 0;
    const plainCell = html`<td class=${diffClasses()}></td>`;
    const signCell = html`<td class=${diffClasses('sign')}></td>`;
    const lineNumberCell = html`
      <td class=${diffClasses('moveControlsLineNumCol')}></td>
    `;
    const moveCell = html`
      <td class=${diffClasses('moveHeader')}>
        <gr-range-header class=${diffClasses()} icon="gr-icons:move-item">
          ${this.renderMoveDescription(movedIn)}
        </gr-range-header>
      </td>
    `;
    return html`
      <tr
        class=${diffClasses('moveControls', movedIn ? 'movedIn' : 'movedOut')}
      >
        ${lineNumberCell} ${signCell} ${movedIn ? plainCell : moveCell}
        ${lineNumberCell} ${signCell} ${movedIn ? moveCell : plainCell}
      </tr>
    `;
  }

  private renderMoveDescription(movedIn: boolean) {
    if (this.group?.moveDetails?.range) {
      const {changed, range} = this.group.moveDetails;
      const otherSide = movedIn ? Side.LEFT : Side.RIGHT;
      const andChangedLabel = changed ? 'and changed ' : '';
      const direction = movedIn ? 'from' : 'to';
      const textLabel = `Moved ${andChangedLabel}${direction} lines `;
      return html`
        <div class=${diffClasses()}>
          <span class=${diffClasses()}>${textLabel}</span>
          ${this.renderMovedLineAnchor(range.start, otherSide)}
          <span class=${diffClasses()}> - </span>
          ${this.renderMovedLineAnchor(range.end, otherSide)}
        </div>
      `;
    }

    return html`
      <div class=${diffClasses()}>
        <span class=${diffClasses()}
          >${movedIn ? 'Moved in' : 'Moved out'}</span
        >
      </div>
    `;
  }

  private renderMovedLineAnchor(line: number, side: Side) {
    const listener = (e: MouseEvent) => {
      e.preventDefault();
      this.handleMovedLineAnchorClick(e.target, side, line);
    };
    // `href` is not actually used but important for Screen Readers
    return html`
      <a class=${diffClasses()} href=${`#${line}`} @click=${listener}
        >${line}</a
      >
    `;
  }

  private handleMovedLineAnchorClick(
    anchor: EventTarget | null,
    side: Side,
    line: number
  ) {
    anchor?.dispatchEvent(
      new CustomEvent<MovedLinkClickedEventDetail>('moved-link-clicked', {
        detail: {
          lineNum: line,
          side,
        },
        composed: true,
        bubbles: true,
      })
    );
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-diff-section': GrDiffSection;
  }
}
