import { Injectable } from "@angular/core"
import { NgLifeCycleEvents, TupleSelector } from "@synerty/vortexjs"
import {
    DocumentResultI,
    PrivateDocumentLoaderService
} from "./_private/document-loader"
import { DocumentTuple } from "./DocumentTuple"
import { DocDbTupleService } from "./_private"
import { DocDbPropertyTuple } from "./DocDbPropertyTuple"

export interface DocPropT {
    title: string;
    value: string;
    order: number;
    showInHeader: boolean;
}

export interface DocDbPropertyTypeFilterI {
    (propType: DocDbPropertyTuple): boolean;
}

// ----------------------------------------------------------------------------
/** LocationIndex Cache
 *
 * This class has the following responsibilities:
 *
 * 1) Maintain a local storage of the index
 *
 * 2) Return DispKey locations based on the index.
 *
 */
@Injectable()
export class DocDbService extends NgLifeCycleEvents {
    
    propertiesByName: { [key: string]: DocDbPropertyTuple; } = {}
    
    constructor(
        private documentLoader: PrivateDocumentLoaderService,
        private tupleService: DocDbTupleService
    ) {
        super()
        
        let propTs = new TupleSelector(DocDbPropertyTuple.tupleName, {})
        this.tupleService.offlineObserver
            .subscribeToTupleSelector(propTs)
            .takeUntil(this.onDestroyEvent)
            .subscribe((tuples: DocDbPropertyTuple[]) => {
                this.propertiesByName = {}
                
                for (let item of tuples) {
                    let propKey = this._makePropKey(item.modelSetId, item.name)
                    this.propertiesByName[propKey] = item
                }
            })
    }
    
    /** Get Locations
     *
     * Get the objects with matching keywords from the index..
     *
     */
    getObjects(
        modelSetKey: string,
        keys: string[]
    ): Promise<DocumentResultI> {
        return this.documentLoader.getDocuments(modelSetKey, keys)
    }
    
    getNiceOrderedProperties(
        doc: DocumentTuple,
        filter: DocDbPropertyTypeFilterI | null = null
    ): DocPropT[] {
        let props: DocPropT[] = []
        
        for (let name of Object.keys(doc.document)) {
            let propKey = this._makePropKey(doc.modelSet.id, name)
            let prop = this.propertiesByName[propKey] || new DocDbPropertyTuple()
            if (filter != null && !filter(prop))
                continue
            props.push({
                title: prop.title,
                value: doc.document[name],
                order: prop.order,
                showInHeader: prop.showInHeader
            })
        }
        props.sort((
            a,
            b
        ) => a.order - b.order)
        
        return props
    }
    
    private _makePropKey(
        modelSetId: number,
        name: string
    ): string {
        return `${modelSetId}.${name.toLowerCase()}`
    }
    
}
