import { Component, OnInit } from '@angular/core';
import { ActivatedRoute} from "@angular/router";
import { HttpClient, HttpParams, HttpHeaders } from "@angular/common/http";
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { PmtData } from "./pmtservice.model";
import { XeroInvoice } from "./xeroinvoice.model";
import { Owner } from '../owner.model';
// import { Item } from '../items/item.model'
import { Order } from '../order/order.model'
import { ConfigData } from '../configdata';
import { faCheck, faHourglass } from '@fortawesome/free-solid-svg-icons';

import { NotifierService } from '../notifier.service';

var QRCode = require('easyqrcodejs');
var URLSafeBase64 = require('urlsafe-base64');
var Buffer = require('buffer/').Buffer;

import { LanguageService } from '../language.service';

@Component({
  selector: 'app-pmtservice',
  templateUrl: './pmtservice.component.html',
  styleUrls: ['./pmtservice.component.css']
})

export class PmtserviceComponent implements OnInit {

  faCheck = faCheck;
  faHourglass = faHourglass;

  beUrl = ConfigData.Be_URL;
  private reqHeaders: HttpHeaders = new HttpHeaders();

  public pmtData : PmtData = {
      ownerId :'',
      invoice: '',
      amount: 0,
      currency: '',
      shortcode: ''
  };

  public invData : XeroInvoice = { 
      inv_Type : '',
      inv_Id : '',
      inv_No : '',
      inv_Contact : '',
      inv_Currency : '',
      inv_CurrencyRate : 0,
      inv_Status : '',
      inv_Total : 0,
      inv_Date : new Date(),
      inv_shortCode : '',
      inv_ProcDate : new Date()
  };

  public owner: Owner = {
         _id: '',
         address: '',
         name: '',
         currency: 'usd',
         tax: false,
         taxValue: 0,
         vat: false,
         vatValue: 0,
         paid: false,
         zats: false,
         invoices: false,
         expiration: new Date(Date.now()).toISOString(),
         payconf: false,
		 crmToken: ''
      }; 

public order: Order = {
         _id : '',
         address: '',
         session: '',
         timestamp: '',
         closed: false,
         currency: '',
         price: 0,
         total: 0,
         totalZec: 0,
         paid: false,
         externalInvoice: '',
         shortCode: '',
         lines: [
            {
               qty: 1,
               name: '',
               cost:0
            }
         ]
      };

 private invData_raw : string = '';
 private invData_buff : any = null;

 public reportType = 1000;
 public Status = 0;

 codeString: string = '';
 zcashUrl: SafeUrl = '';
 zPrice: number = 1.0;
 name: string = '';
 error: boolean = false;
 orderId : string = '';
// -------------------------------------
// Language Support
//
vE = {
   pmtserviceInvalidOwnerid : '',
   pmtserviceNotservClose : '',
   pmtserviceNotservError : '',
   pmtserviceCopyNotavail : '',
   pmtserviceCopyaddressError : '',
   pmtserviceCopyamountError : '',
   pmtserviceCopymemoError : '',
   pmtservicePaymentNotprocessed : '',
   pmtservicePmtsrvNot : '',
   pmtserviceEnabledFor : '',
   pmtserviceConnectoXero : '',
   pmtserviceServerFailed : '',
   pmtserviceInvoiceNum : '',
   pmtserviceInvoiceNotfound : '',
   pmtserviceInvoiceInvalid : '',
   pmtserviceInvoicePaid : '',
   pmtserviceInvoiceCurrency : '',
   pmtserviceCurrencyNotsup : '',
   pmtserviceAmountDoesnot : '',
   pmtserviceMatchValue : '', 
   pmtserviceReportedByxero : '',
   pmtserviceHdrTxt1 : '',
   pmtserviceHdrTxt2 : '',
   pmtserviceHdrTxt3 : '',
   pmtserviceZecdataPrice : '',
   pmtserviceZecdataTotal : '',
   pmtserviceInvoiceItem : '',
   pmtserviceInvoiceQty : '',
   pmtserviceInvoicePrice : '',
   pmtserviceInvoiceTotal : '',
   pmtservicePaymentConfirmed : '',
   pmtservicePaymentPending : '',
   pmtserviceScanQrcode : '',
   pmtserviceCantScan : '',
   pmtserviceUseThis : '',
   pmtserviceWalletLink : '',
   pmtserviceCopyAddress : '',
   pmtserviceCopyAmount : '',
   pmtserviceCopyMemo : ''
}
//
  constructor(private activatedRoute : ActivatedRoute,
              private http : HttpClient,
              private sanitizer: DomSanitizer,
              private notifierService : NotifierService,
              private languageService : LanguageService  ) {}

