/**
 * @license
 * Copyright 2024 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/iron-input/iron-input';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-select/gr-select';
import {AccountDetailInfo, PreferencesInput} from '../../../types/common';
import {grFormStyles} from '../../../styles/gr-form-styles';
import {menuPageStyles} from '../../../styles/gr-menu-page-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, html, css, nothing} from 'lit';
import {customElement, query, state} from 'lit/decorators.js';
import {convertToString} from '../../../utils/string-util';
import {subscribe} from '../../lit/subscription-controller';
import {resolve} from '../../../models/dependency';
import {userModelToken} from '../../../models/user/user-model';
import {
  AppTheme,
  DateFormat,
  DiffViewMode,
  EmailFormat,
  EmailStrategy,
  TimeFormat,
} from '../../../constants/constants';
import {getAppContext} from '../../../services/app-context';
import {KnownExperimentId} from '../../../services/flags/flags';
import {areNotificationsEnabled} from '../../../utils/worker-util';
import {getDocUrl} from '../../../utils/url-util';
import {configModelToken} from '../../../models/config/config-model';
import {SuggestionsProvider} from '../../../api/suggestions';
import {pluginLoaderToken} from '../../shared/gr-js-api-interface/gr-plugin-loader';

/**
 * This provides an interface to show settings for a user profile
 * as defined in PreferencesInfo.
 */
@customElement('gr-preferences')
export class GrPreferences extends LitElement {
  @query('#themeSelect') themeSelect!: HTMLInputElement;

  @query('#changesPerPageSelect') changesPerPageSelect!: HTMLInputElement;

  @query('#dateTimeFormatSelect') dateTimeFormatSelect!: HTMLInputElement;

  @query('#timeFormatSelect') timeFormatSelect!: HTMLInputElement;

  @query('#emailNotificationsSelect')
  emailNotificationsSelect!: HTMLInputElement;

  @query('#emailFormatSelect') emailFormatSelect!: HTMLInputElement;

  @query('#allowBrowserNotifications')
  allowBrowserNotifications?: HTMLInputElement;

  @query('#allowSuggestCodeWhileCommenting')
  allowSuggestCodeWhileCommenting?: HTMLInputElement;

  @query('#allowAiCommentAutocompletion')
  allowAiCommentAutocompletion?: HTMLInputElement;

  @query('#defaultBaseForMergesSelect')
  defaultBaseForMergesSelect!: HTMLInputElement;

  @query('#relativeDateInChangeTable')
  relativeDateInChangeTable!: HTMLInputElement;

  @query('#diffViewSelect') diffViewSelect!: HTMLInputElement;

  @query('#showSizeBarsInFileList') showSizeBarsInFileList!: HTMLInputElement;

  @query('#publishCommentsOnPush') publishCommentsOnPush!: HTMLInputElement;

  @query('#workInProgressByDefault') workInProgressByDefault!: HTMLInputElement;

  @query('#disableKeyboardShortcuts')
  disableKeyboardShortcuts!: HTMLInputElement;

  @query('#disableTokenHighlighting')
  disableTokenHighlighting!: HTMLInputElement;

  @query('#insertSignedOff') insertSignedOff!: HTMLInputElement;

  @state() prefs?: PreferencesInput;

  @state() private originalPrefs?: PreferencesInput;

  @state() account?: AccountDetailInfo;

  @state() private docsBaseUrl = '';

  @state()
  suggestionsProvider?: SuggestionsProvider;

  readonly getUserModel = resolve(this, userModelToken);

  private readonly getConfigModel = resolve(this, configModelToken);

  private readonly getPluginLoader = resolve(this, pluginLoaderToken);

  // private but used in test
  readonly flagsService = getAppContext().flagsService;

