/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import '@polymer/iron-input/iron-input';
import '../../../styles/shared-styles';
import '../gr-button/gr-button';
import '../gr-select/gr-select';
import {DiffPreferencesInfo, IgnoreWhitespaceType} from '../../../types/diff';
import {getAppContext} from '../../../services/app-context';
import {subscribe} from '../../lit/subscription-controller';
import {formStyles} from '../../../styles/gr-form-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, html} from 'lit';
import {customElement, query, state} from 'lit/decorators';
import {convertToString} from '../../../utils/string-util';
import {fire} from '../../../utils/event-util';
import {ValueChangedEvent} from '../../../types/events';
import {GrSelect} from '../gr-select/gr-select';

@customElement('gr-diff-preferences')
export class GrDiffPreferences extends LitElement {
  @query('#contextLineSelect') private contextLineSelect?: HTMLInputElement;

  @query('#columnsInput') private columnsInput?: HTMLInputElement;

  @query('#tabSizeInput') private tabSizeInput?: HTMLInputElement;

  @query('#fontSizeInput') private fontSizeInput?: HTMLInputElement;

  @query('#lineWrappingInput') private lineWrappingInput?: HTMLInputElement;

  @query('#showTabsInput') private showTabsInput?: HTMLInputElement;

  @query('#showTrailingWhitespaceInput')
  private showTrailingWhitespaceInput?: HTMLInputElement;

  @query('#automaticReviewInput')
  private automaticReviewInput?: HTMLInputElement;

  @query('#syntaxHighlightInput')
  private syntaxHighlightInput?: HTMLInputElement;

  @query('#ignoreWhiteSpace') private ignoreWhiteSpace?: HTMLInputElement;

  // Used in gr-diff-preferences-dialog
  @query('#contextSelect') contextSelect?: GrSelect;

  @state() diffPrefs?: DiffPreferencesInfo;

  @state() private originalDiffPrefs?: DiffPreferencesInfo;

  private readonly userModel = getAppContext().userModel;

  override connectedCallback() {
    super.connectedCallback();
    subscribe(this, this.userModel.diffPreferences$, diffPreferences => {
      if (!diffPreferences) return;
      this.originalDiffPrefs = diffPreferences;
      this.diffPrefs = {...diffPreferences};
    });
  }

  static override get styles() {
    return [sharedStyles, formStyles];
  }

  override render() {
    return html`
      <div id="diffPreferences" class="gr-form-styles">
        <section>
          <label for="contextLineSelect" class="title">Context</label>
          <span class="value">
            <gr-select
              id="contextSelect"
              .bindValue=${convertToString(this.diffPrefs?.context)}
              @change=${this.handleDiffContextChanged}
            >
              <select id="contextLineSelect">
                <option value="3">3 lines</option>
                <option value="10">10 lines</option>
                <option value="25">25 lines</option>
                <option value="50">50 lines</option>
                <option value="75">75 lines</option>
                <option value="100">100 lines</option>
                <option value="-1">Whole file</option>
              </select>
            </gr-select>
          </span>
        </section>
        <section>
          <label for="lineWrappingInput" class="title">Fit to screen</label>
          <span class="value">
            <input
              id="lineWrappingInput"
              type="checkbox"
              ?checked=${this.diffPrefs?.line_wrapping}
              @change=${this.handleLineWrappingTap}
            />
          </span>
        </section>
        <section>
          <label for="columnsInput" class="title">Diff width</label>
          <span class="value">
            <iron-input
              .allowedPattern=${'[0-9]'}
              .bindValue=${convertToString(this.diffPrefs?.line_length)}
              @change=${this.handleDiffLineLengthChanged}
            >
              <input id="columnsInput" type="number" />
            </iron-input>
          </span>
        </section>
        <section>
          <label for="tabSizeInput" class="title">Tab width</label>
          <span class="value">
            <iron-input
              .allowedPattern=${'[0-9]'}
              .bindValue=${convertToString(this.diffPrefs?.tab_size)}
              @change=${this.handleDiffTabSizeChanged}
            >
              <input id="tabSizeInput" type="number" />
            </iron-input>
          </span>
        </section>
        <section>
          <label for="fontSizeInput" class="title">Font size</label>
          <span class="value">
            <iron-input
              .allowedPattern=${'[0-9]'}
              .bindValue=${convertToString(this.diffPrefs?.font_size)}
              @change=${this.handleDiffFontSizeChanged}
            >
              <input id="fontSizeInput" type="number" />
            </iron-input>
          </span>
        </section>
        <section>
          <label for="showTabsInput" class="title">Show tabs</label>
          <span class="value">
            <input
              id="showTabsInput"
              type="checkbox"
              ?checked=${this.diffPrefs?.show_tabs}
              @change=${this.handleShowTabsTap}
            />
          </span>
        </section>
        <section>
          <label for="showTrailingWhitespaceInput" class="title"
            >Show trailing whitespace</label
          >
          <span class="value">
            <input
              id="showTrailingWhitespaceInput"
              type="checkbox"
              ?checked=${this.diffPrefs?.show_whitespace_errors}
              @change=${this.handleShowTrailingWhitespaceTap}
            />
          </span>
        </section>
        <section>
          <label for="syntaxHighlightInput" class="title"
            >Syntax highlighting</label
          >
          <span class="value">
            <input
              id="syntaxHighlightInput"
              type="checkbox"
              ?checked=${this.diffPrefs?.syntax_highlighting}
              @change=${this.handleSyntaxHighlightTap}
            />
          </span>
        </section>
        <section>
          <label for="automaticReviewInput" class="title"
            >Automatically mark viewed files reviewed</label
          >
          <span class="value">
            <input
              id="automaticReviewInput"
              type="checkbox"
              ?checked=${!this.diffPrefs?.manual_review}
              @change=${this.handleAutomaticReviewTap}
            />
          </span>
        </section>
        <section>
          <div class="pref">
            <label for="ignoreWhiteSpace" class="title"
              >Ignore Whitespace</label
            >
            <span class="value">
              <gr-select
                .bindValue=${convertToString(this.diffPrefs?.ignore_whitespace)}
                @change=${this.handleDiffIgnoreWhitespaceChanged}
              >
                <select id="ignoreWhiteSpace">
                  <option value="IGNORE_NONE">None</option>
                  <option value="IGNORE_TRAILING">Trailing</option>
                  <option value="IGNORE_LEADING_AND_TRAILING">
                    Leading &amp; trailing
                  </option>
                  <option value="IGNORE_ALL">All</option>
                </select>
              </gr-select>
            </span>
          </div>
        </section>
      </div>
    `;
  }

