import {Injectable} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import {HttpClient, HttpParams, HttpHeaders} from '@angular/common/http';
import {UserService} from './user.service';
import { Owner } from './owner.model';

import { ConfigData } from './configdata';

var Buffer = require('buffer/').Buffer;
//import {User} from './user.model';

@Injectable({providedIn: 'root'})
export class FullnodeService{
	beUrl = ConfigData.Be_URL;
	private session: null|string = '';
	private dataStore: { height: number, memoList: string[], addr: string, price: number } = { height: 0, memoList: [], addr: '', price:0 };
	private _heightUpdated: BehaviorSubject<number> = new BehaviorSubject(this.dataStore.height);
	private _memoUpdated: BehaviorSubject<string[]> = new BehaviorSubject(this.dataStore.memoList);
	private _addrUpdated: BehaviorSubject<string> = new BehaviorSubject(this.dataStore.addr);
	private _priceUpdated: BehaviorSubject<number> = new BehaviorSubject(this.dataStore.price);
	public readonly addrUpdate: Observable<string> = this._addrUpdated.asObservable();
	public readonly heightUpdate: Observable<number> = this._heightUpdated.asObservable();
	public readonly memoUpdate: Observable<string[]> = this._memoUpdated.asObservable();
	public readonly priceUpdate: Observable<number> = this._priceUpdated.asObservable();
	public readonly ownerUpdate: Observable<Owner>;
	private reqHeaders: HttpHeaders;
	private params : HttpParams;
	private owner: Owner = {
		_id: '',
		name: '',
		address: '',
		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: ''
	};

	constructor(private http: HttpClient, public userService: UserService){
		this.session = localStorage.getItem('s4z_token');
		this.params = new HttpParams().append('session', this.session!);
		var auth = 'Basic ' + Buffer.from(ConfigData.UsrPwd).toString('base64');
		this.reqHeaders = new HttpHeaders().set('Authorization', auth);
		this.ownerUpdate = userService.ownerUpdate;
		this.getAddr();
		this.getHeight();
		this.ownerUpdate.subscribe((owner) => {
			this.owner = owner;
			this.getPrice(this.owner.currency);
		});
	}

	getHeight(){
		let obs = this.http.get<{message: string, height: number}>(this.beUrl+'blockheight', { headers: this.reqHeaders, params: this.params });
		obs.subscribe((BlockData) => {
			this.dataStore.height = BlockData.height;
			this._heightUpdated.next(Object.assign({}, this.dataStore).height);
		});

		return obs;
	}

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

		return obs;
	}

	getAddr() {
		let obs = this.http.get<{message: string, addr: string}>(this.beUrl+'getaddr', { headers: this.reqHeaders, params: this.params });

		obs.subscribe((AddrData) => {
			this.dataStore.addr = AddrData.addr;
			this._addrUpdated.next(Object.assign({}, this.dataStore).addr);
		});

		return obs;
	}
}
