/**
 * @license
 * Copyright 2018 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/iron-input/iron-input';
import '../../shared/gr-button/gr-button';
import {getBaseUrl} from '../../../utils/url-util';
import {
  ServerInfo,
  GroupInfo,
  ContributorAgreementInfo,
} from '../../../types/common';
import {fireAlert, fireTitleChange} from '../../../utils/event-util';
import {getAppContext} from '../../../services/app-context';
import {fontStyles} from '../../../styles/gr-font-styles';
import {grFormStyles} from '../../../styles/gr-form-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, html, css} from 'lit';
import {customElement, state} from 'lit/decorators.js';
import {BindValueChangeEvent} from '../../../types/events';
import {ifDefined} from 'lit/directives/if-defined.js';

declare global {
  interface HTMLElementTagNameMap {
    'gr-cla-view': GrClaView;
  }
}

@customElement('gr-cla-view')
export class GrClaView extends LitElement {
  // private but used in test
  @state() groups?: GroupInfo[];

  // private but used in test
  @state() serverConfig?: ServerInfo;

  @state() private agreementsText?: string;

  // private but used in test
  @state() agreementName?: string;

  // private but used in test
  @state() signedAgreements?: ContributorAgreementInfo[];

  @state() private showAgreements = false;

  @state() private agreementsUrl?: string;

  private readonly restApiService = getAppContext().restApiService;

  override connectedCallback() {
    super.connectedCallback();
    this.loadData();

    fireTitleChange('New Contributor Agreement');
  }

  static override get styles() {
    return [
      fontStyles,
      grFormStyles,
      sharedStyles,
      css`
        h1 {
          margin-bottom: var(--spacing-m);
        }
        h3 {
          margin-bottom: var(--spacing-m);
        }
        .agreementsUrl {
          border: 1px solid var(--border-color);
          margin-bottom: var(--spacing-xl);
          margin-left: var(--spacing-xl);
          margin-right: var(--spacing-xl);
          padding: var(--spacing-s);
        }
        #claNewAgreementsLabel {
          font-weight: var(--font-weight-bold);
        }
        .contributorAgreementButton {
          font-weight: var(--font-weight-bold);
        }
        .alreadySubmittedText {
          color: var(--error-text-color);
          margin: 0 var(--spacing-xxl);
          padding: var(--spacing-m);
        }
        main {
          margin: var(--spacing-xxl) auto;
          max-width: 50em;
        }
      `,
    ];
  }

  override render() {
    return html`
      <main>
        <h1 class="heading-1">New Contributor Agreement</h1>
        <h3 class="heading-3">Select an agreement type:</h3>
        ${(this.serverConfig?.auth.contributor_agreements ?? [])
          .filter(agreement => agreement.url)
          .map(item => this.renderAgreementsButton(item))}
        ${this.renderNewAgreement()}
      </main>
    `;
  }

  private renderAgreementsButton(item: ContributorAgreementInfo) {
    return html`
      <span class="contributorAgreementButton">
        <input
          id="claNewAgreementsInput${item.name}"
          name="claNewAgreementsRadio"
          type="radio"
          data-name=${ifDefined(item.name)}
          data-url=${ifDefined(item.url)}
          @click=${this.handleShowAgreement}
          ?disabled=${this.disableAgreements(item)}
        />
        <label id="claNewAgreementsLabel">${item.name}</label>
      </span>
      ${this.renderAlreadySubmittedText(item)}
      <div class="agreementsUrl">${item.description}</div>
    `;
  }

  private renderAlreadySubmittedText(item: ContributorAgreementInfo) {
    if (!this.disableAgreements(item)) return;

    return html`
      <div class="alreadySubmittedText">Agreement already submitted.</div>
    `;
  }

  private renderNewAgreement() {
    if (!this.showAgreements) return;
    return html`
      <div id="claNewAgreement">
        <h3 class="heading-3">Review the agreement:</h3>
        <div id="agreementsUrl" class="agreementsUrl">
          <a
            href=${ifDefined(this.agreementsUrl)}
            target="blank"
            rel="noopener"
          >
            Please review the agreement.</a
          >
        </div>
        ${this.renderAgreementsTextBox()}
      </div>
    `;
  }

  private renderAgreementsTextBox() {
    if (this.computeHideAgreementTextbox()) return;
    return html`
      <div class="agreementsTextBox">
        <h3 class="heading-3">Complete the agreement:</h3>
        <iron-input
          .bindValue=${this.agreementsText}
          @bind-value-changed=${this.handleBindValueChanged}
        >
          <input id="input-agreements" placeholder="Enter 'I agree' here" />
        </iron-input>
        <gr-button
          @click=${this.handleSaveAgreements}
          ?disabled=${this.agreementsText?.toLowerCase() !== 'i agree'}
        >
          Submit
        </gr-button>
      </div>
    `;
  }

  loadData() {
    const promises = [];
    promises.push(
      this.restApiService.getConfig(true).then(config => {
        this.serverConfig = config;
      })
    );

    promises.push(
      this.restApiService.getAccountGroups().then(groups => {
        if (!groups) return;
        this.groups = groups.sort((a, b) =>
          (a.name || '').localeCompare(b.name || '')
        );
      })
    );

    promises.push(
      this.restApiService
        .getAccountAgreements()
        .then((agreements: ContributorAgreementInfo[] | undefined) => {
          this.signedAgreements = agreements || [];
        })
    );

    return Promise.all(promises);
  }

  // private but used in test
  getAgreementsUrl(configUrl: string) {
    if (!configUrl) return '';

    if (configUrl.startsWith('http:') || configUrl.startsWith('https:')) {
      return configUrl;
    }

    return `${getBaseUrl()}/${configUrl}`;
  }

  private readonly handleShowAgreement = (e: Event) => {
    this.agreementName = (e.target as HTMLInputElement).getAttribute(
      'data-name'
    )!;
    const url = (e.target as HTMLInputElement).getAttribute('data-url')!;
    this.agreementsUrl = this.getAgreementsUrl(url);
    this.showAgreements = true;
  };

  private readonly handleSaveAgreements = () => {
    this.createToast('Agreement saving...');

    const name = this.agreementName;
    return this.restApiService.saveAccountAgreement({name}).then(res => {
      let message = 'Agreement failed to be submitted, please try again';
      if (res.status === 200) {
        message = 'Agreement has been successfully submitted.';
      }
      this.createToast(message);
      this.loadData();
      this.agreementsText = '';
      this.showAgreements = false;
    });
  };

  private createToast(message: string) {
    fireAlert(this, message);
  }

  // private but used in test
  disableAgreements(item: ContributorAgreementInfo) {
    for (const group of this.groups ?? []) {
      if (
        item?.auto_verify_group?.id === group.id ||
        this.signedAgreements?.find(i => i.name === item.name)
      ) {
        return true;
      }
    }
    return false;
  }

  // This checks for auto_verify_group,
  // if specified it returns 'true' which
  // then hides the text box and submit button.
  // private but used in test
  computeHideAgreementTextbox() {
    const contributorAgreements =
      this.serverConfig?.auth.contributor_agreements;
    if (!this.agreementName || !contributorAgreements) return false;
    return contributorAgreements.some(
      (contributorAgreement: ContributorAgreementInfo) =>
        this.agreementName === contributorAgreement.name &&
        !contributorAgreement.auto_verify_group
    );
  }

  private readonly handleBindValueChanged = (e: BindValueChangeEvent) => {
    this.agreementsText = e.detail.value;
  };
}
