import {
  AfterViewInit,
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  EventEmitter,
  inject,
  Input,
  OnChanges,
  OnDestroy,
  OnInit,
  Output,
  SimpleChanges,
  ViewChild,
} from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { loadStripe, Stripe } from '@stripe/stripe-js';
import { debounceTime } from 'rxjs';
import { CommonModule } from '@angular/common';
import gsap from 'gsap';
import { DepositService } from '@service/deposit.service';
import { environment } from '@environments/environment';
import { ModalAnimationService } from '@shared/services/modal-animation.service';

@Component({
  selector: 'app-deposit',
  standalone: true,
  imports: [ReactiveFormsModule, CommonModule],
  templateUrl: './deposit.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DepositComponent implements OnInit, AfterViewInit, OnDestroy, OnChanges {
  @Input() isOpen = false;
  @Output() closeModalEmitter = new EventEmitter<void>();
  @ViewChild('modalBg') modalBg!: ElementRef;
  @ViewChild('modalCard') modalCard!: ElementRef;
  protected form!: FormGroup;
  protected errorMsg = '';
  private stripe: Stripe | null = null;
  private service: DepositService = inject(DepositService);
  private modalAnimationService: ModalAnimationService = inject(ModalAnimationService);
  private cdr: ChangeDetectorRef = inject(ChangeDetectorRef);

  async ngOnInit() {
    this.form = new FormGroup({
      amount: new FormControl(50, [Validators.min(50)]),
    });

    this.form.controls['amount'].valueChanges.pipe(debounceTime(1000)).subscribe((value) => {
      if (value < 50) {
        this.errorMsg = 'Minimum Einzahlungsbetrag ist 50€';
      }
    });

    this.stripe = await loadStripe(environment.STRIPE_KEY);
  }

  ngAfterViewInit() {
    if (this.isOpen) {
      this.openModal();
    }
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes['isOpen']) {
      this.cdr.detectChanges();
      setTimeout(() => {
        if (this.modalBg?.nativeElement && this.modalCard?.nativeElement) {
          if (changes['isOpen'].currentValue) {
            this.openModal();
          } else {
            this.closeModal();
          }
        }
      }, 0);
    }
  }

  ngOnDestroy() {
    gsap.killTweensOf([this.modalBg?.nativeElement, this.modalCard?.nativeElement]);
  }

  private openModal() {
    if (this.modalBg?.nativeElement && this.modalCard?.nativeElement) {
      this.modalAnimationService.openModal(
        this.modalCard.nativeElement,
        this.modalBg.nativeElement
      );
    }
  }

  submit() {
    if (!this.stripe) {
      this.errorMsg = 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.';
      return;
    }
    if (!this.form.valid) {
      this.errorMsg = 'Bitte geben Sie einen gültigen Betrag ein.';
      return;
    }

    this.service.handleDeposit(this.form.value.amount as number).subscribe(({ sessionId }) => {
      this.stripe?.redirectToCheckout({ sessionId });
    });
  }

  public closeModal() {
    if (this.modalBg?.nativeElement && this.modalCard?.nativeElement) {
      this.modalAnimationService.closeModal(
        this.modalCard.nativeElement,
        this.modalBg.nativeElement,
        () => this.closeModalEmitter.emit()
      );
    }
  }
}