  private readonly handleDiffContextChanged = () => {
    this.diffPrefs!.context = Number(this.contextLineSelect!.value);
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  private readonly handleLineWrappingTap = () => {
    this.diffPrefs!.line_wrapping = this.lineWrappingInput!.checked;
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  private readonly handleDiffLineLengthChanged = () => {
    this.diffPrefs!.line_length = Number(this.columnsInput!.value);
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  private readonly handleDiffTabSizeChanged = () => {
    this.diffPrefs!.tab_size = Number(this.tabSizeInput!.value);
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  private readonly handleDiffFontSizeChanged = () => {
    this.diffPrefs!.font_size = Number(this.fontSizeInput!.value);
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  private readonly handleShowTabsTap = () => {
    this.diffPrefs!.show_tabs = this.showTabsInput!.checked;
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  // private but used in test
  readonly handleShowTrailingWhitespaceTap = () => {
    this.diffPrefs!.show_whitespace_errors =
      this.showTrailingWhitespaceInput!.checked;
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  private readonly handleSyntaxHighlightTap = () => {
    this.diffPrefs!.syntax_highlighting = this.syntaxHighlightInput!.checked;
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  private readonly handleAutomaticReviewTap = () => {
    this.diffPrefs!.manual_review = !this.automaticReviewInput!.checked;
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  private readonly handleDiffIgnoreWhitespaceChanged = () => {
    this.diffPrefs!.ignore_whitespace = this.ignoreWhiteSpace!
      .value as IgnoreWhitespaceType;
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  };

  hasUnsavedChanges() {
    // We have to wrap boolean values in Boolean() to ensure undefined values
    // use false rather than undefined.
    return (
      Boolean(this.originalDiffPrefs?.syntax_highlighting) !==
        Boolean(this.diffPrefs?.syntax_highlighting) ||
      this.originalDiffPrefs?.context !== this.diffPrefs?.context ||
      Boolean(this.originalDiffPrefs?.line_wrapping) !==
        Boolean(this.diffPrefs?.line_wrapping) ||
      this.originalDiffPrefs?.line_length !== this.diffPrefs?.line_length ||
      this.originalDiffPrefs?.tab_size !== this.diffPrefs?.tab_size ||
      this.originalDiffPrefs?.font_size !== this.diffPrefs?.font_size ||
      this.originalDiffPrefs?.ignore_whitespace !==
        this.diffPrefs?.ignore_whitespace ||
      Boolean(this.originalDiffPrefs?.show_tabs) !==
        Boolean(this.diffPrefs?.show_tabs) ||
      Boolean(this.originalDiffPrefs?.show_whitespace_errors) !==
        Boolean(this.diffPrefs?.show_whitespace_errors) ||
      Boolean(this.originalDiffPrefs?.manual_review) !==
        Boolean(this.diffPrefs?.manual_review)
    );
  }

  async save() {
    if (!this.diffPrefs) return;
    await this.userModel.updateDiffPreference(this.diffPrefs);
    fire(this, 'has-unsaved-changes-changed', {
      value: this.hasUnsavedChanges(),
    });
  }
}

declare global {
  interface HTMLElementEventMap {
    'has-unsaved-changes-changed': ValueChangedEvent<boolean>;
  }
  interface HTMLElementTagNameMap {
    'gr-diff-preferences': GrDiffPreferences;
  }
}
