import { Component, Inject, OnDestroy } from '@angular/core';
import { DatePipe, NgFor, NgIf } from '@angular/common';
import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatOptionModule } from '@angular/material/core';
import { MatSelectModule } from '@angular/material/select';
import { Subscription } from 'rxjs';

import { Jump, JumpAddParams } from 'src/app/core/models';

@Component({
    selector: 'huapp-jump-add-dialog',
    templateUrl: 'jump-add.dialog.html',
    standalone: true,
    imports: [
        DatePipe, NgFor, NgIf, FormsModule, ReactiveFormsModule,
        MatButtonModule, MatCheckboxModule, MatDatepickerModule,
        MatDialogModule, MatFormFieldModule, MatIconModule,
        MatInputModule, MatSelectModule, MatOptionModule
    ]
})
export class JumpAddDialogComponent implements OnDestroy {
    private _formChanges: Array<Subscription> = [];
    public tagField = new FormControl<string>('', { nonNullable: true});
    public jumpForm: FormGroup;
    public jump: Jump;
    public lastJump: Jump;
    public nextJump: number;
    public params: JumpAddParams;
    public filename: string;
    public filepath: string;
    public useLast: {
        all: boolean;
        aeronef: boolean;
        altitude: boolean;
        discipline: boolean;
        divers: boolean;
        dropzone: boolean;
        groupe: boolean;
        programme: boolean;
        voile: boolean;
    } = {
        all: false,
        aeronef: false,
        altitude: false,
        discipline: false,
        divers: false,
        dropzone: false,
        groupe: false,
        programme: false,
        voile: false
    };

    constructor(
        public dialogRef: MatDialogRef<JumpAddDialogComponent>,
        private fb: FormBuilder,
        @Inject(MAT_DIALOG_DATA) public data: {jump: Jump, lastJump: Jump}
    ) {
        this.jump = data.jump;
        this.lastJump = data.lastJump;
        this.nextJump = (this.lastJump.numero + 1);
        this.params = {
            numeros: this.nextJump.toString(),
            date: '',
            video: true
        };
        this.jump.numero = this.nextJump;
        let controlsConfig = {
            date: ['', Validators.required],
            numero: [this.nextJump, Validators.required],
            lieu: ['', Validators.required],
            oaci: '',
            aeronef: ['', Validators.required],
            imat: '',
            hauteur: ['', Validators.required],
            deploiement: '',
            voile: '',
            taille: ['', Validators.required],
            categorie: '',
            module: '',
            participants: [1, Validators.required],
            sautants: [[]],
            programme: '',
            accessoires: '',
            zone: '',
            dossier: '',
            video: ''
        };
        this.jumpForm = this.fb.group(controlsConfig);
        this.filename = this._computeFilename();
        this.filepath = this._computeFilepath();
        this._formChanges.push(
            this.jumpForm.controls['module'].valueChanges.subscribe(() => {
                this.filepath = this._computeFilepath();
            }),
            this.jumpForm.controls['numero'].valueChanges.subscribe(() => {
                this.filename = this._computeFilename();
            })
        );
    }

    ngOnDestroy() {
        this._formChanges.forEach((sub: Subscription) => {
            sub.unsubscribe();
        });
    }

    public onDateChange(): void {
        this.filename = this._computeFilename();
    }

    private _computeFilename(numero?: string): string {
        let file: string = '';
        let timestamp: number = Date.parse(this.jumpForm.controls['date'].value);
        if (isNaN(timestamp) == false) {
            let date: Date = new Date(timestamp);
            file += `${(date.getFullYear() + '').padStart(2, '0')}-${((date.getMonth() + 1) + '').padStart(2, '0')}-${(date.getDate() + '').padStart(2, '0')}_`;
        }
        if (numero !== undefined) {
            numero = (numero + '').padStart(5, '0');
        } else {
            numero = (this.jumpForm.controls['numero'].value + '').padStart(5, '0');
        }
        file += `S${numero}.mp4`;
        this.jumpForm.controls['video'].setValue(file);

        return file;
    }

    private _computeFilepath(): string {
        let path: string = '/Volumes/Storage/Skydive/Videos/';
        if (this.jumpForm.controls['module'].value != '') {
            path += `${this.jumpForm.controls['module'].value}/`;
        }
        this.jumpForm.controls['dossier'].setValue(path);

        return path;
    }

