/**
 * @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-medium);
        }
        .contributorAgreementButton {
          font-weight: var(--font-weight-medium);
        }
        .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;
  };
}
