/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/iron-input/iron-input';
import '../../shared/gr-autocomplete/gr-autocomplete';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-select/gr-select';
import {
  BranchName,
  GroupId,
  ProjectInput,
  RepoName,
} from '../../../types/common';
import {AutocompleteQuery} from '../../shared/gr-autocomplete/gr-autocomplete';
import {getAppContext} from '../../../services/app-context';
import {convertToString} from '../../../utils/string-util';
import {grFormStyles} from '../../../styles/gr-form-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, css, html} from 'lit';
import {customElement, query, property, state} from 'lit/decorators.js';
import {fire} from '../../../utils/event-util';
import {throwingErrorCallback} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
import {createRepoUrl} from '../../../models/views/repo';
import {resolve} from '../../../models/dependency';
import {navigationToken} from '../../core/gr-navigation/gr-navigation';
import {ValueChangedEvent} from '../../../types/events';
import {subscribe} from '../../lit/subscription-controller';
import {configModelToken} from '../../../models/config/config-model';
import {branchName} from '../../../utils/patch-set-util';

declare global {
  interface HTMLElementTagNameMap {
    'gr-create-repo-dialog': GrCreateRepoDialog;
  }
  interface HTMLElementEventMap {
    /** Fired when repostiory name is entered. */
    'new-repo-name': CustomEvent<{}>;
  }
}

@customElement('gr-create-repo-dialog')
export class GrCreateRepoDialog extends LitElement {
  @query('input')
  input?: HTMLInputElement;

  @property({type: Boolean})
  nameChanged = false;

  /* private but used in test */
  @state() repoConfig: ProjectInput & {name: RepoName} = {
    create_empty_commit: true,
    permissions_only: false,
    name: '' as RepoName,
    branches: [],
  };

  /* private but used in test */
  @state() selectedDefaultBranch?: BranchName;

  /* private but used in test */
  @state() repoCreated = false;

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

  /* private but used in test */
  @state() repoOwnerId?: GroupId;

  @state() private defaultBranch = 'master';

  private readonly query: AutocompleteQuery;

  private readonly queryGroups: AutocompleteQuery;

  private readonly restApiService = getAppContext().restApiService;

  private readonly getNavigation = resolve(this, navigationToken);

  private readonly configModel = resolve(this, configModelToken);

  constructor() {
    super();
    this.query = (input: string) => this.getRepoSuggestions(input);
    this.queryGroups = (input: string) => this.getGroupSuggestions(input);
    subscribe(
      this,
      () => this.configModel().serverConfig$,
      config => {
        this.defaultBranch = branchName(
          config?.gerrit?.default_branch ?? 'master'
        );
      }
    );
  }

  static override get styles() {
    return [
      grFormStyles,
      sharedStyles,
      css`
        :host {
          display: inline-block;
        }
        div.title-flex,
        div.value-flex {
          display: flex;
          flex-direction: column;
          justify-content: center;
        }
        input {
          width: 20em;
          box-sizing: border-box;
        }
        div.gr-form-styles section {
          margin: var(--spacing-m) 0;
        }
        div.gr-form-styles span.title {
          width: 13em;
        }
        section .title gr-icon {
          vertical-align: top;
        }
        section .value gr-autocomplete {
          display: block;
          width: 20em;
        }
      `,
    ];
  }

