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 { ResourcesService } from '../../../../services/resources.service';
import { EncService } from '../../../../services/enc.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 { EquipmentManagementService } from '../../../../services/equipment-management.service';
import { FamilyDetailsResponse } from '../../../../interfaces/equipment-management.interface';
import { lastValueFrom } from 'rxjs';
import { MaterialIconsResponse } from '../../../../interfaces/material-icons.interface';
import { availableFiles } from '../../../../../environments/environment.prod';
import { validColorValidator } from 'ngx-colors';

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

  familyCodeControl: FormControl;
  familyNameControl: FormControl;
  familyColorControl: FormControl;
  colorPickerControl: FormControl;
  familyIconControl: FormControl;
  isNew: boolean;
  useCustomIcon: boolean;

  constructor(
    @Inject(MAT_DIALOG_DATA) private _data: any,
    @Inject(DOCUMENT) private _document: Document,
    private _dialofRef: MatDialogRef<NewFamilyComponent>,
    private _resourcesService: ResourcesService,
    private _encService: EncService,
    private _systemAdminService: SystemAdminService,
    private _gdelService: GdelService,
    private _functionsService: FunctionsService,
    private _matIconRegistry: MatIconRegistry,
    private _domSanitizer: DomSanitizer,
    private _equipmentManagementService: EquipmentManagementService,
  ) {
    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('', [Validators.required, Validators.maxLength(5)]);
    this.familyNameControl = new FormControl('', [Validators.required, Validators.maxLength(50)]);
    this.familyColorControl = new FormControl("rgb(79, 195, 255)", [validColorValidator(), Validators.required]);
    this.colorPickerControl = new FormControl("rgb(79, 195, 255)");
    this.familyIconControl = new FormControl('', Validators.required);
    this.isNew = true;
    this.useCustomIcon = false;
  }

  ngOnInit(): void {
    if(this._data.action != 'new'){
      this.familyCodeControl.disable();
      this.isNew = false;

      this.getFamily(this._data.family.CODIGOFAMILIA);
    }else{
      this.getMaterialIcons();
    }
    
    
    this.familyColorControl.valueChanges.subscribe((color) => {
      if(this.familyColorControl.valid){
        this.colorPickerControl.setValue(color, {
          emitEvent: false,
        });
      }
    });

    this.colorPickerControl.valueChanges.subscribe((color) => {
      this.familyColorControl.setValue(color, {
        emitEvent: false,
      })
    });
  }

  async getFamily(familyCode: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let familyCodeEnc = await this._encService.encrypt(familyCode);
      let family: FamilyDetailsResponse = await lastValueFrom(this._equipmentManagementService.familyConsultOnly(familyCodeEnc, idUser, 1));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        this.familyCodeControl.setValue(familyCode);
        this.familyNameControl.setValue(family.response.NOMBRE_FAMILIA);
        this.familyColorControl.setValue(family.response.COLOR_FAMILIA);
        this.colorPickerControl.setValue(family.response.COLOR_FAMILIA);

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

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

          this.customIconStr = family.response.ICONO;
          this.useCustomIcon = true;
        }else{
          this.familyIconControl.setValue(family.response.ICONO);
          this.useCustomIcon = false;
        }

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

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

  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 (3).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (4).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  validateFamilyCode(value: string){
    this.familyCodeControl.markAsTouched();
    this.familyCodeControl.setValue(value.toUpperCase());
  }

  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 (5).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (6).');
      }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 (7).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (8).');
      }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){
      console.log(error);
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (9).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (10).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

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

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

    if(this.familyColorControl.invalid){
      this._resourcesService.openSnackBar('El color de la familia es inválido.');
      return;
    }

    if(this.familyIconControl.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 = {
      code: this.familyCodeControl.value,
      name: this.familyNameControl.value,
      color: this.familyColorControl.value,
      customIcon: this.useCustomIcon ? 'S' : 'N',
      icon: this.useCustomIcon ? this.customIconStr : this.familyIconControl.value,
      iconFile: this.useCustomIcon ? this.uploadedFile!.id : null
    }

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

    this._dialofRef.close(dataEnc);
  }
}