  ngOnInit() {
   var auth = 'Basic ' + Buffer.from(ConfigData.UsrPwd).toString('base64');
   this.reqHeaders = new HttpHeaders().set('Authorization', auth);
   this.activatedRoute.queryParams.subscribe((params) => {
      this.pmtData.ownerId = params["owner"];
      this.pmtData.invoice = params["invoiceNo"];
      this.pmtData.amount = params["amount"];
      this.pmtData.currency = params["currency"];
      this.pmtData.shortcode = params["shortCode"];
      this.getInvoiceData( this.pmtData );
    });
   this.chgUILanguage();
  }

  getInvoiceData( reqData : PmtData ) { 
    
    // 
    // Verify owner id ( Status = 1 if not exists )
    //                 ( Status = 2 if service not available for user )
    //
//    console.log('getOwner -> '+ reqData.ownerId);
//    console.log('received amount -> ' + reqData.amount);
    const ownParams = new HttpParams().append('id', reqData.ownerId);
    let obs = this.http.get<{message:string, owner: any}>
                            ( this.beUrl+'api/ownerid', 
                            { headers: this.reqHeaders,
                              params: ownParams, 
                              observe: 'response'});
    obs.subscribe((OwnerDataResponse) => {
         //console.log('api/getowner', OwnerDataResponse.status);
         if (OwnerDataResponse.status == 200) {
            this.owner = OwnerDataResponse.body!.owner;
            console.log('Owner => ' + this.owner.name );
//
// ==> remove "== false" for production enviroment
// 
            if ( this.owner.invoices ) {
               // process data
               console.log("Owner check passed!!!");
               this.getXeroInvoiceData( reqData );
            } else {
               console.log("Owner check failed!!!") 
               this.reportType = 2;
            };
         } else {
            if ( OwnerDataResponse.status == 204 ) {
               console.log('Res.Status = ' + OwnerDataResponse.status)
               console.log('Owner id not found!!!');
               this.reportType = 1;
            }
         }});
  }

  getXeroInvoiceData( reqData : PmtData  )  { 

/*
    // Call test Xero API 
    let url : string = "http://localhost:3000/xero/" + reqData.invoice;
    this.http
         .get<any>(url)
*/
   console.log('>> find current zcash price');
   this.getPrice(this.owner.currency);

    console.log('get Invoice -> ' + reqData.invoice);
    let invParams = new HttpParams();
    invParams = invParams.append('address', this.owner.address);
    invParams = invParams.append('inv', reqData.invoice);
    let inv = this.http.get<{message:string, invData: any}>
                            ( this.beUrl+'api/invdata', 
                            { headers: this.reqHeaders,
                              params: invParams, 
                              observe: 'response'});
    inv.subscribe( invDataResponse => {
//                  console.log('Response from ZGo-Xero');
//                  console.log(invDataResponse.status);
                  this.invData_buff = invDataResponse.body;
                  this.invData.inv_Type = this.invData_buff.invdata.inv_Type;
                  this.invData.inv_Id = this.invData_buff.invdata.inv_Id;
                  this.invData.inv_No = this.invData_buff.invdata.inv_No;
                  this.invData.inv_Contact = this.invData_buff.invdata.inv_Contact;
                  this.invData.inv_Currency = this.invData_buff.invdata.inv_Currency;
                  this.invData.inv_CurrencyRate = this.invData_buff.invdata.inv_CurrencyRate;
                  this.invData.inv_Total = this.invData_buff.invdata.inv_Total;
                  this.invData.inv_Status = this.invData_buff.invdata.inv_Status;
                  this.invData.inv_Date = this.invData_buff.invdata.inv_Date;
                  this.invData.inv_shortCode = reqData.shortcode;
 /*              
                  console.log('>>> inv_Type -> ' + this.invData.inv_Type);
                  console.log('>>> inv_Id -> ' + this.invData.inv_Id);
                  console.log('>>> inv_No -> ' + this.invData.inv_No);
                  console.log('>>> inv_Contact -> ' + this.invData.inv_Contact);
                  console.log('>>> inv_Currency-> ' + this.invData.inv_Currency);
                  console.log('>>> inv_CurrencyRate -> ' + this.invData.inv_CurrencyRate);
                  console.log('>>> inv_Total -> ' + this.invData.inv_Total);
                  console.log('>>> inv_Status-> ' + this.invData.inv_Status);
                  console.log('>>> inv_Date -> ' + this.invData.inv_Date);
*/
                  if ( this.invData.inv_Type == 'ACCREC' ) {
                     console.log('Invoice type is correct!!');
                     // Test if invoice is not already paid
                     if ( this.invData.inv_Status == 'AUTHORISED') {
                           console.log('invoice is payable');
                        // Test if Invoice's currency is supported
                        if ( this.invData.inv_Currency == reqData.currency ) {
                           console.log('Invoice currency supported');
                           // Test if requested amount is as reported by Xero
                           if ( this.invData.inv_Total == reqData.amount ) {
                              console.log('Invoice amount Ok - create Order');
     // =====> Create order here
                              this.createOrder();
   //
                           } else {
                              console.log('Invoice amount does not match')
                              this.reportType = 8;
                           }
                        } else {
                           console.log('Invoice currency not supported');
                           this.reportType = 7;
                        }
                     } else {
                        console.log('Invoice already paid');
                        this.reportType = 6; 
                     }
                  } else {
                     console.log('Invoice type is invalid' );
                     this.reportType = 5;
                  }
               }, 
       error => {
                  console.log("Error while getting invData!!!");
                  console.log(error);
                  console.log(error.status);
                  if ( error.status == 500 ) {
                     // Assume that invoice was not found by haskell server
                     this.reportType = 4;
                  }

               });
  }

