/**
 * @license
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {RepoName, DashboardId, DashboardInfo} from '../../../types/common';
import {firePageError} from '../../../utils/event-util';
import {getAppContext} from '../../../services/app-context';
import {ErrorCallback} from '../../../api/rest';
import {sharedStyles} from '../../../styles/shared-styles';
import {tableStyles} from '../../../styles/gr-table-styles';
import {LitElement, css, html, PropertyValues} from 'lit';
import {customElement, property} from 'lit/decorators';

interface DashboardRef {
  section: string;
  dashboards: DashboardInfo[];
}

@customElement('gr-repo-dashboards')
export class GrRepoDashboards extends LitElement {
  @property({type: String})
  repo?: RepoName;

  @property({type: Boolean})
  _loading = true;

  @property({type: Array})
  _dashboards?: DashboardRef[];

  private readonly restApiService = getAppContext().restApiService;

  static override get styles() {
    return [
      sharedStyles,
      tableStyles,
      css`
        :host {
          display: block;
          margin-bottom: var(--spacing-xxl);
        }
        .loading #dashboards,
        #loadingContainer {
          display: none;
        }
        .loading #loadingContainer {
          display: block;
        }
      `,
    ];
  }

  override render() {
    return html` <table
      id="list"
      class="genericList ${this._computeLoadingClass(this._loading)}"
    >
      <tbody>
        <tr class="headerRow">
          <th class="topHeader">Dashboard name</th>
          <th class="topHeader">Dashboard title</th>
          <th class="topHeader">Dashboard description</th>
          <th class="topHeader">Inherited from</th>
          <th class="topHeader">Default</th>
        </tr>
        <tr id="loadingContainer">
          <td>Loading...</td>
        </tr>
      </tbody>
      <tbody id="dashboards">
        ${(this._dashboards ?? []).map(
          item => html`
            <tr class="groupHeader">
              <td colspan="5">${item.section}</td>
            </tr>
            ${(item.dashboards ?? []).map(
              info => html`
                <tr class="table">
                  <td class="name">
                    <a href="${this._getUrl(info.project, info.id)}"
                      >${info.path}</a
                    >
                  </td>
                  <td class="title">${info.title}</td>
                  <td class="desc">${info.description}</td>
                  <td class="inherited">
                    ${this._computeInheritedFrom(
                      info.project,
                      info.defining_project
                    )}
                  </td>
                  <td class="default">
                    ${this._computeIsDefault(info.is_default)}
                  </td>
                </tr>
              `
            )}
          `
        )}
      </tbody>
    </table>`;
  }

  override updated(changedProperties: PropertyValues) {
    if (changedProperties.has('repo')) {
      this.repoChanged();
    }
  }

  private repoChanged() {
    const repo = this.repo;
    this._loading = true;
    if (!repo) {
      return Promise.resolve();
    }

    const errFn: ErrorCallback = response => {
      firePageError(response);
    };

    return this.restApiService
      .getRepoDashboards(repo, errFn)
      .then((res?: DashboardInfo[]) => {
        if (!res) {
          return;
        }

        // Group by ref and sort by id.
        const dashboards = res.concat
          .apply([], res)
          .sort((a, b) => (a.id < b.id ? -1 : 1));
        const dashboardsByRef: Record<string, DashboardInfo[]> = {};
        dashboards.forEach(d => {
          if (!dashboardsByRef[d.ref]) {
            dashboardsByRef[d.ref] = [];
          }
          dashboardsByRef[d.ref].push(d);
        });

        const dashboardBuilder: DashboardRef[] = [];
        Object.keys(dashboardsByRef)
          .sort()
          .forEach(ref => {
            dashboardBuilder.push({
              section: ref,
              dashboards: dashboardsByRef[ref],
            });
          });

        this._dashboards = dashboardBuilder;
        this._loading = false;
      });
  }

  _getUrl(project?: RepoName, id?: DashboardId) {
    if (!project || !id) {
      return '';
    }

    return GerritNav.getUrlForRepoDashboard(project, id);
  }

  _computeLoadingClass(loading: boolean) {
    return loading ? 'loading' : '';
  }

  _computeInheritedFrom(project: RepoName, definingProject: RepoName) {
    return project === definingProject ? '' : definingProject;
  }

  _computeIsDefault(isDefault?: boolean) {
    return isDefault ? '✓' : '';
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-repo-dashboards': GrRepoDashboards;
  }
}