    private _isLastForAllSections() {
        return (
            this.useLast.aeronef
            && this.useLast.altitude
            && this.useLast.discipline
            && this.useLast.divers
            && this.useLast.dropzone
            && this.useLast.groupe
            && this.useLast.programme
            && this.useLast.voile
        );
    }

    private _setAllLast(checked: boolean) {
        this.useLast.all = checked;
        this.useLast.aeronef = checked;
        this.useLast.altitude = checked;
        this.useLast.discipline = checked;
        this.useLast.divers = checked;
        this.useLast.dropzone = checked;
        this.useLast.groupe = checked;
        this.useLast.programme = checked;
        this.useLast.voile = checked;
    }

    addSautant(): void {
        this.useLast.groupe = false;
        this.useLast.all = this._isLastForAllSections();
        const tag = this.tagField.value;
        if (tag != null && tag.trim() !== '' && this.jump.sautants.indexOf(tag) < 0) {
            this.jump.sautants.push(tag);
        }
        this.tagField.reset('');
        const participants = (this.jump.sautants.length + 1);
        this.jumpForm.controls['participants'].setValue(participants);
    }

    closeDialog(): void {
        this._setAllLast(false);
        //this.jump = <Jump>{};
        //this.jump.numero = this.nextJump;
        this.dialogRef.close();
    }

    getErrorMessage(name: string): string {
        if (this.jumpForm.controls[name].errors !== null) {
            return 'Ce champ est requis.';
        }
        return '';
    }

    removeSautant(index: string): void {
        this.useLast.groupe = false;
        this.useLast.all = this._isLastForAllSections();
        this.jump.sautants = this.jump.sautants.filter((sautant) => sautant !== index);
        const participants = (this.jump.sautants.length + 1);
        this.jumpForm.controls['participants'].setValue(participants);
    }

    setLastJump(checked: boolean) {
        if (checked) {
            this._setAllLast(true);
            this.jumpForm.controls['lieu'].setValue(this.lastJump.lieu);
            this.jumpForm.controls['oaci'].setValue(this.lastJump.oaci);
            this.jumpForm.controls['aeronef'].setValue(this.lastJump.aeronef);
            this.jumpForm.controls['imat'].setValue(this.lastJump.imat);
            this.jumpForm.controls['hauteur'].setValue(this.lastJump.hauteur);
            this.jumpForm.controls['deploiement'].setValue(this.lastJump.deploiement);
            this.jumpForm.controls['voile'].setValue(this.lastJump.voile);
            this.jumpForm.controls['taille'].setValue(this.lastJump.taille);
            this.jumpForm.controls['categorie'].setValue(this.lastJump.categorie);
            this.jumpForm.controls['module'].setValue(this.lastJump.module);
            this.jumpForm.controls['participants'].setValue(this.lastJump.participants);
            //this.jumpForm.controls['sautants'].setValue(this.lastJump.sautants);
            this.jumpForm.controls['programme'].setValue(this.lastJump.programme);
            this.jumpForm.controls['accessoires'].setValue(this.lastJump.accessoires);
            this.jumpForm.controls['zone'].setValue(this.lastJump.zone);
            this.jump.sautants = this.lastJump.sautants;
            /*
            Object.assign(
                this.jump,
                {
                    date: this.lastJump.date,
                    numero: this.lastJump.numero,
                    lieu: this.lastJump.lieu,
                    oaci: this.lastJump.oaci,
                    aeronef: this.lastJump.aeronef,
                    imat: this.lastJump.imat,
                    hauteur: this.lastJump.hauteur,
                    deploiement: this.lastJump.deploiement,
                    voile: this.lastJump.voile,
                    taille: this.lastJump.taille,
                    categorie: this.lastJump.categorie,
                    module: this.lastJump.module,
                    participants: this.lastJump.participants,
                    sautants: this.lastJump.sautants,
                    programme: this.lastJump.programme,
                    accessoires: this.lastJump.accessoires,
                    zone: this.lastJump.zone,
                }
            );
            */
            this.jump.date = '';
        } else {
            this._setAllLast(false);
            this.jumpForm.controls['lieu'].setValue('');
            this.jumpForm.controls['oaci'].setValue('');
            this.jumpForm.controls['aeronef'].setValue('');
            this.jumpForm.controls['imat'].setValue('');
            this.jumpForm.controls['hauteur'].setValue('');
            this.jumpForm.controls['deploiement'].setValue('');
            this.jumpForm.controls['voile'].setValue('');
            this.jumpForm.controls['taille'].setValue('');
            this.jumpForm.controls['categorie'].setValue('');
            this.jumpForm.controls['module'].setValue('');
            this.jumpForm.controls['participants'].setValue(1);
            //this.jumpForm.controls['sautants'].setValue('');
            this.jumpForm.controls['programme'].setValue('');
            this.jumpForm.controls['accessoires'].setValue('');
            this.jumpForm.controls['zone'].setValue('');
            this.jump.sautants = [];
        }
        this.jump.numero = this.nextJump;
    };

