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

@Component({
  selector: 'app-document-order',
  templateUrl: './document-order.component.html',
  styleUrls: ['./document-order.component.css']
})
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 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 _orderDocumentsService: OrderDocumentsService,
    private _dialog: MatDialog,
    private _gdelService: GdelService,
    private _invoiceService: InvoiceService,
    private _orderService: OrderService,
    private _socketService: SocketService,
    private _usersProfilesSevice: UsersProfilesService,
  ) {

    this.isLoading = false;
    this.isLoadingForm = false;

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

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

  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) => {
      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))
      } else {
        this.dataSource.data = this.arrDocument;
      }
    });
  }

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

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

  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(parseInt(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}`);
            }
          }, ( httpErrorResponse: HttpErrorResponse ) => this.resourcesService.checkErrors(httpErrorResponse)
        );
      }
    });
  }

  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 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.LINE_IDLI === parseInt(requestLine)) {
          let dataRequest:string = '';
          if (objRequestLine.LINE_NUOR == null) {
            dataRequest = `#${objRequestLine.LINE_IDLI}`;
          } else {
            dataRequest = `#${objRequestLine.LINE_IDLI} (OC: #${objRequestLine.LINE_NUOR})`;
          }
          this.formGroup.controls['REQUEST_LINE'].setValue(dataRequest);
          this.formGroup.controls['REQUEST_LINE'].disable();
        }
      });
      
      if (requestLine === '0') {
        await lastValueFrom(this._orderDocumentsService.getDocumentsOrder()).then(
          (responseData: ResponseDataGetDocumentOrder) => {
            if ( !responseData.error ) {
              this.dataSource.data = responseData.response;
              this.arrDocument = [... responseData.response];
              this.isLoading = false;      
            } else {
              this.resourcesService.openSnackBar(responseData.msg);
            }
          }, (error: HttpErrorResponse) => this.resourcesService.checkErrors(error)
        );
      } else {
        await lastValueFrom(this._orderDocumentsService.getDocumentsByRequestLine(encRequestLine)).then(
          (responseData: ResponseDataGetDocumentOrder) => {
            if ( !responseData.error ) {
              this.dataSource.data = responseData.response;
              this.arrDocument = [... responseData.response];
              this.isLoading = false;      
            } else {
              this.resourcesService.openSnackBar(responseData.msg);
            }
          }, (error: HttpErrorResponse) => this.resourcesService.checkErrors(error)
        );
      }
    } else {
      this.resourcesService.openSnackBar(`Ocurrió un error al obtener la información.`);
    }
  }

  private async getRequestLine() {
    await lastValueFrom(this._orderService.getAllRequestLines()).then(
      (responseData:ResponseRequestLines) => {
        if (!responseData.error) {
          this.arrRequestLine = responseData.response;
          this.requestLineStr = [];

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

          this.formGroup.controls['REQUEST_LINE'].enable();
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, (httpErrorResponse: HttpErrorResponse) => this.resourcesService.checkErrors(httpErrorResponse)
    );
  }

  public async openDialog(action: string, dataElement?: GetDocumentOrder) {
    if (action === 'REG') {
      this.dialog.open(DocumentFormComponent, {
        width: '450px',
        disableClose: true,
        data: {
          orden: dataElement?.ORCO_NUOR,
          lineNumber: this.lineNumber,
          formData: null
        }
      }).afterClosed().subscribe((result) => {
        if (result) {
          this.getDocuments();
        }
      });
    } else if (action === 'UPD') {
      this.dialog.open(DocumentFormComponent, {
        width: '450px',
        disableClose: true,
        data: {
          orden: dataElement?.ORCO_NUOR,
          lineNumber: dataElement?.DLSC_IDLI,
          formData: dataElement
        }
      }).afterClosed().subscribe((result:any) => {
        if (result) {
          this.getDocuments();
        }
      });
    }

  }

  public getItemDocument(documentCode: string, type: string){
    let response: string = '';
    let arrCodeDocument: Array<string> = documentCode.split('=');

    if ( type === 'VERSION' ) {
      let arrCode = arrCodeDocument[0].split('-');
      response = arrCode[5];
    } else if ( type === 'NAME' ) {
      response = arrCodeDocument[1];
    }

    return response;
  }

  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'
      }).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'
      }).afterClosed().subscribe(async (result) => {
        if ( result ) {
          

          const codeDocument:string = dataElement.DLSC_CODO;
          const idUser:string = this.resourcesService.getUser();
          const line: number = parseInt(this.resourcesService.getLineNumber());
          await lastValueFrom(this._gdelService.getPublicDocumentUrl(codeDocument, idUser, line)).then(
            (responseData: ResponseDataGetPublicDocumentUrl) => {
              if (!responseData.error) {
                window.open(`${responseData.response.public_uri}`, '_blank');
              }
            }, (httpErrorResponse: HttpErrorResponse) => this.resourcesService.checkErrors(httpErrorResponse)
          );


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

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

  private async deleteDocumentOrder(idDocument: number) {
    await lastValueFrom( this._orderDocumentsService.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);
        }
      }, (error: HttpErrorResponse) => this.resourcesService.checkErrors(error)
    )
  }
}
