import {
  LitElement,
  html,
  CSSResultArray,
  TemplateResult,
} from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { styles } from './nile-error-message.css';

/**
 * A custom error message component that displays error information to the user.
 * @customElement nile-error-message
 */
@customElement('nile-error-message')
export class NileErrorMessage extends LitElement {
  public static get styles(): CSSResultArray {
    return [styles];
  }

  // Represents the error message to be displayed to the user.
  @property({ type: String })
  errorMessage: string = '';

  // Represents additional details about the error, like stack trace or other info.
  @property({ type: String })
  errorResponse: string;

  // Extended error information
  @property({ type: String })
  errorResponseLong: string;

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

  @property({ type: String }) maxWidth: string;

  @property({ type: String }) maxHeight: string;

  @property({ type: String }) maxDialogHeight: string;

  // The maximum length before truncation.
  private readonly MAX_LENGTH: number = 100;

  /**
   * Get a truncated version of the errorResponse if it's too long.
   * @returns {string}
   */
  getTruncatedResponse(): string {
    if (this.errorResponse.length > this.MAX_LENGTH) {
      return `${this.errorResponse.substring(0, this.MAX_LENGTH)}...`;
    }
    return this.errorResponse;
  }

  updated(changedProperties: Map<string, any>) {
    if (changedProperties.has('maxWidth')) {
      this.style.setProperty('--nile-error-max-width', this.maxWidth);
    }
    if (changedProperties.has('maxHeight')) {
      this.style.setProperty('--nile-error-max-height', this.maxHeight);
    }
    if (changedProperties.has('maxDialogHeight')) {
      this.style.setProperty('--nile-error-max-dialog-height', this.maxDialogHeight);
    }
  }

  /**
   * Toggle the expanded state of the error response.
   */
  toggleExpanded() {
    this.isExpanded = !this.isExpanded;
  }

  public render(): TemplateResult {
    const iconName = this.isExpanded ? 'var(--nile-icon-arrow-up, var(--ng-icon-chevron-up))' : 'var(--nile-icon-arrow-down, var(--ng-icon-chevron-down))';

    return html`
      <div class="nile-error-message" part="base">
        <nile-icon
          name="var(--nile-icon-info, var(--ng-icon-info-circle))"
          method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))"
          size="14"
          class="nile-error-message__icon"
          part="icon"
          color="var(--nile-colors-red-700, var(--ng-colors-fg-error-primary))"
        ></nile-icon>
        <span class="nile-error-message__error">${this.errorMessage}</span>


        ${this.errorResponse
        ? html`
            <div class="nile-error-message__response">
            ${this.errorResponse}
            ${this.errorResponseLong
                ? html`
              <span
              class="nile-error-message__more-button"
              @click=${this.toggleExpanded}
              >${this.isExpanded ? 'View Less' : 'View More'}
              <nile-icon color="var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600))" part="icon" size="14" name="${iconName}" method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))"></nile-icon>
              </span
            > `:``}
            </div>
            `
        : ``}

        <div
          class="nile-error-message__response-expanded ${this.isExpanded
            ? 'expanded'
            : 'collapsed'}"
        >
          ${this.errorResponseLong}
        </div>
      </div>
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'nile-error-message': NileErrorMessage;
  }
}
