/**
 * Copyright Aquera Inc 2023
 *
 * This source code is licensed under the BSD-3-Clause license found in the
 * LICENSE file in the root directory of this source tree.
 */

import {
  LitElement,
  html,
  CSSResultArray,
  TemplateResult,
  nothing,
} from 'lit';
import { customElement, state, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';

import { styles } from './nile-avatar.css';
import NileElement from '../internal/nile-element';

/**
 * Nile icon component.
 *
 * @tag nile-avatar
 *
 */
@customElement('nile-avatar')
export class NileAvatar extends NileElement {
  /**
   * The styles for Avatar
   * @remarks If you are extending this class you can extend the base styles with super. Eg `return [super(), myCustomStyles]`
   */
  public static get styles(): CSSResultArray {
    return [styles];
  }

  /** Gives the url to the Avatar */
  @property({ type: String, reflect: true }) src = '';

  /** Gives the icon to the Avatar */
  @property({ type: String, reflect: true }) variant:'icon' | 'image' | 'text' = 'text';

  /** Gives the icon to the Avatar */
  @property({ type: String, reflect: true }) icon = 'var(--nile-icon-user, var(--ng-icon-user-01))';

  /** Gives the default Image Letters to the Avatar */
  @property({ type: String, reflect: true }) name: String = '';

  /** Gives the default bg color  to the Avatar */
  @property({ type: String, reflect: true, attribute: 'bg-color' }) bgColor = '';

  /** Gives the default text color  to the Avatar */
  @property({ type: String, reflect: true, attribute: 'text-color' }) textColor = '';

  /** Gives the default border color  to the Avatar */
  @property({ type: String, reflect: true, attribute: 'border-color' }) borderColor = '';

  /** Size of the Avatar */
  @property({ reflect: true }) size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' = 'md';

  /** Gives a border radius of 50% to the Avatar */
  @property({ type: Boolean, reflect: true }) isRounded = true;

  @state() private imageError = false;

  /* #endregion */

  /* #region Methods */

  private generateInitials(): string {
    if (!this.name) {
      return '';
    }
    const nameParts = this.name
      .split(' ')
      .filter(part => part.length > 0)
      .map(part => part.charAt(0).toUpperCase())
      .slice(0, 2);
    return nameParts.length > 1 ? nameParts[0] + nameParts[1] : nameParts[0];
  }

  private generateVariantCode(initials: string): number {
    const char1 = initials.charCodeAt(0);
    const char2 = initials.length == 1 ? char1 : initials.charCodeAt(1);
    const multifactor = char1 * char2 + (char1 % 23) + (char2 % 23);
    return multifactor % 5;
  }

  private getDefaultIconSize() {
    switch (this.size) {
      case 'xs':
        return '6';
      case 'sm':
        return '10';
      case 'md':
        return '16';
      case 'lg':
        return '20';
      case 'xl':
        return '24';
      case '2xl':
        return '28';
      default:
        return '16';
    }
  }

  public render(): TemplateResult {
    if('image'==this.variant && !this.imageError){
      return this.getImageContent()
    }
    else{
      const defaultInitials = this.generateInitials();
      if('text'==this.variant && defaultInitials){
        return this.getContentWrapped(html`${defaultInitials}`,defaultInitials);
      }
      else{
        return this.getContentWrapped(this.getIconContent(),defaultInitials)
      }
    }
  }

  getContentWrapped(content:TemplateResult,defaultInitials:string){
    const variant__code = this.generateVariantCode(defaultInitials);
    return html`
    <div
      class=${classMap({
        text__avatar: true,
        avatar__xs: this.size === 'xs',
        avatar__small: this.size === 'sm',
        avatar__medium: this.size === 'md',
        avatar__large: this.size === 'lg',
        avatar__extralarge: this.size === 'xl',
        avatar__2xl: this.size === '2xl',
        avatar__rounded: this.isRounded,
        variant__orange: variant__code === 0 && !this.bgColor,
        variant__pink: variant__code === 1 && !this.bgColor,
        variant__blue: variant__code === 2 && !this.bgColor,
        variant__light_blue: variant__code === 3 && !this.bgColor,
        variant__green: variant__code === 4 && !this.bgColor,
      })}
      aria-hidden="true"
      part="avatar__content"
      style="
        background-color: ${this.bgColor};
        color:${this.textColor?this.textColor:"var(--nile-colors-white-base, var(--ng-colors-text-quaternary-500))"};
        border: 1px solid ${this.borderColor ? this.borderColor : 'var(--nile-colors-neutral-500 , var(--ng-colors-border-secondary))'};
        border-color:${defaultInitials ? `${this.borderColor ? this.borderColor : 'var(--nile-colors-neutral-500 , var(--ng-colors-border-secondary))'}` : 'var(--nile-colors-neutral-500 , var(--ng-colors-border-secondary))'}"
    >
      ${content}
    </div>`
  }

  getIconContent(){
    return html`
    <nile-icon
      name="${this.icon}"
      method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))"
      color="${this.textColor?this.textColor:'var(--nile-colors-dark-500, var(--ng-colors-text-quaternary-500))'}"
      size="${this.getDefaultIconSize()}"
    ></nile-icon>`
  }

  getImageContent(){
    return html` 
    <img
      src="${this.src}"
      class="avatar"
      alt="${this.name || 'Avatar'}"
      class=${classMap({
        avatar: true,
        avatar__xs: this.size === 'xs',
        avatar__small: this.size === 'sm',
        avatar__medium: this.size === 'md',
        avatar__large: this.size === 'lg',
        avatar__extralarge: this.size === 'xl',
        avatar__2xl: this.size === '2xl',
        avatar__rounded: this.isRounded,
      })}
      part="avatar__image"
      style="	background-image: url(${this.src}), linear-gradient(lightgray, lightgray);"
      @error="${()=>this.imageError=true}"
      @load="${()=>this.imageError=false}"
    />`
  }

  /* #endregion */
}

export default NileAvatar;

declare global {
  interface HTMLElementTagNameMap {
    'nile-avatar': NileAvatar;
  }
}
