/**
 * @license
 * Copyright 2018 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {Subscription} from 'rxjs';
import '@polymer/iron-a11y-announcer/iron-a11y-announcer';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-icon/gr-icon';
import '../../shared/gr-tooltip-content/gr-tooltip-content';
import {DiffViewMode} from '../../../constants/constants';
import {customElement, property, state} from 'lit/decorators.js';
import {fireIronAnnounce} from '../../../utils/event-util';
import {browserModelToken} from '../../../models/browser/browser-model';
import {resolve} from '../../../models/dependency';
import {css, html, LitElement} from 'lit';
import {sharedStyles} from '../../../styles/shared-styles';
import {userModelToken} from '../../../models/user/user-model';
import {ironAnnouncerRequestAvailability} from '../../polymer-util';

@customElement('gr-diff-mode-selector')
export class GrDiffModeSelector extends LitElement {
  /**
   * If set to true, the user's preference will be updated every time a
   * button is tapped. Don't set to true if there is no user.
   */
  @property({type: Boolean}) saveOnChange = false;

  @property({type: Boolean, attribute: 'show-tooltip-below'})
  showTooltipBelow = false;

  // visible for testing
  @state() mode: DiffViewMode = DiffViewMode.SIDE_BY_SIDE;

  private readonly getBrowserModel = resolve(this, browserModelToken);

  private readonly getUserModel = resolve(this, userModelToken);

  private subscriptions: Subscription[] = [];

  constructor() {
    super();
  }

  override connectedCallback() {
    super.connectedCallback();
    ironAnnouncerRequestAvailability();
    this.subscriptions.push(
      this.getBrowserModel().diffViewMode$.subscribe(
        diffView => (this.mode = diffView)
      )
    );
  }

  override disconnectedCallback() {
    for (const s of this.subscriptions) {
      s.unsubscribe();
    }
    this.subscriptions = [];
    super.disconnectedCallback();
  }

  static override get styles() {
    return [
      sharedStyles,
      css`
        :host {
          /* Used to remove horizontal whitespace between the icons. */
          display: flex;
        }
        gr-button.selected gr-icon {
          color: var(--link-color);
        }
        gr-icon {
          font-size: 1.3rem;
        }
      `,
    ];
  }

  override render() {
    return html`
      <gr-tooltip-content
        has-tooltip
        title="Side-by-side diff"
        ?position-below=${this.showTooltipBelow}
      >
        <gr-button
          id="sideBySideBtn"
          link
          class=${this.computeSideBySideSelected()}
          aria-pressed=${this.isSideBySideSelected()}
          aria-label="Side-by-side diff"
          @click=${this.handleSideBySideTap}
        >
          <gr-icon icon="view_column_2" filled aria-hidden="true"></gr-icon>
        </gr-button>
      </gr-tooltip-content>
      <gr-tooltip-content
        has-tooltip
        ?position-below=${this.showTooltipBelow}
        title="Unified diff"
      >
        <gr-button
          id="unifiedBtn"
          link
          class=${this.computeUnifiedSelected()}
          aria-pressed=${this.isUnifiedSelected()}
          aria-label="Unified diff"
          @click=${this.handleUnifiedTap}
        >
          <gr-icon icon="calendar_view_day" filled aria-hidden="true"></gr-icon>
        </gr-button>
      </gr-tooltip-content>
    `;
  }

  /**
   * Set the mode. If save on change is enabled also update the preference.
   */
  private setMode(newMode: DiffViewMode) {
    if (this.saveOnChange && this.mode && this.mode !== newMode) {
      this.getUserModel().updatePreferences({diff_view: newMode});
    }
    this.mode = newMode;
    let announcement;
    if (this.isUnifiedSelected()) {
      announcement = 'Changed diff view to unified';
    } else if (this.isSideBySideSelected()) {
      announcement = 'Changed diff view to side by side';
    }
    if (announcement) {
      fireIronAnnounce(this, announcement);
    }
  }

  private computeSideBySideSelected() {
    return this.mode === DiffViewMode.SIDE_BY_SIDE ? 'selected' : '';
  }

  private computeUnifiedSelected() {
    return this.mode === DiffViewMode.UNIFIED ? 'selected' : '';
  }

  private isSideBySideSelected() {
    return this.mode === DiffViewMode.SIDE_BY_SIDE;
  }

  private isUnifiedSelected() {
    return this.mode === DiffViewMode.UNIFIED;
  }

  private handleSideBySideTap() {
    this.setMode(DiffViewMode.SIDE_BY_SIDE);
  }

  private handleUnifiedTap() {
    this.setMode(DiffViewMode.UNIFIED);
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-diff-mode-selector': GrDiffModeSelector;
  }
}