  createOrder() {
      this.reportType = 0;
//      console.log('Starting order generation');
//      console.log('>> find current zcash price');

      this.order = {
         _id: '',
         address: this.owner.address,
         session: 'Xero-' + this.owner._id,
         currency: this.owner.currency,
         timestamp: new Date(Date.now()).toISOString(),
         closed: true,
         totalZec: this.invData.inv_Total/this.zPrice,
         price: this.zPrice,
         total: this.invData.inv_Total,
         paid: false,
         externalInvoice: this.invData.inv_No,
         shortCode: this.invData.inv_shortCode,
         lines: [{qty: 1,
                  name: 'Invoice from ' + this.owner.name + '[' + this.invData.inv_No + ']',
                  cost: this.invData.inv_Total}]
      };
 
      let obs = this.http.post<{message: string, order: Order}>
                (this.beUrl+'api/orderx', 
                 {payload: this.order},
                 { headers: this.reqHeaders }
                );
      obs.subscribe((orderData) => {
//         console.log('Order created');

//         console.log(orderData.order);
         this.order = orderData.order
         console.log('>> order -> ' + JSON.stringify(this.order));
         this.orderId = String(this.order._id);

//         console.log('Generating QRCode....')

         this.codeString = `zcash:${this.order.address}?amount=${this.order.totalZec.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGo Order::'.concat(this.orderId).concat(' Invoice: ').concat(orderData.order.externalInvoice)))}`; 

         var qrcode = new QRCode(document.getElementById("payment-qr"), {
           text: this.codeString,
               logo: "/assets/zcash.png",
               width: 180,
               height: 180,
               logoWidth: 50,
               logoHeight: 50,
           correctLevel: QRCode.CorrectLevel.H
         });

         this.zcashUrl = this.sanitizer.bypassSecurityTrustUrl(this.codeString);
      }, error => {
         console.log(error.message);
      
      });
   }

   getIconStyle(order : Order) {
      if( order.paid )
        return "font-size: 14px; color: #72cc50; margin-bottom: -2px;";
      return "color: #FB4F14; margin-bottom: -2px; cursor: pointer;";

   }

   getPrice(currency: string){
      //var currency = 'usd';
      const params = new HttpParams().append('currency', currency);
      let obs = this.http.get<{message: string, price: any}>(this.beUrl+'api/price', { headers:this.reqHeaders, params: params, observe: 'response'});
      obs.subscribe((PriceData) => {
         if (PriceData.status == 200) {
            this.zPrice = PriceData.body!.price.price;
            console.log("price", this.zPrice);
         } else {
            console.log('No price found for currency', currency);
            this.zPrice = 1.0;
         }
      });
     return obs;
   }

   copyAddress() {
      if (!navigator.clipboard) {
//       alert("Copy functionality not supported");
         this.notifierService
             .showNotification(this.vE.pmtserviceCopyNotavail,
               this.vE.pmtserviceNotservClose,
               "error",
               this.vE.pmtserviceNotservError);
      }
      try {
         navigator.clipboard.writeText(this.order.address);
      } catch (err) {
         this.notifierService
             .showNotification(this.vE.pmtserviceCopyaddressError,
               this.vE.pmtserviceNotservClose,
               "error",
               this.vE.pmtserviceNotservError);
//       console.error("Error", err);
      }
   }
   copyAmount() {
      if (!navigator.clipboard) {
//       alert("Copy functionality not supported");
         this.notifierService
             .showNotification(this.vE.pmtserviceCopyNotavail,
               this.vE.pmtserviceNotservClose,
               "error",
               this.vE.pmtserviceNotservError);
      }
      try {
         navigator.clipboard.writeText(this.order.totalZec.toString());
      } catch (err) {
         this.notifierService
             .showNotification(this.vE.pmtserviceCopyamountError,
               this.vE.pmtserviceNotservClose,
               "error",
               this.vE.pmtserviceNotservError);
//       console.error("Error", err);
      }
   }

