import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { TransferState, makeStateKey } from '@angular/platform-browser'

import 'rxjs/add/operator/toPromise'

import { HelperService }        from '../../../services/svc.helper'
import { SharedService }        from '../../../services/svc.shared'
import { CacheService }         from '../../../services/general/svc.cache'

let KEY = makeStateKey('customProductsConfigs')

@Injectable()
export class CustomProductService {



    constructor(
        private _helper: HelperService,
        private _cache: CacheService,
        private _http: HttpClient,
        private _state: TransferState
    ) {}

    private key = this._helper.credentials;
    private api = this._helper.server+'feed/get';
    private productApi = this.api + '/miscProducts' + this.key;

    cacheId = 'configProduct'

    /**
     * Gets Custom Products configurations, uses `CacheService` to keep the data included
     * also uses `TransferState` to load the data on initial load.
     * Returns an error for `HelperService` if the request fails for any reason
     * 
     * @requires CacheService
     * @requires HelperService
     * @requires TransferState
     * @requires HttpClient
     * @requires getStateKey
     */
    getProductSelections() {
    
        // Set state data in a variable so it is accessible
        let value = this._state.get(KEY, null as any)

        if(this._cache.has(this.cacheId)) {

            // Spawn a promise so code thinks its receveing one. then returns data from cache
            return new Promise(resolve => {

                resolve(this._cache.get(this.cacheId))

            }).then((response) => {

                // Clears the key, so cache is utilized for future requests
                if(this._state.hasKey(KEY))
                
                    this._state.remove(KEY)

                return response
            })

        } else {

            if(!value) {

                // If all caches fail, refer to pulling data from the server
                return this._http.get(this.productApi).toPromise().then((response: any) => {
    
                    if(response.status !== 'success' || response.status == 500) throw response

                    else {
    
                        // Set the cache
                        this._cache.set(this.cacheId, response.data)

                        // Set the state
                        this._state.set(KEY, response.data)

                        // Return the data
                        return response.data
                    }
    
                }).catch((err) => {
    
                    if(err.status == 500)
                        this._helper.logRequestError(err.statusText, 'GET', this.productApi, '/app-core/modules/custom-product/services/svc.custom-product.ts')
                    else
                        this._helper.logRequestError(err.data.errorMessage, 'GET', this.productApi, '/app-core/modules/custom-product/services/svc.custom-product.ts')
    
                })

            } else {

                // Spawn a promise so code thinks its receveing one, then returns data from state
                return new Promise(resolve => {

                    resolve(value)

                }).then((response) => {

                    this._cache.set(this.cacheId, response)
                    return response
                })
            }
        }
    }

    getDiscountHash(object) {

        object.key = this._helper.apiKey
        object.storeId = this._helper.storeId
        object.websiteId = this._helper.websiteId
        object.noCache = true

        return this._http.post(this._helper.server + '/feed/get/discount-hash', object).toPromise().then((response) => {
            return response
        })
    }
}