  constructor() {
    super();
    subscribe(
      this,
      () => this.getUserModel().preferences$,
      prefs => {
        this.originalPrefs = prefs;
        this.prefs = {...prefs};
      }
    );
    subscribe(
      this,
      () => this.getUserModel().account$,
      acc => {
        this.account = acc;
      }
    );
    subscribe(
      this,
      () => this.getConfigModel().docsBaseUrl$,
      docsBaseUrl => (this.docsBaseUrl = docsBaseUrl)
    );
    subscribe(
      this,
      () => this.getPluginLoader().pluginsModel.suggestionsPlugins$,
      // We currently support results from only 1 provider.
      suggestionsPlugins =>
        (this.suggestionsProvider = suggestionsPlugins?.[0]?.provider)
    );
  }

  static override get styles() {
    return [
      sharedStyles,
      menuPageStyles,
      grFormStyles,
      css`
        :host {
          border: none;
          margin-bottom: var(--spacing-xxl);
        }
        h2 {
          font-family: var(--header-font-family);
          font-size: var(--font-size-h2);
          font-weight: var(--font-weight-h2);
          line-height: var(--line-height-h2);
        }
      `,
    ];
  }

  override render() {
    return html`
      <h2 id="Preferences" class=${this.hasUnsavedChanges() ? 'edited' : ''}>
        Preferences
      </h2>
      <fieldset id="preferences">
        <div id="preferences" class="gr-form-styles">
          <section>
            <label class="title" for="themeSelect">Theme</label>
            <span class="value">
              <gr-select
                .bindValue=${this.prefs?.theme ?? AppTheme.AUTO}
                @change=${() => {
                  this.prefs!.theme = this.themeSelect.value as AppTheme;
                  this.requestUpdate();
                }}
              >
                <select id="themeSelect">
                  <option value="AUTO">Auto (based on OS prefs)</option>
                  <option value="LIGHT">Light</option>
                  <option value="DARK">Dark</option>
                </select>
              </gr-select>
            </span>
          </section>
          <section>
            <label class="title" for="changesPerPageSelect"
              >Changes per page</label
            >
            <span class="value">
              <gr-select
                .bindValue=${convertToString(this.prefs?.changes_per_page)}
                @change=${() => {
                  this.prefs!.changes_per_page = Number(
                    this.changesPerPageSelect.value
                  ) as 10 | 25 | 50 | 100;
                  this.requestUpdate();
                }}
              >
                <select id="changesPerPageSelect">
                  <option value="10">10 rows per page</option>
                  <option value="25">25 rows per page</option>
                  <option value="50">50 rows per page</option>
                  <option value="100">100 rows per page</option>
                </select>
              </gr-select>
            </span>
          </section>
          <section>
            <label class="title" for="dateTimeFormatSelect"
              >Date/time format</label
            >
            <span class="value">
              <gr-select
                .bindValue=${convertToString(this.prefs?.date_format)}
                @change=${() => {
                  this.prefs!.date_format = this.dateTimeFormatSelect
                    .value as DateFormat;
                  this.requestUpdate();
                }}
              >
                <select id="dateTimeFormatSelect">
                  <option value="STD">Jun 3 ; Jun 3, 2016</option>
                  <option value="US">06/03 ; 06/03/16</option>
                  <option value="ISO">06-03 ; 2016-06-03</option>
                  <option value="EURO">3. Jun ; 03.06.2016</option>
                  <option value="UK">03/06 ; 03/06/2016</option>
                </select>
              </gr-select>
              <gr-select
                .bindValue=${convertToString(this.prefs?.time_format)}
                aria-label="Time Format"
                @change=${() => {
                  this.prefs!.time_format = this.timeFormatSelect
                    .value as TimeFormat;
                  this.requestUpdate();
                }}
              >
                <select id="timeFormatSelect">
                  <option value="HHMM_12">4:10 PM</option>
                  <option value="HHMM_24">16:10</option>
                </select>
              </gr-select>
            </span>
          </section>
          <section>
            <label class="title" for="emailNotificationsSelect"
              >Email notifications</label
            >
            <span class="value">
              <gr-select
                .bindValue=${convertToString(this.prefs?.email_strategy)}
                @change=${() => {
                  this.prefs!.email_strategy = this.emailNotificationsSelect
                    .value as EmailStrategy;
                  this.requestUpdate();
                }}
              >
                <select id="emailNotificationsSelect">
                  <option value="CC_ON_OWN_COMMENTS">Every comment</option>
                  <option value="ENABLED">Only comments left by others</option>
                  <option value="ATTENTION_SET_ONLY">
                    Only when I am in the attention set
                  </option>
                  <option value="DISABLED">None</option>
                </select>
              </gr-select>
            </span>
          </section>
          <section>
            <label class="title" for="emailFormatSelect">Email format</label>
            <span class="value">
              <gr-select
                .bindValue=${convertToString(this.prefs?.email_format)}
                @change=${() => {
                  this.prefs!.email_format = this.emailFormatSelect
                    .value as EmailFormat;
                  this.requestUpdate();
                }}
              >
                <select id="emailFormatSelect">
                  <option value="HTML_PLAINTEXT">HTML and plaintext</option>
                  <option value="PLAINTEXT">Plaintext only</option>
                </select>
              </gr-select>
            </span>
          </section>
          ${this.renderBrowserNotifications()}
          ${this.renderGenerateSuggestionWhenCommenting()}
          ${this.renderAiCommentAutocompletion()}
          ${this.renderDefaultBaseForMerges()}
          <section>
            <label class="title" for="relativeDateInChangeTable"
              >Show Relative Dates In Changes Table</label
            >
            <span class="value">
              <input
                id="relativeDateInChangeTable"
                type="checkbox"
                ?checked=${this.prefs?.relative_date_in_change_table}
                @change=${() => {
                  this.prefs!.relative_date_in_change_table =
                    this.relativeDateInChangeTable.checked;
                  this.requestUpdate();
                }}
              />
            </span>
          </section>
          <section>
            <span class="title">Diff view</span>
            <span class="value">
              <gr-select
                .bindValue=${convertToString(this.prefs?.diff_view)}
                @change=${() => {
                  this.prefs!.diff_view = this.diffViewSelect
                    .value as DiffViewMode;
                  this.requestUpdate();
                }}
              >
                <select id="diffViewSelect">
                  <option value="SIDE_BY_SIDE">Side by side</option>
                  <option value="UNIFIED_DIFF">Unified diff</option>
                </select>
              </gr-select>
            </span>
          </section>
          <section>
            <label for="showSizeBarsInFileList" class="title"
              >Show size bars in file list</label
            >
            <span class="value">
              <input
                id="showSizeBarsInFileList"
                type="checkbox"
                ?checked=${this.prefs?.size_bar_in_change_table}
                @change=${() => {
                  this.prefs!.size_bar_in_change_table =
                    this.showSizeBarsInFileList.checked;
                  this.requestUpdate();
                }}
              />
            </span>
          </section>
          <section>
            <label for="publishCommentsOnPush" class="title"
              >Publish comments on push</label
            >
            <span class="value">
              <input
                id="publishCommentsOnPush"
                type="checkbox"
                ?checked=${this.prefs?.publish_comments_on_push}
                @change=${() => {
                  this.prefs!.publish_comments_on_push =
                    this.publishCommentsOnPush.checked;
                  this.requestUpdate();
                }}
              />
            </span>
          </section>
          <section>
            <label for="workInProgressByDefault" class="title"
              >Set new changes to "work in progress" by default</label
            >
            <span class="value">
              <input
                id="workInProgressByDefault"
                type="checkbox"
                ?checked=${this.prefs?.work_in_progress_by_default}
                @change=${() => {
                  this.prefs!.work_in_progress_by_default =
                    this.workInProgressByDefault.checked;
                  this.requestUpdate();
                }}
              />
            </span>
          </section>
          <section>
            <label for="disableKeyboardShortcuts" class="title"
              >Disable all keyboard shortcuts</label
            >
            <span class="value">
              <input
                id="disableKeyboardShortcuts"
                type="checkbox"
                ?checked=${this.prefs?.disable_keyboard_shortcuts}
                @change=${() => {
                  this.prefs!.disable_keyboard_shortcuts =
                    this.disableKeyboardShortcuts.checked;
                  this.requestUpdate();
                }}
              />
            </span>
          </section>
          <section>
            <label for="disableTokenHighlighting" class="title"
              >Disable token highlighting on hover</label
            >
            <span class="value">
              <input
                id="disableTokenHighlighting"
                type="checkbox"
                ?checked=${this.prefs?.disable_token_highlighting}
                @change=${() => {
                  this.prefs!.disable_token_highlighting =
                    this.disableTokenHighlighting.checked;
                  this.requestUpdate();
                }}
              />
            </span>
          </section>
          <section>
            <label for="insertSignedOff" class="title">
              Insert Signed-off-by Footer For Inline Edit Changes
            </label>
            <span class="value">
              <input
                id="insertSignedOff"
                type="checkbox"
                ?checked=${this.prefs?.signed_off_by}
                @change=${() => {
                  this.prefs!.signed_off_by = this.insertSignedOff.checked;
                  this.requestUpdate();
                }}
              />
            </span>
          </section>
        </div>
        <gr-button
          id="savePrefs"
          @click=${async () => {
            await this.save();
          }}
          ?disabled=${!this.hasUnsavedChanges()}
          >Save changes</gr-button
        >
      </fieldset>
    `;
  }