    setLastAeronef(checked: boolean = false) {
        if (checked) {
            this.useLast.aeronef = true;
            this.jumpForm.controls['aeronef'].setValue(this.lastJump.aeronef);
            this.jumpForm.controls['imat'].setValue(this.lastJump.imat);
        } else {
            this.useLast.aeronef = false;
            this.jumpForm.controls['aeronef'].setValue('');
            this.jumpForm.controls['imat'].setValue('');
        }
        this.useLast.all = this._isLastForAllSections();
    }

    setLastAltitude(checked: boolean = false) {
        if (checked) {
            this.useLast.altitude = true;
            this.jumpForm.controls['hauteur'].setValue(this.lastJump.hauteur);
            this.jumpForm.controls['deploiement'].setValue(this.lastJump.deploiement);
        } else {
            this.useLast.altitude = false;
            this.jumpForm.controls['hauteur'].setValue('');
            this.jumpForm.controls['deploiement'].setValue('');
        }
        this.useLast.all = this._isLastForAllSections();
    }

    setLastDiscipline(checked: boolean = false) {
        if (checked) {
            this.useLast.discipline = true;
            this.jumpForm.controls['categorie'].setValue(this.lastJump.categorie);
            this.jumpForm.controls['module'].setValue(this.lastJump.module);
        } else {
            this.useLast.discipline = false;
            this.jumpForm.controls['categorie'].setValue('');
            this.jumpForm.controls['module'].setValue('');
        }
        this.useLast.all = this._isLastForAllSections();
    }

    setLastDivers(checked: boolean = false) {
        if (checked) {
            this.useLast.divers = true;
            this.jumpForm.controls['accessoires'].setValue(this.lastJump.accessoires);
            this.jumpForm.controls['zone'].setValue(this.lastJump.zone);
        } else {
            this.useLast.divers = false;
            this.jumpForm.controls['accessoires'].setValue('');
            this.jumpForm.controls['zone'].setValue('');
        }
        this.useLast.all = this._isLastForAllSections();
    }

    setLastDropzone(checked: boolean = false) {
        if (checked) {
            this.useLast.dropzone = true;
            this.jumpForm.controls['lieu'].setValue(this.lastJump.lieu);
            this.jumpForm.controls['oaci'].setValue(this.lastJump.oaci);
        } else {
            this.useLast.dropzone = false;
            this.jumpForm.controls['lieu'].setValue('');
            this.jumpForm.controls['oaci'].setValue('');
        }
        this.useLast.all = this._isLastForAllSections();
    }

    setLastGroupe(checked: boolean = false) {
        if (checked) {
            this.useLast.groupe = true;
            this.jumpForm.controls['participants'].setValue(this.lastJump.participants);
            //this.jumpForm.controls['sautants'].setValue(this.lastJump.sautants);
            this.jump.sautants = this.lastJump.sautants;
        } else {
            this.useLast.groupe = false;
            this.jumpForm.controls['participants'].setValue(1);
            //this.jumpForm.controls['sautants'].setValue('');
            this.jump.sautants = [];
        }
        this.useLast.all = this._isLastForAllSections();
    }

    setLastProgramme(checked: boolean = false) {
        if (checked) {
            this.useLast.programme = true;
            this.jumpForm.controls['programme'].setValue(this.lastJump.participants);
        } else {
            this.useLast.programme = false;
            this.jumpForm.controls['programme'].setValue('');
        }
        this.useLast.all = this._isLastForAllSections();
    }

    setLastVoile(checked: boolean = false) {
        if (checked) {
            this.useLast.voile = true;
            this.jumpForm.controls['voile'].setValue(this.lastJump.voile);
            this.jumpForm.controls['taille'].setValue(this.lastJump.taille);
        } else {
            this.useLast.voile = false;
            this.jumpForm.controls['voile'].setValue('');
            this.jumpForm.controls['taille'].setValue('');
        }
        this.useLast.all = this._isLastForAllSections();
    }

