// NG imports
import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'

// Libraries
import { Observable, Subject } from 'rxjs'
import { tap } from 'rxjs/operators'

// Settings
import { apikey, server, websiteId, storeId } from '@k-settings/store-helper'
import { is_local } from '@k-settings/app-setup'

// Dummy
import { dummyComments } from './dummy-comments'

// Services
import { CacheService } from '@k-services/general/svc.cache'
import { HelperService } from '@k-core/services/svc.helper'

@Injectable()
export class StatusService {
	
	// ---- Variables ---- \\

	// Observables
	commentsSource = new Subject()
	comments$ = this.commentsSource.asObservable()


	constructor(
		private _http: HttpClient,
		private _cache: CacheService,
		private helper: HelperService
	) { }




	// ---- Functions ---- \\


	// ---- Public

	// SET
	public setComment(quote_id: string, message) {
		return this._setMessage(quote_id, message, 'comment')
	}

	public setStatus(quote_id: string, status) {
		return this._setMessage(quote_id, status, 'status')
	}


	public removeComment(comment_id: string) {

	}




	// GET

	/**
	 * Get comments array from server
	 */
	public getComments(quote_id: string) {
		return this._getComments(quote_id)
	}


	/**
	 * Get status codes from server or from cache
	 * 
	 * @returns `[{value: string, label: string}]`
	 */
	public getStatusCodes() {
		return this._getStatusCodes()
	}


	/**
	 * Returns http observable for current status code
	 * 
	 * @param quote_id 
	 */
	public getStatusCode(quote_id: string) {
		return this._getCurrentStatus(quote_id)
	}




	// ---- Private


	/**
	 * Sets message and refresh observable after success
	 * 
	 * @param quote_id 
	 * @param message 
	 * @param type 
	 */
	private _setMessage(quote_id: string, message: string, type: string = 'comment') {
		let data = {
			quote_id: quote_id, 
			[type]: message,
			key: apikey,
			websiteId: websiteId,
			storeId: storeId
		}


		return this._http.post(server + '/feed/set/add-comment', data).pipe(
			tap((resp: any) => {
				
				if(resp.status === 'success') {
					// Refresh comments
					this._getComments(quote_id)
	
				}
				else if(resp.status === 'error') {
					console.error('could not submit message: ', resp.data.errorMessage)
				}
			})
		)

	}


	/**
	 * Get comments for quote and update observable
	 * 
	 * @param quote_id 
	 */
	private _getComments(quote_id: string) {
		// reset comments
		this.commentsSource.next([])

		let data = {
			quote_id: quote_id,
			noCache: true,
			key: apikey,
			websiteId: websiteId,
			storeId: storeId
		}

		this._http.post(server + '/feed/get/comments', data).subscribe((resp: any) => {

			if(is_local) {
				// Dummy data for local
				console.warn('is local, using dummy data')
				this.commentsSource.next(dummyComments)
			}
			else if(resp.data && !!resp.data.comments && !!resp.data.comments.length) {
				this.commentsSource.next(resp.data.comments)
			}
			else {
				console.error('could not find any comments')
			}

			return resp.data
		})
	}



	/**
	 * Get status codes from server or from cache
	 * 
	 * @returns `[{value: string, label: string}]`
	 */
	private _getStatusCodes() {
		let cachedStatusCodes = this._cache.get('status-codes')

		let data = {
			noCache: true,
			key: apikey,
			websiteId: websiteId,
			storeId: storeId
		}


		return new Promise((resolve) => {

			// Resolve cached codes if found in cache
			if(cachedStatusCodes) {
				resolve(cachedStatusCodes)
			}

			// Get codes from server
			else {
				this._http.post(server + '/feed/get/status-codes', data).subscribe((resp: any) => {

					// Success
					if(!!resp.status && resp.status === 'success') {
						this._cache.set('status-codes', resp.data.list)
						resolve(resp.data.list)
					}

					// Data error
					else if(!!resp.status && resp.status === 'error') {
						console.error('could not get status codes', resp.data.errorMessage)
						throw(resp.data.errorMessage)
					}

					// Server error
					else {
						console.error('could not get status codes', resp)
						throw(resp)
					}
				})
			}
		})
	}


	/**
	 * Get status code for current quote 
	 * 
	 * @param quote_id 
	 */
	private _getCurrentStatus(quote_id: string) {
		let data = {
			quote_id: quote_id,
			noCache: true,
			key: apikey,
			websiteId: websiteId,
			storeId: storeId
		}

		return this._http.post(server + '/feed/get/status-code', data).pipe(
			tap((resp: any)=> {

				// Show errors if any
				if(resp.status === 'error') {
					console.error('could not get status code: ', quote_id, resp.data.errorMessage)
				}
				else if(!resp.status || resp.satus !== 'success') {
					console.error('could not get status code: ', quote_id, resp)
				}
			})
		)
	}
}