   copyMemo() {
      if (!navigator.clipboard) {
//       alert("Copy functionality not supported");
         this.notifierService
             .showNotification(this.vE.pmtserviceCopyNotavail,
               this.vE.pmtserviceNotservClose,
               "error",
               this.vE.pmtserviceNotservError);
      }
      try {
         navigator.clipboard.writeText("ZGo Order::" + this.orderId + " Invoice: " + this.order.externalInvoice);
      } catch (err) {
         this.notifierService
             .showNotification(this.vE.pmtserviceCopymemoError,
               this.vE.pmtserviceNotservClose,
               "error",
               this.vE.pmtserviceNotservError);
//       console.error("Error", err);
      }
   }

   chgUILanguage(){
      console.log('PMTSERVICE.chgUILanguage Called ');
      this.languageService.getViewElements('pmtservice').subscribe(
         response => { 
               console.log('Received >> ', response );
               console.log('Language Code : ', response.language);
               console.log('Component Name : ',response.component);
               console.log('Language data : ',response.data);

               this.vE.pmtserviceInvalidOwnerid = response.data.pmtservice_invalid_ownerid;
               this.vE.pmtserviceNotservClose = response.data.pmtservice_notserv_close;
               this.vE.pmtserviceNotservError = response.data.pmtservice_notserv_error;
               this.vE.pmtserviceCopyNotavail = response.data.pmtservice_copy_notavail;
               this.vE.pmtserviceCopyaddressError = response.data.pmtservice_copyaddress_error;
               this.vE.pmtserviceCopyamountError = response.data.pmtservice_copyamount_error;
               this.vE.pmtserviceCopymemoError = response.data.pmtservice_copymemo_error;
               this.vE.pmtservicePaymentNotprocessed = response.data.pmtservice_payment_notprocessed;
               this.vE.pmtservicePmtsrvNot = response.data.pmtservice_pmtsrv_not;
               this.vE.pmtserviceEnabledFor = response.data.pmtservice_enabled_for;
               this.vE.pmtserviceConnectoXero = response.data.pmtservice_connecto_xero;
               this.vE.pmtserviceServerFailed = response.data.pmtservice_server_failed;
               this.vE.pmtserviceInvoiceNum = response.data.pmtservice_invoice_num;
               this.vE.pmtserviceInvoiceNotfound = response.data.pmtservice_invoice_notfound;
               this.vE.pmtserviceInvoiceInvalid = response.data.pmtservice_invoice_invalid;
               this.vE.pmtserviceInvoicePaid = response.data.pmtservice_invoice_paid;
               this.vE.pmtserviceInvoiceCurrency = response.data.pmtservice_invoice_currency; 
               this.vE.pmtserviceCurrencyNotsup = response.data.pmtservice_currensy_notsup; 
               this.vE.pmtserviceAmountDoesnot = response.data.pmtservice_amount_doesnot;
               this.vE.pmtserviceMatchValue = response.data.pmtservice_match_value;
               this.vE.pmtserviceReportedByxero = response.data.pmtservice_reported_byxero;
               this.vE.pmtserviceHdrTxt1 = response.data.pmtservice_hdr_txt1;
               this.vE.pmtserviceHdrTxt2 = response.data.pmtservice_hdr_txt2;
               this.vE.pmtserviceHdrTxt3 = response.data.pmtservice_hdr_txt3;
               this.vE.pmtserviceZecdataPrice = response.data.pmtservice_zecdata_price;
               this.vE.pmtserviceZecdataTotal = response.data.pmtservice_zecdata_total;
               this.vE.pmtserviceInvoiceItem = response.data.pmtservice_invoice_item;
               this.vE.pmtserviceInvoiceQty = response.data.pmtservice_invoice_qty;
               this.vE.pmtserviceInvoicePrice = response.data.pmtservice_invoice_price;
               this.vE.pmtserviceInvoiceTotal = response.data.pmtservice_invoice_total;
               this.vE.pmtservicePaymentConfirmed = response.data.pmtservice_payment_confirmed;
               this.vE.pmtservicePaymentPending = response.data.pmtservice_payment_pending;
               this.vE.pmtserviceScanQrcode = response.data.pmtservice_scan_qrcode;
               this.vE.pmtserviceCantScan = response.data.pmtservice_cant_scan;
               this.vE.pmtserviceUseThis = response.data.pmtservice_use_this;
               this.vE.pmtserviceWalletLink = response.data.pmtservice_wallet_link;
               this.vE.pmtserviceCopyAddress = response.data.pmtservice_copy_address;
               this.vE.pmtserviceCopyAmount = response.data.pmtservice_copy_amount;
               this.vE.pmtserviceCopyMemo = response.data.pmtservice_copy_memo;
 
           },
               error  => { console.log('Error >> ',error); }
         );
   }  

}
