import { Component, Inject, OnInit } from '@angular/core';
import { TempFileInfo } from '../../../../interfaces/temp-file-info.interface';
import { FormControl, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { DOCUMENT } from '@angular/common';
import { EncService } from '../../../../services/enc.service';
import { ResourcesService } from '../../../../services/resources.service';
import { SystemAdminService } from '../../../../services/system-admin.service';
import { GdelService } from '../../../../services/gdel.service';
import { FunctionsService } from '../../../../services/functions.service';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { lastValueFrom } from 'rxjs';
import { MaterialIconsResponse } from '../../../../interfaces/material-icons.interface';
import { availableFiles } from '../../../../../environments/environment.prod';

@Component({
    selector: 'app-new-subfamily',
    templateUrl: './new-subfamily.component.html',
    styleUrl: './new-subfamily.component.css',
    standalone: false
})
export class NewSubfamilyComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;
  materialIcons: Map<string, string[]>;
  iconsCategories: string[];
  uploadedFile: TempFileInfo | null;
  isUploading: boolean;
  customIconStr: string;

  familyCodeControl: FormControl;
  subfamilyCodeControl: FormControl;
  subfamilyNameControl: FormControl;
  subfamilyIconControl: FormControl;
  isNew: boolean;
  useCustomIcon: boolean;

  constructor(
    @Inject(MAT_DIALOG_DATA) private _data: any,
    @Inject(DOCUMENT) private _document: Document,
    private _encService: EncService,
    private _dialogRef: MatDialogRef<NewSubfamilyComponent>,
    private _resourcesService: ResourcesService,
    private _systemAdminService: SystemAdminService,
    private _gdelService: GdelService,
    private _functionsService: FunctionsService,
    private _matIconRegistry: MatIconRegistry,
    private _domSanitizer: DomSanitizer,
  ) {
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = '';
    this.materialIcons = new Map();
    this.iconsCategories = [];
    this.uploadedFile = null;
    this.isUploading = false;
    this.customIconStr = '';

    this.familyCodeControl = new FormControl({disabled: true, value: ''}, Validators.required);
    this.subfamilyCodeControl = new FormControl('', [Validators.required, Validators.maxLength(5)]);
    this.subfamilyNameControl = new FormControl('', [Validators.required, Validators.maxLength(60)]);
    this.subfamilyIconControl = new FormControl('', Validators.required);
    this.isNew = true;
    this.useCustomIcon = false;
  }

  ngOnInit(): void {
    this.init();
  }

  async init(){
    let idUser = localStorage.getItem('idusuario')!;
    let familyCodeDec = await this._encService.decrypt(this._data.family);
    this.familyCodeControl.setValue(familyCodeDec);

    if(this._data.action != 'new'){
      this.isNew = false;
      this.subfamilyCodeControl.disable();

      let subfamilyCodeDec = await this._encService.decrypt(this._data.subfamily.CODIGOSUBFAMILIA);
      this.subfamilyCodeControl.setValue(subfamilyCodeDec);
      this.subfamilyNameControl.setValue(this._data.subfamily.NOMBRESUBFAMILIA);

      if(this._data.subfamily.ICONO_PERSONALIZADO == 'S'){
        let iconFileDec = await this._encService.decrypt(this._data.subfamily.ARCHIVO_ICONO!);
        let iconFile = await lastValueFrom(this._gdelService.getFileInfo(this._data.subfamily.ARCHIVO_ICONO!, idUser, 1));
        this.uploadedFile = {
          id: this._data.subfamily.ARCHIVO_ICONO!,
          name: iconFileDec,
          size: this._functionsService.formatBytes(iconFile.response.PESO),
          isFinalFile: true,
        };

        let iconURI = await lastValueFrom(this._gdelService.getPublicDocumentUrl(this._data.subfamily.ARCHIVO_ICONO!, idUser, 1));
        this._matIconRegistry.addSvgIcon(
          this._data.subfamily.ICONO,
          this._domSanitizer.bypassSecurityTrustResourceUrl(iconURI.response.public_uri)
        );

        this.customIconStr = this._data.subfamily.ICONO;
        this.useCustomIcon = true;
      }else{
        this.subfamilyIconControl.setValue(this._data.subfamily.ICONO);
        this.useCustomIcon = false;
      }
    }
    
    this.getMaterialIcons();
  }

  async getMaterialIcons(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let icons: MaterialIconsResponse = await lastValueFrom(this._systemAdminService.getMaterialIcons(idUser, 1));

      this.hasError = icons.error;
      this.errorStr = icons.msg;

      if(!this.hasError){
        for(const icon of icons.response){
          if(icon.categorie.length > 0){
            let category = icon.categorie[0];
            if(this.materialIcons.has(category)){
              let iconsByCategory = this.materialIcons.get(category);
              iconsByCategory!.push(icon.name);

              this.materialIcons.set(category, iconsByCategory!);
            }else{
              this.materialIcons.set(category, [icon.name]);
              this.iconsCategories.push(category);
            }
          }
        }
      }

      this.isLoading = false;
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = false;
    }
  }

  verifySubfamilyCode(value: string){
    this.subfamilyCodeControl.setValue(value.toUpperCase());
    this.subfamilyCodeControl.markAsTouched();
  }

  openFileUploader(){
    let uploader = this._document.getElementById('file');
    if(this.uploadedFile == null){
      uploader!.click();
    }else{
      this.deleteTempFile();
    }
  }

  async deleteTempFile(){
    try{
      this.isUploading = true;

      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();
      
      formData.append('id_file', this.uploadedFile!.id);
      formData.append('id_user', idUser);
      formData.append('linea', '1');

      if(this.uploadedFile!.isFinalFile){
        await lastValueFrom(this._gdelService.deleteFile(formData));
      }else{
        await lastValueFrom(this._gdelService.deleteTempFile(formData));
      }

      this.isUploading = false;
      this.uploadedFile = null;
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.isUploading = false;
    }
  }

  checkFile(event: any){
    let fileTypes = availableFiles;
    let sizes = Object.keys(fileTypes);
    let extensions = Object.values(fileTypes);
    let maxSizeMB = 0;

    let extArr = event.target.files[0].name.split(".").reverse();
    let extStr = extArr[0];

    if(extStr != 'svg'){
      this._resourcesService.openSnackBar('El archivo seleccionado tiene una extensión inválida.');
      return;
    }

    let i = 0;
    extensions.forEach(ext => {
      let size = parseInt(sizes[i]);

      if(ext.includes(extStr)) maxSizeMB = size;
      i++;
    });

    if(maxSizeMB == 0){
      this._resourcesService.openSnackBar(`Los archivos ${extStr} no están soportados`);
    }else{
      let maxFileSize = 1048576 * maxSizeMB;
      let fileSize = event.target.files[0].size;

      if(fileSize > maxFileSize){
        this._resourcesService.openSnackBar(`El tamaño del archivo supera el límite de ${maxSizeMB} MB`);
      }else{
        this.isUploading = true;
        this.uploadTmp(event.target.files[0]);
      }
    }
  }

  async uploadTmp(fileData: any){
    try{
      let idUser = localStorage.getItem('idusuario');
      let formData = new FormData();

      formData.append('file', fileData);
      formData.append('id_user', idUser!);
      formData.append('linea', "1");

      let response = await lastValueFrom(this._gdelService.uploadTempFile(formData));

      if(response.error){
        this._resourcesService.openSnackBar(response.msg);
      }else{
        this.uploadedFile = {
          id: response.response.idArchivo,
          name: fileData.name,
          size: this._functionsService.formatBytes(fileData.size),
          isFinalFile: false,
        };
      }

      this.isUploading = false;
      this.registerCustomIcon();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar('error.error.msg');
      }
      this.isUploading = false;
    }
  }

  async registerCustomIcon(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let sanitizedIconName = this._functionsService.sanitizeIconName(this.uploadedFile!.name);
      let publicTempURI = await lastValueFrom(this._gdelService.getPublicTempDocumentUrl(this.uploadedFile!.id, idUser, 1));
      
      if(publicTempURI.error){
        this._resourcesService.openSnackBar(publicTempURI.msg);
      }else{
        this._matIconRegistry.addSvgIcon(
          sanitizedIconName,
          this._domSanitizer.bypassSecurityTrustResourceUrl(publicTempURI.response.public_uri)
        );

        this.customIconStr = sanitizedIconName;
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async saveSubfamily(){
    if(this.familyCodeControl.invalid){
      this._resourcesService.openSnackBar('El código de la familia relacionada es inválido.');
      return;
    }

    if(this.subfamilyCodeControl.invalid){
      this._resourcesService.openSnackBar('El código de la subfamilia es inválido.');
      return;
    }

    if(this.subfamilyNameControl.invalid){
      this._resourcesService.openSnackBar('El nombre de la subfamilia es inválido.');
      return;
    }


    if(this.subfamilyIconControl.invalid && !this.useCustomIcon){
      this._resourcesService.openSnackBar('El ícono seleccionado es inválido.');
      return;
    }

    if(this.useCustomIcon && this.uploadedFile == null){
      this._resourcesService.openSnackBar('Aún no se ha subido ningún archivo SVG.');
    }

    let dataObj = {
      family: this.familyCodeControl.value,
      code: this.subfamilyCodeControl.value,
      name: this.subfamilyNameControl.value,
      customIcon: this.useCustomIcon ? 'S' : 'N',
      icon: this.useCustomIcon ? this.customIconStr : this.subfamilyIconControl.value,
      iconFile: this.useCustomIcon ? this.uploadedFile!.id : null
    }

    let dataStr = JSON.stringify(dataObj);
    let dataEnc = await this._encService.encrypt(dataStr);

    this._dialogRef.close(dataEnc);
  }
}
