import { Injectable } from '@angular/core';
import { Role, Application, Permission, AccessControl, ApplicationService } from '../../shared';
import { Headers, Http, Response } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { AppSettings } from 'app/core/app-settings';

/*Sample JSON to test UI and add new role*/
const sampleRoles: Role[] = [
    {
        code: "1",
        name: "Admin",
        isEditable: false,
        isDeletable: false,
        access: [
            { applicationCode: '1', permissionCode: '1', activate: true },
            { applicationCode: '1', permissionCode: '2', activate: true },
            { applicationCode: '1', permissionCode: '3', activate: true },
            { applicationCode: '1', permissionCode: '4', activate: true },
            { applicationCode: '1', permissionCode: '5', activate: true },
            { applicationCode: '2', permissionCode: '6', activate: true },
            { applicationCode: '2', permissionCode: '7', activate: true }
        ]
    },
    {
        code: "2",
        name: "Dispatcher",
        isEditable: true,
        isDeletable: false,
        access: [
            { applicationCode: '1', permissionCode: '1', activate: true },
            { applicationCode: '1', permissionCode: '2', activate: true },
            { applicationCode: '1', permissionCode: '3', activate: true },
            { applicationCode: '1', permissionCode: '4', activate: true },
            { applicationCode: '1', permissionCode: '5', activate: true },
            { applicationCode: '2', permissionCode: '6', activate: false },
            { applicationCode: '2', permissionCode: '7', activate: false }
        ]
    },
    {
        code: "3",
        name: "Driver",
        isEditable: true,
        isDeletable: false,
        access: [
            { applicationCode: '1', permissionCode: '1', activate: false },
            { applicationCode: '1', permissionCode: '2', activate: false },
            { applicationCode: '1', permissionCode: '3', activate: false },
            { applicationCode: '1', permissionCode: '4', activate: false },
            { applicationCode: '1', permissionCode: '5', activate: false },
            { applicationCode: '2', permissionCode: '6', activate: true },
            { applicationCode: '2', permissionCode: '7', activate: true }
        ]
    }
];

@Injectable()
export class RoleService {
    private role: any;
    private applicationService: any;

    constructor(private http: Http, private appSettings: AppSettings) {
        this.role = sampleRoles;
        this.applicationService = new ApplicationService(http, appSettings);
    }

    addRole(param: Role): Promise<any> {

        let accessForRole: AccessControl[];
        let newRole: Role;
        let code = "18";

        let url = this.getUri('query for getting next role Id');

        /* Get application info for creating a new roles */
        let allAppDetails: Application[];
        accessForRole = new Array();
        this.applicationService.getApplications().then(app => {
            allAppDetails = app;
            for (let appInfo of allAppDetails) {
                for (let permInfo of appInfo.permissions) {
                    accessForRole.push({ applicationCode: appInfo.code, permissionCode: permInfo.code, activate: false })
                }
            }
            newRole = new Role(code, param.name, true, true, accessForRole);
            /* POST this new role to db in service call*/
            sampleRoles.push(newRole); // stub
        });

        // This function will be modified to HTTP/Promise call for update Role table
        return new Promise((resolve, reject) => {
            resolve('Success');
        });

    }

    deleteRole(role: Role): Promise<any> {
        /* POST this role to be deleted in service call*/
        // stub
        if (this.role.indexOf(role) !== -1) {
            this.role.splice(this.role.indexOf(role), 1);
        }

        // This function will be modified to HTTP/Promise call for update Role table
        return new Promise((resolve, reject) => {
            resolve('Success');
        });
    }

    getRoles(): Promise<Array<Role>> {
        let url = this.getUri();
        return new Promise((resolve, reject) => {
            resolve(this.role);
        });
    }

    private getHeaders(obj?: any) {
        const headers = new Headers();
        headers.append('Content-Type', 'application/json');

        for (let h in obj || {}) {
            headers.append(h, obj[ h ]);
        }

        return headers;
    }

    private getUri(endpoint?: string): string {
        return this.appSettings.apiUrl + 'Role/' + endpoint;
    }

    private handleError(error: any): Promise<any> {
        console.error('An error occurred', error);
        return Promise.reject(error.message || error);
    }
}
