import { Component, OnInit,
    ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core'

import { Subject, timer } from 'rxjs'
import { map } from 'rxjs/operators'
import { WebSocketSubject } from 'rxjs/webSocket'

import { SchedulerService, Job, JobEvent } from './scheduler.service'

@Component({
    selector: 'gisaf-admin-scheduler-jobs',
    templateUrl: './jobs.component.html',
    styleUrls: ['./jobs.component.css'],
    changeDetection: ChangeDetectionStrategy.OnPush,
    providers: [
        SchedulerService,
    ],
})
export class AdminSchedulerJobsComponent implements OnInit {
    error: string
    jobs: Object = {}  //Job[]
    status: string = 'connecting...'
    timeDelta: number  // Time delta between browser and scheduler (positive: )
    time: Date

    constructor(
        private cdr: ChangeDetectorRef,
        public schedulerService: SchedulerService,
    ) {}

    ngOnInit() {
        this.getJobs()
        this.getTime()
        // TODO: websocket status (below: plain websockets, but graphql-ws is different)
        //let onOpenSubject = new Subject()
        //let onCloseSubject = new Subject()
        //onOpenSubject.subscribe(
        //    res => {
        //        this.status = 'connected'
        //        this.cdr.markForCheck()
        //    }
        //)
        //onCloseSubject.subscribe(
        //    (res: CloseEvent) => {
        //        this.status = 'disconnected - reason: ' + res.reason || res.code.toString() || 'unknown'
        //        this.cdr.markForCheck()
        //    }
        //)
    }

    getTime() {
        // Get the time of the scheduler and set the running clock
        this.schedulerService.getTime().subscribe(
            serverTime => {
                // Approximate the network latency: rountrip time
                this.timeDelta = (serverTime.getTime() - new Date().getTime()) / 2 + 10
                // Just an approximate running clock for the user
                timer(1000, 1000).subscribe(
                    _ => {
                        this.time = new Date(new Date().getTime() - this.timeDelta)
                        this.cdr.markForCheck()
                    }
                )
            }
        )
    }

    getJobs() {
        this.schedulerService.getJobs().subscribe({
            next: jobs => {
                this.jobs = {}
                jobs.forEach((job: Job) => {
                    this.jobs[job.id] = job
                })
                this.getJobEvents()
                this.cdr.markForCheck()
            },
            // complete: () => {
            //     console.log('getJobs completed')
            // },
            error: err => {
                console.log(err)
                this.error = `Scheduler not reachable (not running?): ${err.statusText || err.message}`
                this.cdr.markForCheck()
            }
        })
    }

    getJobEvents() {
        this.schedulerService.getJobEvents().subscribe(
            jobEvent => {
                let job: Job = this.jobs[jobEvent.jobId]
                if (!job) {
                    console.log('Event for unknown job', jobEvent)
                    return
                }
                job.setLastEvent(jobEvent)
                // Force a change detection on jobs, to run the orderBy pipe
                this.jobs = { ...this.jobs }
                this.cdr.markForCheck()
            }
        )
    }
}
