import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { Store } from '@ngrx/store';

import { AppState } from '../ecm-store/reducers';
import { ReviewAction } from '../ecm-store/actions';
import { Review } from './review-manager/review.model';
import { Reviews } from '../ecm-model/product-review.model';
import { HostUrlService } from '../host-url.service';

@Injectable()
export class UserReviewService {

//    private userActionUrl = '/ecm/service/feeds/L2D01/review';

    private userActionUrl = '/ecm/service/feeds';
    userReview: Review[];

    value;

    constructor( public hostUrlService : HostUrlService,private http: Http, private store: Store<AppState>, private reviewActions: ReviewAction ) { }

    loadUserReview() {
        this.fetchUserInfo().subscribe(
            data => {
                this.userReview = data;
                if ( data && data != null ) {
                    this.userReview.forEach( userReview => {
                        this.store.dispatch( this.reviewActions.updateReviews( userReview ) );
                    })
                }
            });
    }


    fetchUserInfo(): Observable<Review[]> {

        let headers = new Headers( { 'Content-Type': 'application/json' });
        let options = new RequestOptions( { headers: headers });
        let siteCode = localStorage.getItem('SITE_CODE'); 
        
        return this.http.get( this.userActionUrl + '/' + siteCode + '/review' , options )
            .map(( res ) => this.extractData( res ) );
    }

    updateUserInfo( userReview ) {
        console.log( "StoreInReview Called" );
        console.log( JSON.stringify( userReview ) );
        let headers = new Headers( { 'Content-Type': 'application/json' });
        let options = new RequestOptions( { headers: headers });
        let siteCode = localStorage.getItem('SITE_CODE'); 
        
        return this.http.post( '', JSON.stringify( userReview ), options )
            .map(( res ) => this.extractData( res ) );
    }

    deleteCartItem( userReview ) {
        console.log( "deleteUserreview Called" );
        let siteCode = localStorage.getItem('SITE_CODE'); 
        
        return this.http.delete( this.hostUrlService.hostUrl + this.userActionUrl + '/' + siteCode + '/review' + '/' + userReview.userCode, {})
            .map( res => res.json() );

    }

    getUserReview( itemCode ) {
        console.log( "URL: " + this.hostUrlService.hostUrl+this.userActionUrl );
        let siteCode = localStorage.getItem('SITE_CODE'); 
        
        let headers = new Headers( { 'Content-Type': 'application/json' });
        let options = new RequestOptions( { headers: headers });

        return this.http.get( this.hostUrlService.hostUrl+this.userActionUrl + '/' + siteCode + '/review' + '/' + itemCode, options )
            .map( this.extractData )
            .catch( this.handleError );
    }
    
    submitReview(reviewData){
        let headers = new Headers( { 'Content-Type': 'application/json' });
        let options = new RequestOptions( { headers: headers });
        let siteCode = localStorage.getItem('SITE_CODE'); 
        
        console.log("Submitting Review...");
        console.log(JSON.stringify(reviewData));
        
        this.http.post(this.hostUrlService.hostUrl+this.userActionUrl + '/' + siteCode + '/review' , reviewData, options)
        .subscribe(data => {
           console.log("Add Review");
        }, error => {
            console.log(error.json());
        }); 
    }
    
    removeReview(itemCode){
        let headers = new Headers( { 'Content-Type': 'application/json' });
        let options = new RequestOptions( { headers: headers });
        let siteCode = localStorage.getItem('SITE_CODE'); 
        
        console.log("Deleting Review for...",itemCode);
        
        this.http.delete(this.hostUrlService.hostUrl+this.userActionUrl + '/' + siteCode + '/review' + '/' +  itemCode, options)
        .subscribe(data => {
           console.log("Deleted Review");
        }, error => {
            console.log(error.json());
        });
    }

    get itemCode(): string { return this.value; }

    set itemCode( itemCode: string ) {
        console.log( 'set itemCode', itemCode );
        this.value = itemCode;
    }

    private extractData( res: Response ) {
        let respJson = res.json();
        console.log( 'extracData', respJson );
        if ( respJson != null ) {
            for ( let key of Object.keys( respJson ) ) {
                console.log( "getUserReview Review ==> key: " + key )
                let data = respJson[key];

                try {
                    respJson[key] = JSON.parse( data );
                    console.log( "getUserReview Review try : " + respJson[key] );
                }
                catch ( e ) {
                    console.log( "getUserReview Review ==> key: ", data, typeof data === 'object' )
                    if ( typeof data === 'object' )
                        respJson[key] = this.formatObject( data );
                    else
                        respJson[key] = data;
                    console.log( "getUserAddress Review catch : " + respJson[key] );
                }
            }
            console.log( 'extractData[' + JSON.stringify( respJson ) + ']' );
        }
        return respJson || {};
    }

    formatObject( respJson: any ) {

        console.log( 'formatObject', respJson );
        if ( respJson != null ) {
            for ( let key of Object.keys( respJson ) ) {
                console.log( "formatObject Review ==> key: " + key )
                let data = respJson[key];
                try {
                    respJson[key] = JSON.parse( data );
                    console.log( "formatObject Review try : " + respJson[key] );
                }
                catch ( e ) {
                    respJson[key] = data;
                    console.log( "formatObject Review catch : " + respJson[key] );
                }
            }
            console.log( 'formatObject[' + JSON.stringify( respJson ) + ']' );
        }
        return respJson || {};
    }

    private handleError( error: Response | any ) {
        // In a real world app, we might use a remote logging infrastructure
        let errMsg: string;
        if ( error instanceof Response ) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify( body );
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error( 'Service handleError:' + errMsg );
        return Observable.throw( errMsg );
    }

}