    submitForm(): void {
        /* 
         * Création d'un tableau de saut contenant de 1 à n saut en fonction
         * de la valeur du champ numero du formulaire jumpForm
         */
        let jumps: Array<Jump> = [];
        let jump: Jump = {} as Jump;
        let numeros: Array<number> = [];
        let date: Date;
        /* Controle de la validité du champ date et conversion au format ISO */
        let timestamp: number = Date.parse(this.jumpForm.controls['date'].value);
        if (isNaN(timestamp) == false) {
            date = new Date(timestamp);
        } else {
            date = new Date();
        }

        if (isNaN(+this.jumpForm.controls['numero'].value)) {
            /*
             * 'numero' n'est pas un entier , il s'agit donc d'une plage, d'une quantité ou de plusieurs valeur
             * decomposer la valeur 'numero' et ajouter chaque sauts au tableau retourné par la fenêtre dialog
             */
            let jumpNum: number = this.lastJump.numero;
            const elements: string[] = this.jumpForm.controls['numero'].value.split(';');
            elements.forEach((element: string) => {
                if (element == '') {
                    jumpNum ++;
                    element = jumpNum.toString();
                }
                const values: string[] = element.split('-');
                if (values.length == 2) {
                    const start: number = parseInt(values[0]);
                    const stop: number = parseInt(values[1]);
                    const diff: number = (stop - start);
                    /* Ajout de saut par plage */
                    for (let index = 0; index <= diff; index++) {
                        jumpNum = (start + index);
                        numeros.push(jumpNum);
                    }
                } else {
                    const quantity: string[] = values[0].split('+');
                    if (quantity.length == 2) {
                        /* Ajout de sauts par quantité */
                        const start: number = jumpNum;
                        for (let index = 1; index <= parseInt(quantity[1]); index++) {
                            jumpNum ++;
                            numeros.push(jumpNum);
                        }
                    } else {
                        /* Ajout de sauts par numero */
                        jumpNum = parseInt(quantity[0]);
                        numeros.push(jumpNum);
                    }
                }
            });
        } else {
            /* 'numero' est un entier */
            numeros.push(this.jumpForm.controls['numero'].value);
        }

        /* Valeurs communes aux 1 à n saut(s) à ajouter */
        jump.date = date.toISOString();
        jump.lieu = this.jumpForm.controls['lieu'].value;
        jump.oaci = this.jumpForm.controls['oaci'].value;
        jump.aeronef = this.jumpForm.controls['aeronef'].value;
        jump.imat = this.jumpForm.controls['imat'].value;
        jump.hauteur = this.jumpForm.controls['hauteur'].value;
        jump.deploiement = this.jumpForm.controls['deploiement'].value;
        jump.voile = this.jumpForm.controls['voile'].value;
        jump.taille = this.jumpForm.controls['taille'].value;
        jump.categorie = this.jumpForm.controls['categorie'].value;
        jump.module = this.jumpForm.controls['module'].value;
        jump.participants = this.jumpForm.controls['participants'].value;
        jump.sautants = this.jump.sautants;
        //jump.sautants = this.jumpForm.controls['sautants'].value;
        jump.programme = this.jumpForm.controls['programme'].value;
        jump.accessoires = this.jumpForm.controls['accessoires'].value;
        jump.zone = this.jumpForm.controls['zone'].value;
        //jump.dossier = this.jumpForm.controls['dossier'].value;
        //jump.video = this.jumpForm.controls['video'].value;

        //console.log(numeros);
        /* Ajout du saut au tableau à retourner */
        numeros.forEach((numero: number) => {
            let item: Jump = {} as Jump;
            Object.assign(item, jump);
            item.numero = numero;
            item.dossier = this._computeFilepath();
            item.video = this._computeFilename(numero.toString());
            jumps.push(item);
            //console.log(item);
        });
        //console.log(jumps);
        /* Reset all 'last jump values' booleans */
        this._setAllLast(false);
        /* close the dialog with result */
        this.dialogRef.close(jumps);

        /*
        // Reset all 'last jump values' booleans
        this._setAllLast(false);
        // update the model
        this.updateJump(this.jumpForm.value);
        // close the dialog with result
        this.dialogRef.close(this.jump);
        */
    }

    updateJump(values: NonNullable<unknown>): void {
        Object.assign(this.jump, values);
    }
}
