/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import './gr-avatar';
import '../gr-hovercard-account/gr-hovercard-account';
import {AccountInfo, ServerInfo} from '../../../types/common';
import {LitElement, PropertyValues, css, html} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {
  isDetailedAccount,
  uniqueAccountId,
  uniqueDefinedAvatar,
} from '../../../utils/account-util';
import {resolve} from '../../../models/dependency';
import {configModelToken} from '../../../models/config/config-model';
import {subscribe} from '../../lit/subscription-controller';
import {getDisplayName} from '../../../utils/display-name-util';
import {accountsModelToken} from '../../../models/accounts-model/accounts-model';
import {isDefined} from '../../../types/types';
import {when} from 'lit/directives/when.js';

/**
 * This elements draws stack of avatars overlapped with each other.
 *
 * If accounts is empty or contains accounts with more than MAX_STACK unique
 * avatars the fallback slot is rendered instead.
 *
 * Style parameters:
 *   --avatar-size: size of the individual avatars. (Default: 16px)
 *   --stack-border-color: border of individual avatars in stack.
 *       (Default: #ffffff)
 */
@customElement('gr-avatar-stack')
export class GrAvatarStack extends LitElement {
  static readonly MAX_STACK = 4;

  @property({type: Array})
  accounts: AccountInfo[] = [];

  @state()
  detailedAccounts: AccountInfo[] = [];

  /**
   * The size of requested image in px.
   *
   * By default this also controls avatarSize.
   */
  @property({type: Number})
  imageSize = 16;

  /**
   * Whether a hover-card should be shown for each avatar when hovered
   */
  @property({type: Boolean})
  enableHover = false;

  /**
   * In gr-app, gr-account-chip is in charge of loading a full account, so
   * avatars will be set. However, code-owners will create gr-avatars with a
   * bare account-id. To enable fetching of those avatars, a flag is added to
   * gr-avatar-stack that will fetch the accounts on demand
   */
  @property({type: Boolean})
  forceFetch = false;

  private readonly getAccountsModel = resolve(this, accountsModelToken);

  @state() config?: ServerInfo;

  static override get styles() {
    return [
      css`
        gr-avatar {
          box-sizing: border-box;
          vertical-align: top;
          height: var(--avatar-size, 16px);
          width: var(--avatar-size, 16px);
          border: solid 1px var(--stack-border-color, transparent);
        }
        gr-avatar:not(:first-child) {
          margin-left: calc((var(--avatar-size, 16px) / -2));
        }
      `,
    ];
  }

  private readonly getConfigModel = resolve(this, configModelToken);

  constructor() {
    super();
    subscribe(
      this,
      () => this.getConfigModel().serverConfig$,
      config => (this.config = config)
    );
  }

  override updated(changedProperties: PropertyValues) {
    if (changedProperties.has('accounts')) {
      if (
        this.forceFetch &&
        this.accounts.length > 0 &&
        this.accounts.some(a => !isDetailedAccount(a))
      ) {
        Promise.all(
          this.accounts.map(account =>
            this.getAccountsModel().fillDetails(account)
          )
        ).then(accounts => {
          // Only keep the detailed accounts as only those will be shown.
          // It is possible for the server to return an empty account with just an account-id.
          // This could be due to the fact that the user does not have permission to see this account.
          this.detailedAccounts = accounts.filter(
            a => isDefined(a) && isDetailedAccount(a)
          );
        });
      } else {
        this.detailedAccounts = this.accounts;
      }
    }
  }

  override render() {
    const uniqueAvatarAccounts = this.forceFetch
      ? this.detailedAccounts.filter(uniqueAccountId)
      : this.detailedAccounts
          .filter(account => !!account?.avatars?.[0]?.url)
          .filter(uniqueDefinedAvatar);
    const hasAvatars = this.config?.plugin?.has_avatars ?? false;
    if (
      !hasAvatars ||
      uniqueAvatarAccounts.length === 0 ||
      uniqueAvatarAccounts.length > GrAvatarStack.MAX_STACK
    ) {
      return html`<slot name="fallback"></slot>`;
    }
    return uniqueAvatarAccounts.map(
      account =>
        html`<gr-avatar
          .account=${account}
          .imageSize=${this.imageSize}
          aria-label=${getDisplayName(this.config, account)}
        >
          ${when(
            this.enableHover,
            () =>
              html`<gr-hovercard-account
                .account=${account}
              ></gr-hovercard-account>`
          )}
        </gr-avatar>`
    );
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-avatar-stack': GrAvatarStack;
  }
}