  // When the experiment is over, move this back to render(),
  // removing this function.
  private renderBrowserNotifications() {
    if (!this.flagsService.isEnabled(KnownExperimentId.PUSH_NOTIFICATIONS))
      return nothing;
    if (
      !this.flagsService.isEnabled(
        KnownExperimentId.PUSH_NOTIFICATIONS_DEVELOPER
      ) &&
      !areNotificationsEnabled(this.account)
    )
      return nothing;
    return html` <section id="allowBrowserNotificationsSection">
      <div class="title">
        <label for="allowBrowserNotifications"
          >Allow browser notifications</label
        >
        <a
          href=${getDocUrl(
            this.docsBaseUrl,
            'user-attention-set.html#_browser_notifications'
          )}
          target="_blank"
          rel="noopener noreferrer"
        >
          <gr-icon icon="help" title="read documentation"></gr-icon>
        </a>
      </div>
      <span class="value">
        <input
          id="allowBrowserNotifications"
          type="checkbox"
          ?checked=${this.prefs?.allow_browser_notifications}
          @change=${() => {
            this.prefs!.allow_browser_notifications =
              this.allowBrowserNotifications!.checked;
            this.requestUpdate();
          }}
        />
      </span>
    </section>`;
  }

  // When the experiment is over, move this back to render(),
  // removing this function.
  private renderGenerateSuggestionWhenCommenting() {
    if (!this.suggestionsProvider) return nothing;
    return html`
      <section id="allowSuggestCodeWhileCommentingSection">
        <div class="title">
          <label for="allowSuggestCodeWhileCommenting"
            >AI suggested fixes while commenting</label
          >
          <a
            href=${this.suggestionsProvider.getDocumentationLink?.() ||
            getDocUrl(
              this.docsBaseUrl,
              'user-suggest-edits.html#_generate_suggestion'
            )}
            target="_blank"
            rel="noopener noreferrer"
          >
            <gr-icon icon="help" title="read documentation"></gr-icon>
          </a>
        </div>
        <span class="value">
          <input
            id="allowSuggestCodeWhileCommenting"
            type="checkbox"
            ?checked=${this.prefs?.allow_suggest_code_while_commenting}
            @change=${() => {
              this.prefs!.allow_suggest_code_while_commenting =
                this.allowSuggestCodeWhileCommenting!.checked;
              this.requestUpdate();
            }}
          />
        </span>
      </section>
    `;
  }

