﻿import { Injectable } from '@angular/core';
import { Http, Headers, Response, RequestOptions } from "@angular/http";
import 'rxjs/Rx';
import { Observable } from "rxjs";
import { TfabricaCrudReport } from './tfabrica.crud.report.model';
import { TfabricaSharedService } from '../main/tfabrica.shared.service';
import { TfabricaCrudFilter } from './tfabrica.crud.filter.model';

@Injectable()
export class TfabricaCrudService {

    constructor(
        private _http: Http,
        private _shared: TfabricaSharedService
    ) { }

    public initFromReport(report: TfabricaCrudReport) {
        this.setFields(report.fields);
        this.setFieldsToDisplay(report.fieldsToDisplay);
        this.setFilters(report.filters);
        console.log(report.filters);
    }

    public readData(report: TfabricaCrudReport): Observable<TfabricaCrudReport> {

        let that = this;
        let urlToCall = this._shared.appSettings.getCommonApiValue("/api/Report/ReadData");
        console.log("Start call service: " + urlToCall);

        report.filters.forEach(function (filter) {
            if (filter.conversionFunction != null && filter.conversionFunction != undefined
                && filter.conversionFunction != "") {
                if (filter.conversionFunction == "fromDateToSapDate") {
                    that.conversionFromDateToSapDate(filter);
                }
            }
        });

        let bodyString = JSON.stringify(report);
        let headers = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
        let options = new RequestOptions({ headers: headers }); // Create a request option

        return this._http.post(urlToCall, bodyString, options) // ...using post request
            .map((res) => this.extractReadData(res)) // ...and calling .json() on the response to return data
            .catch((err) => this.handleError(err)); //...errors if any
    }

    private conversionFromDateToSapDate(filter: TfabricaCrudFilter) {
        if (filter.valueLow != "" && filter.valueLow != undefined) {
            filter.valueLow = this.fromDateToSapDate(filter.valueLow);
        }
        if (filter.valueHigh != "" && filter.valueHigh != undefined) {
            filter.valueHigh = this.fromDateToSapDate(filter.valueHigh);
        }
    }

    private fromDateToSapDate(actDateS: string) {
        let actDate = new Date(actDateS);
        let ddn = actDate.getDate();
        let dd = "";
        if (ddn < 10) dd = "0" + ddn.toString();
        else dd = ddn.toString();

        let mm = "";
        let mmn = actDate.getMonth() + 1; //January is 0!
        if (mmn < 10) mm = "0" + mmn.toString();
        else mm = mmn.toString();

        var yyyy = actDate.getFullYear();

        return yyyy.toString() + mm.toString() + dd.toString() ;
    }

    private fromYYYYMMDDtoDDMMYYYYWithScore(actDateS: string) {
        let correctData = actDateS.split("T");
        console.log("correctData: " + correctData);
        let actData = correctData[0].split("-");
        let yyyy = actData[0];
        let mm = actData[1];
        let dd = actData[2];
        return dd + "-" + mm + "-" + yyyy;
    }
    
    private fromSapDateToDate(actDateS: string) {
        let yyyy = actDateS.substring(0, 4);
        let mm = actDateS.substring(4, 6);
        let dd = actDateS.substring(6, 8);
        return new Date(yyyy + "-" + mm + "-" + dd);
    }

    private fromSapDateToDateString(actDateS: string) {
        let yyyy = actDateS.substring(0, 4);
        let mm = actDateS.substring(4, 6);
        let dd = actDateS.substring(6, 8);
        //return dd + "-" + mm + "-" + yyyy;
        return yyyy + "-" + mm + "-" + dd;
    }

