import { Injectable } from '@angular/core'
import { Observable, BehaviorSubject, of as observableOf } from 'rxjs'
import { map } from 'rxjs/operators'

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


// const tagsPluginQuery = gql`
// query tagsPlugins {
//     tagsPlugins {
//         stores {
//             store
//             tagActions {
//                 domain
//                 key
//                 actions {
//                     name
//                     plugin
//                     link
//                     roles
//                     action
//                 }
//             }
//         }
//     }
// }
// `

// const tagsPluginSubmitMutation = gql`
// mutation submitTagsPlugin(
//     $stores: [String],
//     $ids: [[String]],
//     $values: [String]!,
//     $keys: [String]!,
// ) {
//     submitTagsPlugin(
//         stores: $stores,
//         ids: $ids,
//         values: $values,
//         keys: $keys
//     ) {
//         tags {
//             key
//             value
//         }
//     }
// }
// `
// const doTagActionMutation=gql`
// mutation doTagAction (
//     $store: String!,
//     $id: String!,
//     $plugin: String!,
//   	$action: String!,
//   	$value: String!,
// ) {
//     doTagAction(
//         store: $store,
//         id: $id,
//         plugin: $plugin,
//         action: $action,
//         value: $value,
//     ) {
//         result
//     }
// }
// `

export type Tag = {
    key: string
    value: string
}

export class TagAction {
    constructor(
        public name: string,
        public plugin: string,
        public action: string,
        public roles: string[],
        public link: string,
    ) {}
}

export class TagActions {
    constructor(
        public domain: string,
        public key: string,
        public actions: TagAction[],
    ) {}

    get fullKey() {
        return (this.domain == '') ? this.key : this.domain + ':' + this.key
    }
}

export class Store {
    constructor(
        public store: string,
        public tagActions: TagActions[],
    ) {}
}

export class Stores {
    constructor(
        public stores: Store[],
    ) {}

    getByNames(stores: string[]): Store[] {
        return this.stores.filter(store => stores.find(s => store.store == s))
    }
}

@Injectable()
export class TagsPluginsService {
    protected _tagsPlugins: Object = {}
    protected _stores: Stores

    constructor(
        // private apollo: Apollo
    ) {
        // FIXME: the stores are available only after the instantiation of the TagsPluginsService
        /*
        this.getTagsPlugins().subscribe(
            tagsPluginsStores => {
                this.stores = tagsPluginsStores
            }
        )
        */
    }

    getTagsPlugins(): Observable<Stores> {
        console.warn('Migrate Graphql')
        return observableOf()
        // if (this._stores === undefined) {
        //     return this.apollo.query({
        //         query: tagsPluginQuery,
        //     }).pipe(map(
        //         res => {
        //             const stores = new Stores(
        //                 res['data']['tagsPlugins']['stores'].map(
        //                     (store: Object) => new Store(
        //                         store['store'],
        //                         store['tagActions'].map(
        //                             (tagKey: Object) => new TagActions(
        //                                 tagKey['domain'],
        //                                 tagKey['key'],
        //                                 tagKey['actions'].map(
        //                                     (tagAction: Object) => new TagAction(
        //                                         tagAction['name'],
        //                                         tagAction['plugin'],
        //                                         tagAction['action'],
        //                                         tagAction['roles'],
        //                                         tagAction['link'],
        //                                     )
        //                                 )
        //                             )
        //                         )
        //                     )
        //                 )
        //             )
        //             this._stores = stores
        //             return stores
        //         }
        //     ))
        // }
        // else {
        //     return observableOf(this._stores)
        // }
    }

    submit(features, keys: string[], values: string[]): Observable<Tag[]> {
        console.warn('Migrate Graphql')
        return observableOf()
        // let variables = {
        //     stores: Object.keys(features),
        //     ids: Object.values(features).map(ids => Array.from(<Number[][]>ids)),
        //     keys: keys,
        //     values: values,
        // }
        // return this.apollo.mutate({
        //     mutation: tagsPluginSubmitMutation,
        //     variables: variables,
        // }).pipe(map(
        //     res => res['data']['submitTagsPlugin']['tags'].map(
        //         (tag: Object) => new Tag(tag['key'], tag['value'])
        //     )
        // ))
    }

    doAction(store: string, id: string, action: TagAction, value: string): Observable<string> {
        let variables = {
            "store": store,
            "id": id,
            "plugin": action.plugin,
            "action": action.action,
            "value": value,
        }
        console.warn('Migrate Graphql')
        return observableOf()
        // return this.apollo.mutate({
        //     mutation: doTagActionMutation,
        //     variables: variables
        // }).pipe(map(
        //     res => res['data']['doTagAction']['result']
        // ))
    }
}