import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  ElementRef,
  Input,
  OnChanges,
  SimpleChanges,
  ViewChild,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { CountUp } from 'countup.js';

@Component({
  selector: 'app-animated-number',
  standalone: true,
  imports: [CommonModule],
  template: ` <span #numberElement>{{ formattedValue }}</span> `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AnimatedNumberComponent implements OnChanges, AfterViewInit {
  @Input() value = 0;
  @Input() duration = 1;
  @Input() ease = 'power1.out';

  @ViewChild('numberElement') numberElement!: ElementRef;

  private countUp: CountUp | null = null;
  private previousValue = 0;
  formattedValue = '0,00 €';

  ngAfterViewInit(): void {
    this.initializeCountUp();
    if (this.countUp && this.value !== 0) {
      this.countUp.start(() => {
        this.previousValue = this.value;
      });
    }
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['value']) {
      if (this.countUp) {
        const endVal = this.value;

        this.countUp.update(endVal);
        this.previousValue = endVal;
      } else {
        this.formattedValue = new Intl.NumberFormat('de-DE', {
          style: 'currency',
          currency: 'EUR',
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        }).format(this.value);
      }
    }
  }

  private initializeCountUp(): void {
    if (this.numberElement) {
      this.countUp = new CountUp(this.numberElement.nativeElement, this.value, {
        startVal: this.previousValue,
        duration: this.duration,
        decimalPlaces: 2,
        useEasing: true,
        useGrouping: false,
        easingFn: (t, b, c, d) => {
          if (this.ease === 'power1.out') {
            return c * (1 - Math.pow(1 - t / d, 1)) + b;
          }
          return c * (t / d) + b;
        },
        formattingFn: (value) => {
          const formatted = new Intl.NumberFormat('de-DE', {
            style: 'currency',
            currency: 'EUR',
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
          }).format(value);
          this.formattedValue = formatted;
          return formatted;
        },
      });
    }
  }
}
