// Angular Core
import { Component, AfterViewInit, Renderer2, ElementRef, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http';

// RxJs
import { Subscription, throwError } from 'rxjs';
import { catchError } from "rxjs/operators";

// Services
import { SessionService } from 'src/app/services/session/session.service';
import { LocalStorageService } from 'src/app/services/localstorage/local-storage.service';

// Interfaces
import { AccountInfoService } from 'src/app/services/accountInfo/account-info.service';
import { UserDataInterface } from 'src/app/interfaces/user/user-data-interface';

// Third Party
import HelloSign from 'hellosign-embedded';
import { SessionDataInterface } from 'src/app/interfaces/session-data-interface';

@Component({
  standalone: false,
  selector: 'app-e-sign',
  templateUrl: './e-sign.component.html',
  styleUrls: ['./e-sign.component.scss']
})
export class ESignComponent implements AfterViewInit, OnDestroy, OnInit {


  session!: SessionDataInterface['data'];
  isBuyer!: boolean;
  renderMe!: boolean;
  regActiveStep: string = 'step3';
  signed: boolean = false;
  isAutoValidated: boolean = false;
  payMethodAdded: boolean = false;

  constructor(private router: Router,
    private accountInfoService: AccountInfoService,
    private sessionService: SessionService,
    private renderer: Renderer2,
    private elementRef: ElementRef,
    private localStorageService: LocalStorageService,
  ) {}

  ngOnInit(): void {
    this.session = this.sessionService.getSession();
    this.isBuyer = this.session.is_buyer;
    this.renderMe = this.session.logged_in && (this.session.reg_step >= 4) && (this.session.is_buyer === true);
    this.hasPayMethods();
  }

    ngAfterViewInit(): void {
      this.getAccount()
    }

  getAccountInfoSubscribe!:Subscription;
  documentUrlSubscribe!:Subscription;
  applicationSignedSubscribe!:Subscription;

  getAccount() {

    if (this.renderMe) {
      this.getAccountInfoSubscribe = this.accountInfoService.getAccountInfo()
        .pipe(
          catchError(() => {
            return throwError(() => new Error('ups sommething happend'));
          })
        )
        .subscribe({
          next: (res: UserDataInterface) => {
            let response = JSON.stringify(res);
            if (res.data.active === 1
              && res.data.approved === 1
              && this.isBuyer === true) {
              this.documentUrlSubscribe = this.accountInfoService.documentUrl()
                .pipe(
                  catchError(() => {
                    return throwError(() => new Error('ups sommething happend'));
                  })
                )
                .subscribe({
                  next: (res: any) => {
                    let result = res;
                    var url = result.data.url;
                    var client_id = result.data.client_id;
                    var user_id = result.data.user_id;
                    var signature_request_id = result.data.signature_request_id;
                    const client = new HelloSign({
                      clientId: client_id,
                    });
                    client.open(url, {
                      allowCancel: true,
                      skipDomainVerification: true,
                      debug: true,
                      container: this.elementRef.nativeElement.querySelector('#application_dialog') ?? undefined,
                    });

                    client.on('sign', (data: any) => {
                      // Reducing the height of hellosign container for next and back button alignment.
                      var params = {
                        'signature_request_id': signature_request_id,
                        'user_id': user_id
                      };
                      this.applicationSignedSubscribe = this.accountInfoService.applicationSigned(params)
                        .pipe(
                          catchError(() => {
                            return throwError(() => new Error('ups sommething happend'));
                          })
                        )
                        .subscribe({
                          next: () => {
                            this.accountInfoService.helloSignEmail(params).subscribe();
                            this.signed = true;
                            this.accountInfoService.isAutoValidated(this.payMethodAdded)
                              .pipe(
                                catchError(() => {
                                  return throwError(() => new Error('ups sommething happend'));
                                })
                              )
                              .subscribe({
                                next: (response: any) => {
                                  this.sessionService.reCheckSession();
                                  this.isAutoValidated = response.data.autoValidated;
                                  this.localStorageService.setItem('autoValidate', String(this.isAutoValidated));
                                },
                                error: (err: any) => {
                                  this.accountInfoService.errorCallBack(err)
                                },
                                complete: () => { }
                              });

                          },
                          error: (err: HttpErrorResponse) => {
                            this.accountInfoService.errorCallBack(err)
                          },
                          complete: () => { }
                        });
                    });

                    client.on('close', () => {
                    });
                  },
                  error: (err: HttpErrorResponse) => {
                    this.accountInfoService.errorCallBack(err);
                  },
                  complete: () => { }
                });

            } else {
              this.router.navigate(['/market/payment'])
            }
          },
          error: (err: HttpErrorResponse) => {
            this.accountInfoService.errorCallBack(err);
          },
          complete: () => { }
        });
    }

  }

    hasPayMethodsSubscribe!:Subscription;
    hasPayMethods() {
        this.hasPayMethodsSubscribe = this.accountInfoService
            .hasPayMethods()
            .pipe(
                catchError(() => {
                  return throwError(() => new Error('ups sommething happend'));
                })
            )
            .subscribe({
                next: (res: any) => {
                  if (res.data !== false) {
                    this.payMethodAdded = true;
                  }
                },
                error: (err: HttpErrorResponse) => {
                  this.accountInfoService.errorCallBack(err);
                },
                complete: () => { }
            });
    };

  previousStep() {
    this.router.navigate(['/market/questionnaire'])
  };

    saveUserInfoSubscribe!:Subscription;
    nextStep() {
        if (this.isAutoValidated && this.payMethodAdded) {
          this.router.navigate(['/market/home'])
        } else if (this.payMethodAdded) {
            let paymentStepInfo = {
              'xu_payment_step': 1,
            };
            this.saveUserInfoSubscribe = this.accountInfoService.saveUserInfo(paymentStepInfo)
            .pipe(
              catchError(() => {
                return throwError(() => new Error('ups sommething happend'));
              })
            ).subscribe({
              next: () => {
                this.sessionService.reCheckSession();
                this.router.navigate(['/market/licenseVerification']);
              },
              error: (err: HttpErrorResponse) => {
                this.accountInfoService.errorCallBack(err);
              }
            });
        } else {
            this.router.navigate(['/market/payment'])
        }
    };

    ngOnDestroy(){
        this.getAccountInfoSubscribe?.unsubscribe();
        this.documentUrlSubscribe?.unsubscribe();
        this.applicationSignedSubscribe?.unsubscribe();
        this.hasPayMethodsSubscribe?.unsubscribe();
        this.saveUserInfoSubscribe?.unsubscribe();
    }
}