  // When the experiment is over, move this back to render(),
  // removing this function.
  private renderAiCommentAutocompletion() {
    if (
      !this.flagsService.isEnabled(KnownExperimentId.COMMENT_AUTOCOMPLETION) ||
      !this.suggestionsProvider
    )
      return nothing;
    return html`
      <section id="allowAiCommentAutocompletionSection">
        <div class="title">
          <label for="allowAiCommentAutocompletion"
            >AI suggested text completions while commenting</label
          >
        </div>
        <span class="value">
          <input
            id="allowAiCommentAutocompletion"
            type="checkbox"
            ?checked=${this.prefs?.allow_autocompleting_comments}
            @change=${() => {
              this.prefs!.allow_autocompleting_comments =
                this.allowAiCommentAutocompletion!.checked;
              this.requestUpdate();
            }}
          />
        </span>
      </section>
    `;
  }

  // When this is fixed and can be re-enabled, move this back to render()
  // and remove function.
  private renderDefaultBaseForMerges() {
    if (!this.prefs?.default_base_for_merges) return nothing;
    return nothing;
    // TODO: Re-enable respecting the default_base_for_merges preference.
    // See corresponding TODO in change-model.
    // return html`
    //   <section>
    //     <span class="title">Default Base For Merges</span>
    //     <span class="value">
    //       <gr-select
    //         .bindValue=${convertToString(
    //           this.prefs?.default_base_for_merges
    //         )}
    //         @change=${() => {
    //           this.prefs!.default_base_for_merges = this
    //             .defaultBaseForMergesSelect.value as DefaultBase;
    //           this.requestUpdate();
    //         }}
    //       >
    //         <select id="defaultBaseForMergesSelect">
    //           <option value="AUTO_MERGE">Auto Merge</option>
    //           <option value="FIRST_PARENT">First Parent</option>
    //         </select>
    //       </gr-select>
    //     </span>
    //   </section>
    // `;
  }

