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 { Tag } from '../info/info-tags/tags.service'
import { TaggedLayer, TaggedFeature, FormFieldInput } from '../info/info-data.service'

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 ActionsStore {
    constructor(
        public store: string,
        public actions: Action[],
    ) {}
}

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 ActionsResults {
    constructor(
        public message: string,
        public actionResults: ActionResults[],
    ) {}
}

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 apollo: Apollo,
    ) {
        this.getTagsActionsStores().subscribe(
            actionsStores => {
                this.actionsStores = actionsStores
            }
        )
    }

    public getTagsActionsStores(): Observable<ActionsStore[]> {
        console.warn('Migrate Graphql')
        return observableOf()
        // 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> {
        console.warn('Migrate Graphql')
        return observableOf()
        // return this.apollo.mutate({
        //     mutation: executeTagsActionsQuery,
        //     variables: {
        //         stores: stores,
        //         ids: ids,
        //         names: actionNames,
        //         params: params,
        //         formFields: formFields
        //     }
        // }).pipe(map(
        //     result => result['data']['executeAction']['result'].map(
        //         res => new ActionsResults(
        //             res['message'],
        //             res['actionResults'].map(
        //                 r => new ActionResults(
        //                     r['name'],
        //                     r['message'],
        //                     r['actionResults'] && r['actionResults'].map(
        //                         actionResults => new ActionResult(
        //                             actionResults['name'],
        //                             actionResults['message'],
        //                             (actionResults['taggedLayers'] || []).map(
        //                                 taggedLayer => new TaggedLayer(
        //                                     taggedLayer['store'],
        //                                     taggedLayer['taggedFeatures'].map(
        //                                         taggedFeature => new TaggedFeature(
        //                                             taggedFeature['id'],
        //                                             taggedFeature['lon'],
        //                                             taggedFeature['lat'],
        //                                             taggedFeature['tags'].map(
        //                                                 tag => new Tag(
        //                                                     tag['key'],
        //                                                     tag['value']
        //                                                 )
        //                                             )
        //                                         )
        //                                     )
        //                                 )
        //                             )
        //                         )
        //                     )
        //                 )
        //             )
        //         )
        //     )
        // ))
    }
}
