import { Component, Inject, OnInit, ChangeDetectorRef, ViewChild } from '@angular/core'
import {
    FormBuilder, FormControl, FormGroup, Validators,
    AbstractControl, ValidationErrors, ValidatorFn
} from '@angular/forms'
import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper'

import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'
import { MatSelect } from '@angular/material/select'
import { Observable } from 'rxjs'
import { map, startWith } from 'rxjs/operators'

import { DOC_ORIENTATION } from 'ngx-image-compress'

import { DataService } from 'src/app/data.service'
import { ActionService } from 'src/app/action.service'
import { Plant, Trails } from 'src/app/models'

export interface DialogData {
    instruction: string,
    plantId: string,
    fileName: string,
    picture: string,
}

@Component({
    selector: 'plant-chooser-dialog',
    templateUrl: './plant-chooser-dialog.html',
    styleUrls: ['./plant-chooser-dialog.scss'],
    providers: [
        {
            provide: STEPPER_GLOBAL_OPTIONS,
            useValue: { showError: true },
        },
    ]
})
export class PlantChooserDialogComponent implements OnInit {
    form: FormGroup
    filteredOptions: Observable<Plant[]>
    trails: Trails
    file: File
    @ViewChild('select') private select: MatSelect

    constructor(
        public dialogRef: MatDialogRef<PlantChooserDialogComponent>,
        @Inject(MAT_DIALOG_DATA) public data: DialogData,
        public dataService: DataService,
        public actionService: ActionService,
        public cdr: ChangeDetectorRef,
        private fb: FormBuilder,
    ) {
    }

    ngOnInit() {
        const formPlant = this.fb.group({
            plantId: new FormControl('', [
                Validators.required,
                this.createPlantValidator()
            ]),
            trails: new FormControl([]),
        })
        const formPicture = this.fb.group({
            picture: new FormControl(''),
            file: new FormControl(),
        })
        const formDetails = this.fb.group({
            status: new FormControl(''),
            condition: new FormControl(''),
            comments: new FormControl(''),
            height: new FormControl(),
        })
        this.form = this.fb.group({
            plant: formPlant,
            picture: formPicture,
            details: formDetails,
        })
        this.filteredOptions = (<FormGroup>this.form.controls['plant']).controls['plantId'].valueChanges.pipe(
            startWith(''),
            map(value => this._filter(value || '')),
        )

        this.form.valueChanges.subscribe(() => {
            this.select.close();
        });
    }

    createPlantValidator(): ValidatorFn {
        return (control: AbstractControl): ValidationErrors | null => {
            const isPlantName = control.value in this.dataService.all.value.plants
            return !isPlantName ? { plantName: true } : null
        }
    }

    private _filter(value: string): Plant[] {
        const filterValue = value.toLowerCase()
        return Object.values(this.dataService.all.value.plants).filter(
            plant => plant.isMatch(filterValue)
        )
    }

    maxImgSize: number = 300000
    resizeFactor: number = 50

    onImageFileSelected(e: Event) {
        const reader = new FileReader()

        if ((<HTMLInputElement>e.target).files
            && (<FileList>(<HTMLInputElement>e.target).files).length) {
            const files = <FileList>(<HTMLInputElement>e.target).files
            this.file = files[0]
            reader.readAsDataURL(this.file)

            reader.onload = () => {
                const imgFile = <string>reader.result
                if (imgFile.length > this.maxImgSize) {
                    // Image too big => resize (arbitrary set to 50%)
                    this.actionService.imageCompressService.compressFile(
                        imgFile, DOC_ORIENTATION.Up, this.resizeFactor
                    ).then(
                        compressedImage => {
                            (<FormGroup>this.form.get('picture')).controls.picture.setValue(compressedImage)
                        }
                    )
                }
                else {
                    (<FormGroup>this.form.get('picture')).controls.picture.setValue(imgFile)
                }
            }
        }
    }
}