import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { GetDocumentOrder, ResponseDataGetDocumentOrder } from '../../../../interfaces/acquisition-management/document-order.interface';
import { lastValueFrom, map, Observable, startWith } from 'rxjs';
import { RequestLines, ResponseRequestLines } from '../../../../interfaces/acquisition-management/order.interface';
import { FormControl, FormGroup } from '@angular/forms';
import { ResourcesService } from '../../../../services/resources.service';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { EncService } from '../../../../services/enc.service';
import { AcquisitionService } from '../../../../services/acquisition-management/acquisition.service';
import { GdelService } from '../../../../services/gdel.service';
import { InvoiceService } from '../../../../services/acquisition-management/invoice.service';
import { SocketService } from '../../../../services/socket.service';
import { UsersProfilesService } from '../../../../services/users-profiles.service';
import { HttpErrorResponse } from '@angular/common/http';
import { UserConsultResponse } from '../../../../interfaces/user.interface';
import { ProfileInterface } from '../../../../interfaces/profile.interface';
import { PermissionsData } from '../../acquisition-management.component';
import { DocumentFormComponent } from './document-form/document-form.component';
import { AlertComponent } from '../../../resources/dialogs/alert/alert.component';
import { ResponseData } from '../../../../interfaces/response-data';
import { ResponseDataGetPublicDocumentUrl } from '../../../../interfaces/gdel.interface';
import { ResponseDataGetInvoice } from '../../../../interfaces/acquisition-management/invoice.interface';
import { FunctionsService } from '../../../../services/functions.service';

const ID_MODULE = "S002V01M05GEAD";
@Component({
    selector: 'app-document-order',
    templateUrl: './document-order.component.html',
    styleUrl: './document-order.component.css',
    standalone: false
})
export class DocumentOrderComponent implements AfterViewInit, OnInit {
  public displayedColumns: Array<string> = ['DLSC_IDLI','DLSC_TIPO','DLSC_DESC','DLSC_TIAR','DLSC_USMO','DOOR_FEMO','DLSC_ESTA','ACCIONES'];

  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  public getDocumentEnabled: boolean;
  public formDocumentEnabled: boolean;

  public isLoading: boolean;
  public isLoadingForm: boolean;
  
  public selectedRequest: string | null;

  public dataSource: MatTableDataSource<GetDocumentOrder>;

  public lineNumber:string;

  filteredLineRequest?: Observable<string[]>;
  public requestLineStr: Array<string>;
  public arrRequestLine: Array<RequestLines>;

  public arrDocument: Array<GetDocumentOrder>;

  public formGroup: FormGroup;
  
  constructor(
    public resourcesService: ResourcesService,
    public dialog: MatDialog,
    private _router: Router,
    private _activatedRouter: ActivatedRoute,
    private _encService: EncService,
    private _acquisitionService: AcquisitionService,
    private _dialog: MatDialog,
    private _gdelService: GdelService,
    private _invoiceService: InvoiceService,
    private _socketService: SocketService,
    private _usersProfilesSevice: UsersProfilesService,
    private _functionsService: FunctionsService,
  ) {
    this._functionsService.consultModuleStatus(ID_MODULE);
    this.isLoading = false;
    this.isLoadingForm = false;
    
    this.selectedRequest = null;

    this.getDocumentEnabled = true;
    this.formDocumentEnabled = true;

    this.dataSource = new MatTableDataSource();
    this.lineNumber = '';
    this.formGroup = this.createFormGroup();
    this.arrDocument = [];
    this.arrRequestLine = [];
    this.requestLineStr = [];
  }

  private createFormGroup() {
    return new FormGroup({
      REQUEST_LINE: new FormControl({ value: '', disabled: true })
    });
  }

