import { Component, OnInit, Input, ViewChild, ViewChildren, AfterViewInit,
    ChangeDetectionStrategy, ChangeDetectorRef, QueryList } from '@angular/core'
import { ActivatedRoute, Router, ParamMap } from '@angular/router'

import { MatButtonToggleGroup } from '@angular/material/button-toggle'
import { MatTabGroup, MatTabChangeEvent } from '@angular/material/tabs'

import { DataService } from '../_services/data.service'
import { ModelDataService } from '../_services/apollo.service'

import { MapControlService } from '../map/map-control.service'

import { InfoPlotComponent } from './info-plot/plot.component'
import { ToolsComponent } from './info-tools/tools.component'
import { GraphComponent } from './info-graph/graph.component'
import { InfoAdminComponent } from './info-admin/info-admin.component'
import { FullInfo, InfoDataService, Feature } from './info-data.service'

@Component({
    selector: 'gisaf-info',
    templateUrl: './info.component.html',
    styleUrls: ['./info.component.css'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class InfoComponent implements OnInit /*, AfterViewInit */ {
    @Input() id: string
    @Input() store: string
    @Input() inMap: boolean = false

    canBeHidden: boolean = true
    hasFeature: boolean = true
    hasSelection: boolean = false
    featureClicked: Feature = undefined

    attachment: object = {}
    image: object = {}
    view = [800, 300]
    hideAdmin: boolean = true
    tags: object  = {}
    show: boolean = false

    fullInfo: FullInfo

    @ViewChild(MatButtonToggleGroup, { static: true }) modeSelector: MatButtonToggleGroup
    @ViewChild(InfoPlotComponent, { static: true }) plot: InfoPlotComponent
    @ViewChild(ToolsComponent, { static: true }) tools: ToolsComponent
    @ViewChild(GraphComponent, { static: true }) graph: GraphComponent
    @ViewChild(InfoAdminComponent, { static: true }) admin: InfoAdminComponent
    @ViewChild(MatTabGroup) tabs!: MatTabGroup
    @ViewChildren(InfoComponent) childrenComponent: QueryList<InfoComponent>

    constructor(
        protected dataService: DataService,
        protected modelDataService: ModelDataService,
        protected mapControlService: MapControlService,
        protected route: ActivatedRoute,
        protected router: Router,
        protected infoDataService: InfoDataService,
        private cdr: ChangeDetectorRef,
    ) {}

    ngOnInit() {
        // The component can be used with mapControlService...
        this.mapControlService.featureClicked$.subscribe(
            feature => {
                this.featureClicked = feature
                this.updateShow()
                this.setFeature(this.featureClicked)
            }
        )

        // ... or, the component can be used with a router (with children)
        this.route.parent.paramMap.subscribe(
            (params: ParamMap) => this.store = params.get('store')
        )

        this.route.paramMap.subscribe(
            (params: ParamMap) => {
                if (params.has('id')) {
                    this.id = params.get('id')
                    this.featureClicked = new Feature(this.store, this.id)
                    this.updateShow()
                    this.setFeature(this.featureClicked)
                }
            }
        )

        this.mapControlService.selection$.subscribe(
            selection => {
                this.hasSelection = Object.entries(selection).length != 0
                this.updateShow()
                this.cdr.markForCheck()
            }
        )

        this.mapControlService.toggleInfo$.subscribe(
            flag => {
                if (this.canBeHidden) {
                    if (this.hasFeature == flag) {
                        this.hasFeature = !flag
                    }
                }
            }
        )

        this.infoDataService.refresh$.subscribe(
            _ => {
                this.setFeature(this.featureClicked)
            }
        )
    }

    /*
    selectDefaultTab() {
        if (this.fullInfo.modelInfo.values.length > 0) {
            this.tabs.selectedIndex = 2
        }
        else {
            if (!!this.fullInfo.featureInfo.graph) {
                this.tabs.selectedIndex = 4
            }
            else {
                this.tabs.selectedIndex = 0
            }
        }
    }
    */

    /*
    ngAfterViewInit() {
        this.childrenComponent.changes.subscribe(
            (comps: QueryList<InfoComponent>) => this.selectDefaultTab()
        )
    }
    */

    setFeature(feature: Feature) {
        if (feature) {
            this.infoDataService.getFullInfo(feature).subscribe(
                fullInfo => {
                    this.fullInfo = fullInfo
                    /*
                    if (this.tabs) {
                        this.selectDefaultTab()
                    }
                    */
                    this.store = fullInfo.modelInfo.store
                    // Emit the data for measures, etc
                    this.infoDataService.dataProviderService.next(fullInfo)
                    this.cdr.markForCheck()
                }
            )
        }
        else {
            this.fullInfo = undefined
            this.cdr.markForCheck()
        }
    }

    close() {
        this.featureClicked = undefined
        this.updateShow()
        this.setFeature(undefined)
    }

    closeSelection() {
        this.mapControlService.selection.next([])
    }

    get icon(): string {
        return this.store.replace('.', '-')
    }

    get title(): string {
        return this.store + ': ' + (this.fullInfo.featureInfo.itemName || this.id)
    }

    updateShow(){
        let _newShow = !!this.featureClicked || this.hasSelection
        if (_newShow != this.show) {
            setTimeout(
                () => this.mapControlService.resize(),
                0
            )
            this.show = _newShow
        }
    }

    get link(): string {
        // Return a URL that can be copied/paste, to the Gisaf instance which will zoom to and select the feature
        return window.location.origin + '/map?show=' + this.fullInfo.modelInfo.store + ':id:' + this.fullInfo.featureInfo.id
    }

    onTabChange(evt: MatTabChangeEvent) {
        // Workaround for plotly to resize to its div
        window.dispatchEvent(new Event('resize'))
    }

    goToAdmin(store, id) {
        this.router.navigate(['/admin', store, id])
    }
}
