/*
 * Copyright (C) 2022 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

import {Component, ElementRef, HostListener, Input, OnChanges, OnInit, ViewChild} from '@angular/core';
import {SCThings} from '@openstapps/core';
import {SCIcon} from '../../../util/ion-icon/icon';

const AccordionButtonState = {
  collapsed: SCIcon.expand_more,
  expanded: SCIcon.expand_less,
};

@Component({
  selector: 'stapps-title-card',
  templateUrl: './title-card.component.html',
  styleUrls: ['./title-card.component.scss'],
})
export class TitleCardComponent implements OnInit, OnChanges {
  /**
   * The item whose title (and description) to display
   */
  @Input() item: SCThings;

  @ViewChild('accordionTextArea') accordionTextArea: ElementRef;

  buttonState: (typeof AccordionButtonState)[keyof typeof AccordionButtonState] =
    AccordionButtonState.collapsed;

  buttonShown = true;

  descriptionLinesShown: number;

  descriptionLinesTotal: number;

  descriptionPreviewLines = 3;

  descriptionLinesToDisplay = 0;

  ngOnInit(): void {
    if (this.item.description) {
      this.descriptionLinesToDisplay = this.descriptionPreviewLines;
      setTimeout(() => this.checkTextElipsis(), 100);
    }
  }

  ngOnChanges() {
    this.checkTextElipsis();
  }

  @HostListener('window:resize', ['$event'])
  checkTextElipsis() {
    if (this.accordionTextArea === undefined) {
      return;
    }
    const element = this.accordionTextArea.nativeElement as HTMLElement;

    const lineHeight = Number.parseInt(getComputedStyle(element).getPropertyValue('line-height'));
    this.descriptionLinesTotal = element?.scrollHeight / lineHeight;
    this.descriptionLinesShown = element?.offsetHeight / lineHeight;
    if (this.buttonState === AccordionButtonState.expanded) {
      this.descriptionLinesToDisplay = this.descriptionLinesTotal;
    }
    const isElipsed = element?.offsetHeight < element?.scrollHeight;
    this.buttonShown =
      (isElipsed && this.buttonState === AccordionButtonState.collapsed) ||
      (!isElipsed && this.buttonState === AccordionButtonState.expanded);
  }

  toggleDescriptionAccordion() {
    if (this.descriptionLinesToDisplay > 0) {
      this.descriptionLinesToDisplay =
        this.descriptionLinesToDisplay === this.descriptionPreviewLines
          ? this.descriptionLinesTotal
          : this.descriptionPreviewLines;
    }
    this.buttonState =
      this.buttonState === AccordionButtonState.collapsed
        ? AccordionButtonState.expanded
        : AccordionButtonState.collapsed;
    setTimeout(() => this.checkTextElipsis(), 0);
  }
}
