import { Component, OnInit, Inject } from '@angular/core';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UntypedFormGroup, UntypedFormControl, UntypedFormArray } from '@angular/forms';
import { ToastrService } from 'ngx-toastr';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { trigger } from '@angular/animations';
import { fadeIn, simpleFade } from 'src/app/shared/animations/animations';
import { ProductSpecification, ProductSpecificationCharacteristicRes, ProductSpecificationCharacteristicValue, ProductSpecificationUpdate } from 'src/app/openApis/productCatalogManagement/models';
import { ProductSpecificationService } from 'src/app/openApis/productCatalogManagement/services';



@Component({
    selector: 'app-edit-product-spec-characteristics',
    templateUrl: './edit-product-spec-characteristics.component.html',
    styleUrls: ['./edit-product-spec-characteristics.component.scss'],
    animations: [trigger('fadeIn', fadeIn()), trigger('simpleFade', simpleFade())]
})
export class EditProductSpecCharacteristicsComponent implements OnInit {

    constructor(
        @Inject(MAT_DIALOG_DATA) public data: {
            productSpec: ProductSpecification,
            specToBeUpdated: ProductSpecificationCharacteristicRes,
        },
        private dialogRef: MatDialogRef<EditProductSpecCharacteristicsComponent>,
        private specService: ProductSpecificationService,
        private toast: ToastrService
    ) { }

    editFormCharacteristic = new UntypedFormGroup({
        name: new UntypedFormControl(),
        description: new UntypedFormControl(),
        configurable: new UntypedFormControl(),
        extensible: new UntypedFormControl(),
        maxCardinality: new UntypedFormControl(1),
        minCardinality: new UntypedFormControl(0),
        validFor: new UntypedFormGroup({
            endDateTime: new UntypedFormControl(new Date(new Date().setFullYear(new Date().getFullYear() + 20))),
            startDateTime: new UntypedFormControl(new Date())
        }),
        valueType: new UntypedFormControl(),
        productSpecCharacteristicValue: new UntypedFormArray([])
    })

    subValueTypeCtrl = new UntypedFormControl('INTEGER')

    valueTypes = ['INTEGER', 'SMALLINT', 'LONGINT', 'FLOAT', 'BINARY', 'BOOLEAN', 'ARRAY', 'SET', 'TEXT', 'LONGTEXT', 'ENUM', 'TIMESTAMP']
    subValueTypes = ['INTEGER', 'SMALLINT', 'LONGINT', 'FLOAT', 'BINARY', 'BOOLEAN', 'TEXT', 'LONGTEXT', 'TIMESTAMP']

    // valueSubType = new FormControl()
    subTypeSelection: boolean = false

    newSpec: boolean = false

    compDestroy$ = new Subject()

    isCharValueBlockExpanded: boolean[] = []

    ngOnInit(): void {
        if (this.data.specToBeUpdated) {
            if (!this.data.specToBeUpdated.validFor) this.data.specToBeUpdated.validFor = { endDateTime: null, startDateTime: null }
            this.editFormCharacteristic.patchValue(this.data.specToBeUpdated)

            const formArray = this.editFormCharacteristic.get('productSpecCharacteristicValue') as UntypedFormArray
            this.data.specToBeUpdated.productSpecCharacteristicValue.forEach(val => {
                formArray.push(this.updateFormArrayItem(val))
                this.isCharValueBlockExpanded.push(false)
            })

            this.subValueTypeCtrl.patchValue(this.data.specToBeUpdated.productSpecCharacteristicValue[0].valueType)
            if (['SET', 'ARRAY', 'ENUM'].includes(this.data.specToBeUpdated.valueType)) {
                this.subTypeSelection = true
            }
        }

        else { this.newSpec = true }

        this.editFormCharacteristic.get('valueType').valueChanges.pipe(
            takeUntil(this.compDestroy$)
        )
            .subscribe(
                val => {
                    this.editFormCharacteristic.setControl('productSpecCharacteristicValue', new UntypedFormArray([]))
                    this.createFormArrayItem()


                    if (['SET', 'ARRAY', 'ENUM'].includes(val)) {
                        this.subTypeSelection = true
                        this.subValueTypeCtrl.valueChanges.pipe(
                            takeUntil(this.compDestroy$)
                        )
                            .subscribe(
                                subVal => {
                                    this.editFormCharacteristic.setControl('productSpecCharacteristicValue', new UntypedFormArray([]))
                                    this.createFormArrayItem()
                                }
                            )
                    } else {
                        this.subTypeSelection = false
                    }
                    // const formArray = this.editFormCharacteristic.get('serviceSpecCharacteristicValue') as FormArray
                    // if (val !== 'ARRAY' && val !=='ENUM' && val !=='SET') {       
                    //   this.subTypeSelection = false   
                    //   formArray.setControl(0,       
                    //     new FormGroup({
                    //     value: new FormGroup({
                    //       alias: new FormControl(),
                    //       value: new FormControl(),
                    //     }),
                    //     unitOfMeasure: new FormControl(),
                    //     isDefault: new FormControl(),
                    //     valueType: new FormControl(this.editFormCharacteristic.get('valueType').value)
                    //   }))
                    // }
                }
            )
    }