  // private but used in test
  hasUnsavedChanges() {
    // We have to wrap boolean values in Boolean() to ensure undefined values
    // use false rather than undefined.
    return (
      this.originalPrefs?.theme !== this.prefs?.theme ||
      this.originalPrefs?.changes_per_page !== this.prefs?.changes_per_page ||
      this.originalPrefs?.date_format !== this.prefs?.date_format ||
      this.originalPrefs?.time_format !== this.prefs?.time_format ||
      this.originalPrefs?.email_strategy !== this.prefs?.email_strategy ||
      this.originalPrefs?.email_format !== this.prefs?.email_format ||
      Boolean(this.originalPrefs?.allow_browser_notifications) !==
        Boolean(this.prefs?.allow_browser_notifications) ||
      Boolean(this.originalPrefs?.allow_suggest_code_while_commenting) !==
        Boolean(this.prefs?.allow_suggest_code_while_commenting) ||
      Boolean(this.originalPrefs?.allow_autocompleting_comments) !==
        Boolean(this.prefs?.allow_autocompleting_comments) ||
      this.originalPrefs?.default_base_for_merges !==
        this.prefs?.default_base_for_merges ||
      Boolean(this.originalPrefs?.relative_date_in_change_table) !==
        Boolean(this.prefs?.relative_date_in_change_table) ||
      this.originalPrefs?.diff_view !== this.prefs?.diff_view ||
      Boolean(this.originalPrefs?.size_bar_in_change_table) !==
        Boolean(this.prefs?.size_bar_in_change_table) ||
      Boolean(this.originalPrefs?.publish_comments_on_push) !==
        Boolean(this.prefs?.publish_comments_on_push) ||
      Boolean(this.originalPrefs?.work_in_progress_by_default) !==
        Boolean(this.prefs?.work_in_progress_by_default) ||
      Boolean(this.originalPrefs?.disable_keyboard_shortcuts) !==
        Boolean(this.prefs?.disable_keyboard_shortcuts) ||
      Boolean(this.originalPrefs?.disable_token_highlighting) !==
        Boolean(this.prefs?.disable_token_highlighting) ||
      Boolean(this.originalPrefs?.signed_off_by) !==
        Boolean(this.prefs?.signed_off_by)
    );
  }

  async save() {
    if (!this.prefs) return;
    await this.getUserModel().updatePreferences(this.prefs);
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-preferences': GrPreferences;
  }
}