  async ngOnInit() {
    this.isLoading = true;
    await this.getRequestLine();
    await this.getDocuments();
    await this.refreshPermissions();
    await this.setPermissions();
    this.isLoading = false;
    
    this.filteredLineRequest = this.formGroup.controls['REQUEST_LINE'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.requestLineStr.filter((item) => item.toLowerCase().includes(filterValue));
      })
    );

    this.formGroup.controls['REQUEST_LINE'].valueChanges.subscribe((value:string) => {

      if (value !== null && value !== undefined && value.includes('#') && value.length > 1 ) {
        let filterRequestLine = this.requestLineStr.filter((requestLine:string) => requestLine == value );

        if (filterRequestLine.length > 0) {
          let requestLine: string = '';
          if ( value.includes('(') && value.includes(')') ) {
            requestLine = value.split(' ')[0];
            requestLine = requestLine.trim();
            requestLine = requestLine.replace('#', '');
          } else {
            requestLine = value.trim();
            requestLine = requestLine.replace('#', '');
          }
          this.dataSource.data = this.dataSource.data.filter((element:GetDocumentOrder) => element.DLSC_IDLI === parseInt(requestLine))
          this.selectedRequest = requestLine;
        } else {
          this.dataSource.data = this.arrDocument;
          this.selectedRequest = null;
        }
      } else {
        this.dataSource.data = this.arrDocument;
        this.selectedRequest = null;
      }
      
     
    });
  }

  ngAfterViewInit(): void {
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

  private async getRequestLine() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._acquisitionService.getAllRequestLines(user, line)).then(
      (responseData:ResponseRequestLines) => {
        if (!responseData.error) {
          this.arrRequestLine = responseData.response;
          this.requestLineStr = [];

          this.arrRequestLine.map((requestLine) => {
            let dataRequest: string = '';
            if (requestLine.NUMERO_ORDEN == null) {
              dataRequest = `#${requestLine.ID_LINEA_SOLICITUD}`;
            } else {
              dataRequest = `#${requestLine.ID_LINEA_SOLICITUD} (OC: #${requestLine.NUMERO_ORDEN})`;
            }
            this.requestLineStr.push(dataRequest);
          });

          this.formGroup.controls['REQUEST_LINE'].enable();
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getRequestLine();
        }
      }
    );
  }

  public async getDocuments(){
    this.isLoading = true;

    const encRequestLine = this._activatedRouter.snapshot.paramMap.get('line');
    if (encRequestLine !== null && encRequestLine !== undefined && encRequestLine !== '') {
      let requestLine = await this._encService.decrypt(encRequestLine);
      this.lineNumber = requestLine;

      this.arrRequestLine.map((objRequestLine:RequestLines) => {
        if (objRequestLine.ID_LINEA_SOLICITUD === parseInt(requestLine)) {
          let dataRequest:string = '';
          if (objRequestLine.NUMERO_ORDEN == null) {
            dataRequest = `#${objRequestLine.ID_LINEA_SOLICITUD}`;
          } else {
            dataRequest = `#${objRequestLine.ID_LINEA_SOLICITUD} (OC: #${objRequestLine.NUMERO_ORDEN})`;
          }
          this.formGroup.controls['REQUEST_LINE'].setValue(dataRequest);
          this.formGroup.controls['REQUEST_LINE'].disable();
          this.selectedRequest = objRequestLine.ID_LINEA_SOLICITUD.toString();
        }
      });
      
      const user: string = this.resourcesService.getUser();
      const line: number = this.resourcesService.getLineNumber();
      if (requestLine === '0') {
        await lastValueFrom(this._acquisitionService.getDocumentsOrder(user, line)).then(
          (responseData: ResponseDataGetDocumentOrder) => {
            if ( !responseData.error ) {
              this.dataSource.data = responseData.response;
              this.arrDocument = [... responseData.response];
              this.isLoading = false;      
            } else {
              this.resourcesService.openSnackBar(responseData.msg);
            }
          }, async (httpErrorResponse: HttpErrorResponse) => {
            let response = this.resourcesService.checkErrors(httpErrorResponse)
            if (response !== null && response.reload) {
              await this.getDocuments();
            }
          }
        );
      } else {
        await lastValueFrom(this._acquisitionService.getDocumentsByRequestLine(encRequestLine, user, line)).then(
          (responseData: ResponseDataGetDocumentOrder) => {
            if ( !responseData.error ) {
              this.dataSource.data = responseData.response;
              this.arrDocument = [... responseData.response];
              this.isLoading = false;      
            } else {
              this.resourcesService.openSnackBar(responseData.msg);
            }
          }, async (httpErrorResponse: HttpErrorResponse) => {
            let response = this.resourcesService.checkErrors(httpErrorResponse)
            if (response !== null && response.reload) {
              await this.getDocuments();
            }
          }
        );
      }
    } else {
      this.resourcesService.openSnackBar(`Ocurrió un error al obtener la información.`);
    }
  }

  private async refreshPermissions() {
    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
      let idUser = localStorage.getItem('idusuario')!;
      let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesSevice.getUser(idUser, idUser, 1));
      let currentProfile = await this._encService.decrypt(localStorage.getItem('perfil')!);

      if(currentProfile != usrInfo.response.PERFIL){
        this._router.navigate(['/sam/home']);
      }

      let profileUpdated = await this._encService.decrypt(`${profUpdEnc}`);
      if(profileUpdated == currentProfile){
        let profile = localStorage.getItem('perfil')!;

        await lastValueFrom(this._usersProfilesSevice.getProfile( profile, idUser, 1 )).then(
          (responseData: ProfileInterface) => {
            if (!responseData.error) {
              let modPerm = responseData.response.PERMISOS.permissions.filter(item => item.id == 'S002V01M05GEAD')[0];
              let funPerm = modPerm.children.filter(item => item.id == 'S002V01S01ADQU')[0];
              let panPerm = funPerm.children.filter(item => item.id == "S002V01F04GEDO")[0];

              this.getDocumentEnabled = panPerm.children.filter(item => item.id == 'S002V01P01CODO')[0].access > 0;
              this.formDocumentEnabled = panPerm.children.filter(item => item.id == 'S002V01P02SUDO')[0].access > 0;

              if (panPerm.access === 0) {
                this._router.navigate(['/sam/home']);
              }

            } else {
              this.resourcesService.openSnackBar(`${responseData.msg}`);
            }
          }, async (httpErrorResponse: HttpErrorResponse) => {
            let response = this.resourcesService.checkErrors(httpErrorResponse)
            if (response !== null && response.reload) {
              await this.refreshPermissions();
            }
          }
        );
      }
    });

    this._socketService.refreshModules().subscribe(async () => this._functionsService.consultModuleStatus(ID_MODULE));
  }

  private async setPermissions() {
    const encPermissions = localStorage.getItem('permisos');
    if (encPermissions === null || encPermissions === undefined || encPermissions === '') {
      this.resourcesService.openSnackBar(`Ocurrió un error al obtener los permisos del usuario.`);
      this._router.navigate(['/sam/home']);
      return;
    }
    const strPermissions:string = await this._encService.decrypt(encPermissions);
    const arrPermissions:Array<PermissionsData> = JSON.parse(strPermissions).permissions;

    let modPerm = arrPermissions.filter(item => item.id == 'S002V01M05GEAD')[0];
    let funPerm = modPerm.children.filter(item => item.id == 'S002V01S01ADQU')[0];
    let panPerm = funPerm.children.filter(item => item.id == "S002V01F04GEDO")[0];

    this.getDocumentEnabled = panPerm.children.filter(item => item.id == 'S002V01P01CODO')[0].access > 0;
    this.formDocumentEnabled = panPerm.children.filter(item => item.id == 'S002V01P02SUDO')[0].access > 0;

    if (panPerm.access === 0) {
      this._router.navigate(['/sam/home']);
    }

  }

  public async openDialog(action: string, dataElement?: GetDocumentOrder) {
    if (action === 'REG' && this.selectedRequest !== null) {
      this.dialog.open(DocumentFormComponent, {
        width: '450px',
        maxWidth: '450px',
        disableClose: true,
        data: {
          orden: dataElement?.ORCO_NUOR,
          lineNumber: this.selectedRequest,
          formData: null
        }
      }).afterClosed().subscribe((result) => {
        if (result) {
          this.getDocuments();
          this.formGroup.reset();
        }
      });
    } else if (action === 'UPD' && dataElement !== undefined) {
      this.dialog.open(DocumentFormComponent, {
        width: '450px',
        maxWidth: '450px',
        disableClose: true,
        data: {
          orden: dataElement.ORCO_NUOR,
          lineNumber: dataElement.DLSC_IDLI,
          formData: dataElement
        }
      }).afterClosed().subscribe((result:any) => {
        if (result) {
          this.getDocuments();
          this.formGroup.reset();
        }
      });
    } else {
      this.resourcesService.openSnackBar(`Opción no disponible`);
    }

  }

  public async alert(type: string, dataElement: GetDocumentOrder):Promise<void> {
    this.isLoadingForm = true;
    if (type === 'ELIM') {
      this._dialog.open(AlertComponent, {
        data: {
          icon: "warning",
          title: "Eliminar Documento",
          description: "¿Está seguro de eliminar el documento?",
        },
        disableClose: true,
        width: '400px',
        maxWidth: '400px',
      }).afterClosed().subscribe(async (result) => {
        if ( result ) {
          await this.deleteDocumentOrder(dataElement.DLSC_IDDO);
        }
      });
    } else if (type === 'DOWNLOAD') {
      this._dialog.open(AlertComponent, {
        data: {
          icon: "warning",
          title: "Descarga de Documento",
          description: "¿Está seguro de descargar el documento?",
        },
        disableClose: true,
        width: '400px',
        maxWidth: '400px',
      }).afterClosed().subscribe(async (result) => {
        if ( result ) {
          const codeDocument:string = dataElement.DLSC_CODO;
          const idUser:string = this.resourcesService.getUser();
          const line: number = this.resourcesService.getLineNumber();
          await lastValueFrom(this._gdelService.getPublicDocumentUrl(codeDocument, idUser, line)).then(
            (responseData: ResponseDataGetPublicDocumentUrl) => {
              if (!responseData.error) {
                window.open(`${responseData.response.public_uri}`, '_blank');
              }
            }, async (httpErrorResponse: HttpErrorResponse) => {
              let response = this.resourcesService.checkErrors(httpErrorResponse)
              if (response !== null && response.reload) {
                await this.alert(type, dataElement);
              }
            }
          );


          if (dataElement.DLSC_IDFA !== null) {
            const user: string = this.resourcesService.getUser();
            const line: number = this.resourcesService.getLineNumber();
            const encIdInvoice:string = await this._encService.encrypt(dataElement.DLSC_IDFA.toString());
  
            await lastValueFrom(this._invoiceService.getInvoiceById(encIdInvoice, user, line)).then(
              async (responseData: ResponseDataGetInvoice) => {
                if (!responseData.error) {

                  const codeDocument:string = responseData.response.FALS_CODO;
                  const idUser:string = this.resourcesService.getUser();
                  const line: number = this.resourcesService.getLineNumber();
                  await lastValueFrom(this._gdelService.getPublicDocumentUrl(codeDocument, idUser, line)).then(
                    (responseData: ResponseDataGetPublicDocumentUrl) => {
                      if (!responseData.error) {
                        window.open(`${responseData.response.public_uri}`, '_blank');
                      }
                    }, async (httpErrorResponse: HttpErrorResponse) => {
                      let response = this.resourcesService.checkErrors(httpErrorResponse)
                      if (response !== null && response.reload) {
                        await this.alert(type, dataElement);
                      }
                    }
                  );
                } else {
                  this.resourcesService.openSnackBar(`${responseData.msg}`);
                }
              }, async (httpErrorResponse: HttpErrorResponse) => {
                let response = this.resourcesService.checkErrors(httpErrorResponse)
                if (response !== null && response.reload) {
                  await this.alert(type, dataElement);
                }
              }
            );
          }
        }
      });
    } 
    this.isLoadingForm = false;
  }

  private async deleteDocumentOrder(idDocument: number) {
    await lastValueFrom( this._acquisitionService.deleteDocumentOrder({
      ID_DOCUMENTO: idDocument,
      NUMERO_LINEA: this.resourcesService.getLineNumber(),
      USUARIO: this.resourcesService.getUser()
    })).then(
      ( responseData: ResponseData ) => {
        if ( !responseData.error ) {
          this.resourcesService.openSnackBar('¡Eliminación de Documento Exitoso!');
          this.getDocuments();
        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.deleteDocumentOrder(idDocument);
        }
      }
    )
  }
}