    private extractReadData(res: Response) {
        console.log(res);
        if (res.status < 200 || res.status >= 300) {
            throw new Error('Bad response status: ' + res.status);
        }
        let that = this;
        let reportData = new TfabricaCrudReport();
        reportData.setFromJson(res.json().report);

        // apply conversion on Output
        
        reportData.readedRows.forEach(function (row) {
            reportData.fields.forEach(function (field) {
                if (field.conversionFunction != undefined && field.conversionFunction != "") {
                    if (field.conversionFunction == "fromDateToSapDate") {
                        row[field.name] = that.fromSapDateToDateString(row[field.name]);
                        //console.log(row[field.name]);
                    }
                    if (field.conversionFunction == "YYYY-MM-DD to DD-MM-YYYY") {
                        row[field.name] = that.fromYYYYMMDDtoDDMMYYYYWithScore(row[field.name]);
                        console.log(row[field.name]);
                    }
                }
            });
        });
        
        return reportData;
    }

    private handleError(error: any) {
        console.error(error); // log to console instead
        let errMsg = error.message || 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
    }


    public updateData(report: TfabricaCrudReport, rowData, operation: string): Observable<TfabricaCrudReport> {
        let urlToCall = "";
        let that = this;

        console.log(report.fields);
        report.fields.forEach(function (field) {
            if (field.conversionFunction != null && field.conversionFunction != undefined
                && field.conversionFunction != "") {

                console.log("conversionFunction: " + field.conversionFunction);

                if (field.conversionFunction == "fromDateToSapDate") {
                    rowData[field.name] = that.fromDateToSapDate(rowData[field.name]);
                    console.log(rowData[field.name]);
                }

                if (field.conversionFunction == "YYYY-MM-DD to DD-MM-YYYY") {
                    rowData[field.name] = that.fromYYYYMMDDtoDDMMYYYYWithScore(rowData[field.name]);
                    console.log(rowData[field.name]);
                }
            }
        });
        report.updateRow = rowData;
        
        urlToCall = this._shared.appSettings.basePath + "/api/Report/InsertData";
        if (operation == "U") {
            urlToCall = this._shared.appSettings.basePath + "/api/Report/UpdateData";
        }
        console.log("Start call service: " + urlToCall);

        let bodyString = JSON.stringify(report);
        let headers = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
        let options = new RequestOptions({ headers: headers }); // Create a request option

        return this._http.post(urlToCall, bodyString, options) // ...using post request
            .map((res) => this.extractUpdateData(res)) // ...and calling .json() on the response to return data
            .catch((err) => this.handleError(err)); //...errors if any
    }

    private extractUpdateData(res: Response) {
        console.log(res);
        if (res.status < 200 || res.status >= 300) {
            throw new Error('Bad response status: ' + res.status);
        }
        let reportData = new TfabricaCrudReport();
        reportData.setFromJson(res.json().report);
        return reportData;
    }



    private setFieldsToDisplay(fields) {
        localStorage.setItem('fieldsToDisplay', JSON.stringify(fields));
    }

    public getFieldsToDisplay() {
        return JSON.parse(localStorage.getItem('fieldsToDisplay'));
    }

    public setFields(fields) {
        localStorage.setItem('fields', JSON.stringify(fields));
    }

    public getFields() {
        return JSON.parse(localStorage.getItem('fields'));
    }

    public setFilters(filters) {
        localStorage.setItem('filters', JSON.stringify(filters));
    }

    public getFilters() {
        return JSON.parse(localStorage.getItem('filters'));
    }

    public setSelectedRow(row) {
        localStorage.setItem('crud-row', JSON.stringify(row));
    }

    public getSelectedRow() {
        return JSON.parse(localStorage.getItem('crud-row'));
    }

    public setReport(report) {
        localStorage.setItem('crud-report', JSON.stringify(report));
    }

    public getReport() {
        return JSON.parse(localStorage.getItem('crud-report'));
    }

    public setOperation(operation) {
        localStorage.setItem('crud-operation', JSON.stringify(operation));
    }

    public getOperation() {
        return JSON.parse(localStorage.getItem('crud-operation'));
    }


}