/**
 * @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, query, state} 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 {grFormStyles} 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';
import {notDeepEqual} from '../../../utils/deep-util';

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;

  @state()
  originalProjects?: ProjectWatchInfo[];

  @state()
  projects?: ProjectWatchInfo[];

  @state()
  projectsToRemove: ProjectWatchInfo[] = [];

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

  private readonly restApiService = getAppContext().restApiService;

  static override get styles() {
    return [
      sharedStyles,
      grFormStyles,
      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.originalProjects = projs;
      this.projects = projs ? [...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.originalProjects = projects;
        this.projects = projects ? [...projects] : [];
        this.projectsToRemove = [];
        this.setHasUnsavedChanges();
      });
  }

  // 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 || !this.originalProjects) return;
    const index = this.projects.indexOf(project);
    if (index < 0) return;
    this.projects.splice(index, 1);
    // Don't add project to projectsToRemove if it wasn't in
    // originalProjects.
    if (this.originalProjects.includes(project))
      this.projectsToRemove.push(project);
    this.requestUpdate();
    this.setHasUnsavedChanges();
  }

  // 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();
  }

  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();
  }

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

  private setHasUnsavedChanges() {
    const hasUnsavedChanges =
      notDeepEqual(this.originalProjects, this.projects) ||
      this.projectsToRemove.length > 0;
    fire(this, 'has-unsaved-changes-changed', {value: hasUnsavedChanges});
  }

  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;
  }
}
