import { Injectable } from '@angular/core'

import { Observable, pipe, BehaviorSubject, of as observableOf } from 'rxjs'
import { map } from 'rxjs/operators'

// import { Apollo, gql } from 'apollo-angular'

import { ApiService, ActionsStore, ActionsResults,
         FormFieldInput, TaggedLayer } from '../openapi'

export class ActionParam {
    constructor(
        public name: string,
        public type: string,
        public dflt: string,
    ) {}
}

export class Action {
    constructor(
        public name: string,
        public roles: string[],
        public params: ActionParam[],
    ) {}
}

export class ActionResult {
    constructor(
        public name: string,
        public message: string,
        public taggedLayers: TaggedLayer[],
    ) {}
}

// export class ActionResults {
//     constructor(
//         public name: string,
//         public message: string,
//         public actionResults: ActionResult[],
//     ) {}
// }

export class ActionAction {
    constructor(
        public plugin: string,
        public name: string,
    ) {}
}


export class Store {
    constructor(
        public store: string,
        public actions: ActionAction[],
    ) {}
}


// const getTagsActionsQuery = gql`
// query actionsPlugins {
//     actionsPlugins {
//         store
//         actions {
//             name
//             roles
//             params {
//                 name
//                 type
//                 dflt
//             }
//         }
//     }
// }
// `

// const executeTagsActionsQuery = gql`
// mutation executeAction(
//     $stores: [String]!,
//     $ids: [[String]]!,
//     $names: [String]!,
//     $params: [ActionParamInput],
//     $formFields: [FormFieldInput]
// ) {
//     executeAction(
//         stores: $stores,
//         ids: $ids,
//         names: $names,
//         params: $params,
//         formFields: $formFields,
//     ) {
//         result {
//             message
//             actionResults {
//                 name
//                 message
//                 actionResults {
//                     message
//                     taggedLayers {
//                         store
//                         taggedFeatures {
//                             id
//                             lon
//                             lat
//                             tags {
//                                 key
//                                 value
//                             }
//                         }
//                     }
//                 }
//             }
//         }
//     }
// }
// `


@Injectable()
export class ActionsService {
    actionsStores: ActionsStore[] = []

    public actionsProviderService = new BehaviorSubject<ActionsStore[]>([])
    public actionsProviderService$ = this.actionsProviderService.asObservable()

    constructor(
        private apiService: ApiService,
    ) {
        this.getTagsActionsStores().subscribe(
            actionsStores => {
                this.actionsStores = actionsStores
            }
        )
    }

    public getTagsActionsStores(): Observable<ActionsStore[]> {
        return this.apiService.getActionsApiActionsGet()
        // return this.apollo.query({
        //     query: getTagsActionsQuery,
        // }).pipe(map(
        //     res => {
        //         let actionStores = res['data']['actionsPlugins'].map(pipe(
        //             store => new Store(
        //                 store['store'],
        //                 store['actions'].map(
        //                     action => new Action(
        //                         action['name'],
        //                         action['roles'],
        //                         action['params'].map(
        //                             param => new ActionParam(
        //                                 param['name'],
        //                                 param['type'],
        //                                 param['dflt']
        //                             )
        //                         )
        //                     )
        //                 )
        //             )
        //         ))
        //         this.actionsProviderService.next(actionStores)
        //         return actionStores
        //     }
        // ))
    }

    public execute(
        stores: string[],
        ids: string[][],
        actionNames: string[],
        params: ActionParam[],
        formFields?: FormFieldInput[]
    ): Observable<ActionsResults> {
        return this.apiService.executeTagActionApiExecTagActionsPost({
            "requestBody": {
                "stores": stores,
                "ids": ids,
                "actionNames": actionNames,
                "params": params,
                "formFields": formFields
            }
        })
    }
}