    updateFormArrayItem(CharValue: ProductSpecificationCharacteristicValue): UntypedFormGroup {
        return new UntypedFormGroup({
            value: new UntypedFormGroup({
                alias: new UntypedFormControl(CharValue.value.alias),
                value: new UntypedFormControl(CharValue.value.value),
            }),
            unitOfMeasure: new UntypedFormControl(CharValue.unitOfMeasure),
            isDefault: new UntypedFormControl({ value: (CharValue.isDefault || this.data.specToBeUpdated.valueType === 'ARRAY'), disabled: this.data.specToBeUpdated.valueType === 'ARRAY' }),
            valueType: new UntypedFormControl(CharValue.valueType)
        })
    }


    createFormArrayItem() {
        const formArray = this.editFormCharacteristic.get('productSpecCharacteristicValue') as UntypedFormArray

        // let isDisabled: boolean = true
        let subType: string = this.editFormCharacteristic.get('valueType').value

        if (['SET', 'ARRAY', 'ENUM'].includes(this.editFormCharacteristic.get('valueType').value)) {
            // isDisabled = false
            subType = this.subValueTypeCtrl.value
        }

        formArray.push(
            new UntypedFormGroup({
                value: new UntypedFormGroup({
                    alias: new UntypedFormControl(),
                    value: new UntypedFormControl(),
                }),
                unitOfMeasure: new UntypedFormControl(),
                isDefault: new UntypedFormControl({ value: this.editFormCharacteristic.get('valueType').value === 'ARRAY', disabled: this.editFormCharacteristic.get('valueType').value === 'ARRAY' }),
                valueType: new UntypedFormControl(subType)
            })
        )
        this.isCharValueBlockExpanded.push(false)
    }

    deleteFormArrayItem(index) {
        const formArray = this.editFormCharacteristic.get('productSpecCharacteristicValue') as UntypedFormArray
        formArray.removeAt(index)
        this.isCharValueBlockExpanded.splice(index, 1)
    }

    expandCharValueBlock(index) {
        this.isCharValueBlockExpanded[index] = !this.isCharValueBlockExpanded[index]
    }

    isDefaultCheckboxChanged(index, event: MatCheckboxChange) {
        if (this.editFormCharacteristic.get('valueType').value === "ENUM" && event.checked) {
            const formArray = this.editFormCharacteristic.get('productSpecCharacteristicValue') as UntypedFormArray
            for (let i = 0; i < formArray.controls.length; i++) {
                if (i !== index) formArray.controls[i].get('isDefault').setValue(false)
            }
        }
    }


    closeDialog() {
        this.dialogRef.close()
    }

    submitDialog() {



        if (this.newSpec) {
            this.data.productSpec.productSpecCharacteristic.push(this.editFormCharacteristic.getRawValue())
        } else {
            const updateCharacteristIndex = this.data.productSpec.productSpecCharacteristic.findIndex(char => char.uuid === this.data.specToBeUpdated.uuid)
            this.data.productSpec.productSpecCharacteristic[updateCharacteristIndex] = this.editFormCharacteristic.getRawValue()
        }

        const updateCharacteristicObj: ProductSpecificationUpdate = {
            productSpecCharacteristic: this.data.productSpec.productSpecCharacteristic
        }

        this.specService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateCharacteristicObj }).subscribe(
            data => { },
            error => this.toast.error("An error occurred upon updating Spec Characteristics"),
            () => { this.dialogRef.close('updated') }
        )
    }

    ngOnDestroy(): void {
        this.compDestroy$.next("destroyed")
    }


}