  override render() {
    return html`
      <div class="gr-form-styles">
        <div id="form">
          <section>
            <div class="title-flex">
              <span class="title">Repository Name</span>
            </div>
            <iron-input
              .bindValue=${convertToString(this.repoConfig.name)}
              @bind-value-changed=${this.handleNameBindValueChanged}
            >
              <input id="repoNameInput" autocomplete="on" />
            </iron-input>
          </section>
          <section ?hidden=${!!this.repoConfig.permissions_only}>
            <div class="title-flex">
              <span class="title">Default Branch</span>
            </div>
            <span class="value">
              <gr-autocomplete
                id="defaultBranchNameInput"
                .text=${convertToString(this.selectedDefaultBranch)}
                .placeholder=${`Optional, defaults to '${this.defaultBranch}'`}
                @text-changed=${this.handleBranchNameBindValueChanged}
              >
              </gr-autocomplete>
            </span>
          </section>
          <section>
            <div class="title-flex">
              <span class="title">
                <gr-tooltip-content
                  has-tooltip
                  title="For inheriting access rights and repository configuration"
                >
                  Parent Repository <gr-icon icon="info"></gr-icon>
                </gr-tooltip-content>
              </span>
            </div>
            <span class="value">
              <gr-autocomplete
                id="rightsInheritFromInput"
                .text=${convertToString(this.repoConfig.parent)}
                .query=${this.query}
                .placeholder=${"Optional, defaults to 'All-Projects'"}
                @text-changed=${this.handleRightsTextChanged}
              >
              </gr-autocomplete>
            </span>
          </section>
          <section>
            <div class="title-flex">
              <span class="title">
                <gr-tooltip-content
                  has-tooltip
                  title="When the project is created, the 'Owner' access right is automatically assigned to this group."
                >
                  Owner Group <gr-icon icon="info"></gr-icon>
                </gr-tooltip-content>
              </span>
            </div>
            <span class="value">
              <gr-autocomplete
                id="ownerInput"
                .text=${convertToString(this.repoOwner)}
                .value=${convertToString(this.repoOwnerId)}
                .query=${this.queryGroups}
                .placeholder=${'Optional'}
                @text-changed=${this.handleOwnerTextChanged}
                @value-changed=${this.handleOwnerValueChanged}
              >
              </gr-autocomplete>
            </span>
          </section>
          <section>
            <div class="title-flex">
              <span class="title">
                <gr-tooltip-content
                  has-tooltip
                  title="Choose 'false', if you want to import an existing repo, 'true' otherwise."
                >
                  Create Empty Commit <gr-icon icon="info"></gr-icon>
                </gr-tooltip-content>
              </span>
            </div>
            <div class="value-flex">
              <span class="value">
                <gr-select
                  id="initialCommit"
                  .bindValue=${this.repoConfig.create_empty_commit}
                  @bind-value-changed=${this
                    .handleCreateEmptyCommitBindValueChanged}
                >
                  <select>
                    <option value="false">False</option>
                    <option value="true">True</option>
                  </select>
                </gr-select>
              </span>
            </div>
          </section>
          <section>
            <div class="title-flex">
              <span class="title">
                <gr-tooltip-content
                  has-tooltip
                  title="Only serve as a parent repository for other repositories
to inheright access rights and configs.
If 'true', then you cannot push code to this repo.
It will only have a 'refs/meta/config' branch."
                >
                  Parent Repo Only <gr-icon icon="info"></gr-icon>
                </gr-tooltip-content>
              </span>
            </div>
            <div class="value-flex">
              <span class="value">
                <gr-select
                  id="parentRepo"
                  .bindValue=${this.repoConfig.permissions_only}
                  @bind-value-changed=${this
                    .handlePermissionsOnlyBindValueChanged}
                >
                  <select>
                    <option value="false">False</option>
                    <option value="true">True</option>
                  </select>
                </gr-select>
              </span>
            </div>
          </section>
        </div>
      </div>
    `;
  }

  override focus() {
    this.input?.focus();
  }

  async handleCreateRepo() {
    if (this.selectedDefaultBranch)
      this.repoConfig.branches = [this.selectedDefaultBranch];
    if (this.repoOwnerId) this.repoConfig.owners = [this.repoOwnerId];
    const repoRegistered = await this.restApiService.createRepo(
      this.repoConfig
    );
    if (repoRegistered.status === 201) {
      this.repoCreated = true;
      this.getNavigation().setUrl(createRepoUrl({repo: this.repoConfig.name}));
    }
    return repoRegistered;
  }

  private async getRepoSuggestions(input: string) {
    const response = await this.restApiService.getSuggestedRepos(
      input,
      /* n=*/ undefined,
      throwingErrorCallback
    );

    const repos = [];
    for (const [name, repo] of Object.entries(response ?? {})) {
      repos.push({name, value: repo.id});
    }
    return repos;
  }

  private async getGroupSuggestions(input: string) {
    const response = await this.restApiService.getSuggestedGroups(
      input,
      /* project=*/ undefined,
      /* n=*/ undefined,
      throwingErrorCallback
    );

    const groups = [];
    for (const [name, group] of Object.entries(response ?? {})) {
      groups.push({name, value: decodeURIComponent(group.id)});
    }
    return groups;
  }

  private handleRightsTextChanged(e: ValueChangedEvent) {
    this.repoConfig = {
      ...this.repoConfig,
      parent: e.detail.value as RepoName,
    };
  }

  private handleOwnerTextChanged(e: ValueChangedEvent) {
    this.repoOwner = e.detail.value;
  }

  private handleOwnerValueChanged(e: ValueChangedEvent) {
    this.repoOwnerId = e.detail.value as GroupId;
  }

  private handleNameBindValueChanged(e: ValueChangedEvent) {
    this.repoConfig.name = e.detail.value as RepoName;
    // nameChanged needs to be set before the event is fired,
    // because when the event is fired, gr-repo-list gets
    // the nameChanged value.
    this.nameChanged = !!e.detail.value;
    fire(this, 'new-repo-name', {});
    this.requestUpdate();
  }

  private handleBranchNameBindValueChanged(e: ValueChangedEvent) {
    this.selectedDefaultBranch = e.detail.value as BranchName;
  }

  private handleCreateEmptyCommitBindValueChanged(
    e: ValueChangedEvent<string>
  ) {
    this.repoConfig = {
      ...this.repoConfig,
      create_empty_commit: e.detail.value === 'true',
    };
  }

  private handlePermissionsOnlyBindValueChanged(e: ValueChangedEvent<string>) {
    this.repoConfig = {
      ...this.repoConfig,
      permissions_only: e.detail.value === 'true',
    };
  }
}
