/**
 * @license
 * Copyright 2016 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 {customElement, property, query} from 'lit/decorators.js';
import {
  AutocompleteQuery,
  GrAutocomplete,
  AutocompleteSuggestion,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {assertIsDefined} from '../../../utils/common-util';
import {ProjectWatchInfo, RepoName} from '../../../types/common';
import {getAppContext} from '../../../services/app-context';
import {css, html, LitElement} from 'lit';
import {sharedStyles} from '../../../styles/shared-styles';
import {formStyles} from '../../../styles/gr-form-styles';
import {when} from 'lit/directives/when.js';
import {fire} from '../../../utils/event-util';
import {PropertiesOfType} from '../../../utils/type-util';
import {throwingErrorCallback} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';

type NotificationKey = PropertiesOfType<Required<ProjectWatchInfo>, boolean>;

const NOTIFICATION_TYPES: Array<{name: string; key: NotificationKey}> = [
  {name: 'Changes', key: 'notify_new_changes'},
  {name: 'Patches', key: 'notify_new_patch_sets'},
  {name: 'Comments', key: 'notify_all_comments'},
  {name: 'Submits', key: 'notify_submitted_changes'},
  {name: 'Abandons', key: 'notify_abandoned_changes'},
];

@customElement('gr-watched-projects-editor')
export class GrWatchedProjectsEditor extends LitElement {
  // Private but used in tests.
  @query('#newFilter')
  newFilter?: HTMLInputElement;

  // Private but used in tests.
  @query('#newProject')
  newProject?: GrAutocomplete;

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

  @property({type: Array})
  projects?: ProjectWatchInfo[];

  @property({type: Array})
  projectsToRemove: ProjectWatchInfo[] = [];

  private readonly query: AutocompleteQuery = input =>
    this.getProjectSuggestions(input);

  private readonly restApiService = getAppContext().restApiService;

  static override get styles() {
    return [
      sharedStyles,
      formStyles,
      css`
        #watchedProjects .notifType {
          text-align: center;
          padding: 0 var(--spacing-s);
        }
        .notifControl {
          cursor: pointer;
          text-align: center;
        }
        .notifControl:hover {
          outline: 1px solid var(--border-color);
        }
        .projectFilter {
          color: var(--deemphasized-text-color);
          font-style: italic;
          margin-left: var(--spacing-l);
        }
        .newFilterInput {
          width: 100%;
        }
      `,
    ];
  }

  override render() {
    const types = NOTIFICATION_TYPES;
    return html` <div class="gr-form-styles">
      <table id="watchedProjects">
        <thead>
          <tr>
            <th>Repo</th>
            ${types.map(type => html`<th class="notifType">${type.name}</th>`)}
            <th></th>
          </tr>
        </thead>
        <tbody>
          ${(this.projects ?? []).map(project => this.renderProject(project))}
        </tbody>
        <tfoot>
          <tr>
            <th>
              <gr-autocomplete
                id="newProject"
                .query=${this.query}
                threshold="1"
                allow-non-suggested-values
                tab-complete
                placeholder="Repo"
              ></gr-autocomplete>
            </th>
            <th colspan=${types.length}>
              <iron-input id="newFilterInput" class="newFilterInput">
                <input
                  id="newFilter"
                  class="newFilterInput"
                  placeholder="branch:name, or other search expression"
                />
              </iron-input>
            </th>
            <th>
              <gr-button link="" @click=${this.handleAddProject}>Add</gr-button>
            </th>
          </tr>
        </tfoot>
      </table>
    </div>`;
  }

  private renderProject(project: ProjectWatchInfo) {
    const types = NOTIFICATION_TYPES;
    return html` <tr>
      <td>
        ${project.project}
        ${when(
          project.filter,
          () => html`<div class="projectFilter">${project.filter}</div>`
        )}
      </td>
      ${types.map(type => this.renderNotifyControl(project, type.key))}
      <td>
        <gr-button
          link=""
          @click=${(_e: Event) => this.handleRemoveProject(project)}
          >Delete</gr-button
        >
      </td>
    </tr>`;
  }

  private renderNotifyControl(project: ProjectWatchInfo, key: NotificationKey) {
    return html` <td class="notifControl" @click=${this.handleNotifCellClick}>
      <input
        type="checkbox"
        data-key=${key}
        @change=${(e: Event) => this.handleCheckboxChange(project, key, e)}
        ?checked=${!!project[key]}
      />
    </td>`;
  }

  loadData() {
    return this.restApiService.getWatchedProjects().then(projs => {
      this.projects = projs;
    });
  }

  save() {
    let deletePromise: Promise<Response | undefined>;
    if (this.projectsToRemove.length) {
      deletePromise = this.restApiService.deleteWatchedProjects(
        this.projectsToRemove
      );
    } else {
      deletePromise = Promise.resolve(undefined);
    }

    return deletePromise
      .then(() => {
        if (this.projects) {
          return this.restApiService.saveWatchedProjects(this.projects);
        } else {
          return Promise.resolve(undefined);
        }
      })
      .then(projects => {
        this.projects = projects;
        this.projectsToRemove = [];
        this.setHasUnsavedChanges(false);
      });
  }

  // private but used in tests.
  getProjectSuggestions(input: string) {
    return this.restApiService
      .getSuggestedRepos(input, /* n=*/ undefined, throwingErrorCallback)
      .then(response => {
        const repos: AutocompleteSuggestion[] = [];
        for (const [name, repo] of Object.entries(response ?? {})) {
          repos.push({name, value: repo.id});
        }
        return repos;
      });
  }

  private handleRemoveProject(project: ProjectWatchInfo) {
    if (!this.projects) return;
    const index = this.projects.indexOf(project);
    if (index < 0) return;
    this.projects.splice(index, 1);
    this.projectsToRemove.push(project);
    this.requestUpdate();
    this.setHasUnsavedChanges(true);
  }

  // private but used in tests.
  canAddProject(
    project: string | null,
    text: string | null,
    filter: string | null
  ) {
    if (project === null && text === null) {
      return false;
    }

    // This will only be used if not using the auto complete
    if (!project && text) {
      return true;
    }

    if (!this.projects) return true;
    // Check if the project with filter is already in the list.
    for (let i = 0; i < this.projects.length; i++) {
      if (
        this.projects[i].project === project &&
        this.areFiltersEqual(this.projects[i].filter, filter)
      ) {
        return false;
      }
    }

    return true;
  }

  // private but used in tests.
  getNewProjectIndex(name: string, filter: string | null) {
    if (!this.projects) return;
    let i;
    for (i = 0; i < this.projects.length; i++) {
      const projectFilter = this.projects[i].filter;
      if (
        this.projects[i].project > name ||
        (this.projects[i].project === name &&
          this.isFilterDefined(projectFilter) &&
          this.isFilterDefined(filter) &&
          projectFilter! > filter!)
      ) {
        break;
      }
    }
    return i;
  }

  // Private but used in tests.
  handleAddProject() {
    assertIsDefined(this.newProject, 'newProject');
    assertIsDefined(this.newFilter, 'newFilter');
    const newProject = this.newProject.value;
    const newProjectName = this.newProject.text as RepoName;
    const filter = this.newFilter.value;

    if (!this.canAddProject(newProject, newProjectName, filter)) {
      return;
    }

    const insertIndex = this.getNewProjectIndex(newProjectName, filter);

    if (insertIndex !== undefined) {
      this.projects?.splice(insertIndex, 0, {
        project: newProjectName,
        filter,
        _is_local: true,
      });
      this.requestUpdate();
    }

    this.newProject.clear();
    this.newFilter.value = '';
    this.setHasUnsavedChanges(true);
  }

  private handleCheckboxChange(
    project: ProjectWatchInfo,
    key: NotificationKey,
    e: Event
  ) {
    const el = e.target as HTMLInputElement;
    const checked = el.checked;
    project[key] = !!checked;
    this.requestUpdate();
    this.setHasUnsavedChanges(true);
  }

  private handleNotifCellClick(e: Event) {
    if (e.target === null) return;
    const checkbox = (e.target as HTMLElement).querySelector('input');
    if (checkbox) {
      checkbox.click();
    }
  }

  private setHasUnsavedChanges(value: boolean) {
    this.hasUnsavedChanges = value;
    fire(this, 'has-unsaved-changes-changed', {value});
  }

  isFilterDefined(filter: string | null | undefined) {
    return filter !== null && filter !== undefined;
  }

  areFiltersEqual(
    filter1: string | null | undefined,
    filter2: string | null | undefined
  ) {
    // null and undefined are equal
    if (!this.isFilterDefined(filter1) && !this.isFilterDefined(filter2)) {
      return true;
    }
    return filter1 === filter2;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-watched-projects-editor': GrWatchedProjectsEditor;
  }
}
