import { Component, ViewChild, OnInit, AfterViewInit } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Router } from '@angular/router';
import { EncService } from 'src/app/services/enc/enc.service';
import { ContentArtitle, DataTableResponse, DialogModule, ResponseDataLine } from 'src/app/interfaces/acquisition-management/acquisition/artitle.interface';
import { ObjectRequestLine } from 'src/app/interfaces/acquisition-management/acquisition/order.interface';
import { AlertData } from 'src/app/interfaces/alert.interface';
import { MatDialog } from '@angular/material/dialog';
import { AlertComponent } from 'src/app/components/resources/dialogs/alert/alert.component';
import { DescriptionLineComponent } from '../description-line/description-line.component';
import { ResourcesService } from 'src/app/services/resources/resources.service';
import { lastValueFrom } from 'rxjs';
import { ArtitleService } from 'src/app/services/acquisition-management/acquisition/artitle.service';
import { HttpErrorResponse } from '@angular/common/http';
import { OrderService } from 'src/app/services/acquisition-management/acquisition/order.service';

@Component({
  selector: 'app-shopping-cart',
  templateUrl: './shopping-cart.component.html',
  styleUrls: ['./shopping-cart.component.css']
})
export class ShoppingCartComponent implements AfterViewInit, OnInit {

  // Variable loading
  public isLoading: boolean;
  public isLoadingForm: boolean;

  // Variables de reacomodar la pantalla
  public btnSmall: boolean;
  public card_size: string;

  // Variables de la tabla
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;
  public dataSource: MatTableDataSource<any>;
  public displayedColumns: Array<string>;

  // Productos del carrito de compra
  public arrShoppingCart: Array<ContentArtitle>;

  constructor(
    private _router: Router,
    private _encService: EncService,
    private _artitleServices: ArtitleService,
    private _orderServices: OrderService,
    private _dialog: MatDialog,
    private _resourcesServices: ResourcesService,
  ) {
    this.isLoading = false;
    this.isLoadingForm = false;
    this.btnSmall = false;
    this.card_size = 'card-size-normal mat-elevation-z8';
    this.dataSource = new MatTableDataSource<DataTableResponse>([]);
    this.arrShoppingCart = [];
    this.displayedColumns = ['IMAGEN','ARTICULO','PROVEEDOR','MODELO','CODIGO','CANTIDAD','PRECIO','PRECIOTOTAL','ACCIONES'];

  }

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

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

  public async getShoppingCart() {
    // Se obtiene los datos del localstorage del carrito de compra
    let localStorageCar = localStorage.getItem('car_shopping_artitles');
    // Se valida que la variable se encuentre en el localstorage
    let strItemsCar: string = localStorageCar !== null && localStorageCar !== undefined ? localStorageCar : '';

    if (strItemsCar.length !== 0) {
      // Se desencripta la cadena obtenida por el localstorage
      let strArtitlesSelected: string = await this._encService.desencriptar(strItemsCar);
      // Se transforma a un arreglo
      this.arrShoppingCart = JSON.parse(strArtitlesSelected);

      // Se inicializa el arreglo de los artículos del carrito
      let arrCarArtitles: Array<DataTableResponse> = [];
      // Se iteran los productos del carrito
      this.arrShoppingCart.map((shoppingCart: ContentArtitle) => {
        // Se iterea el contenido de los artículos
        shoppingCart.content.map((element: DataTableResponse) => {
          // Se genera el objeto para las tablas
          let arrTable: DataTableResponse = {
            NUMERO_ARTICULO: shoppingCart.idArtitle,
            ARTICULO: shoppingCart.artitle,
            URL_IMAGEN: shoppingCart.url_imagen,
            NUMERO_PROVEEDOR: shoppingCart.idProvider,
            NUMERO_PRODUCTO: element.NUMERO_PRODUCTO,
            MODELO: element.MODELO,
            CODIGO: element.CODIGO,
            CARACTERISTICAS: element.CARACTERISTICAS,
            TIPO: element.TIPO,
            CANTIDAD: element.CANTIDAD,
            PRECIO: element.PRECIO,
            MONEDA: element.MONEDA,
          }
          arrCarArtitles.push(arrTable);
        });
      });

      this.dataSource.data = arrCarArtitles;
    }
  }

  public openModal( dataElement: any = null ) {
    const dialogRef = this._dialog.open(DescriptionLineComponent, {
      data: dataElement === null ? '' : dataElement,
      disableClose: true,
      width: '600px',
    });

    dialogRef.afterClosed().subscribe((description) => {
      if (description) {
        this.alert('CREATE', description);
      }
    });
  }

  // Método para ejecutar una alerta
  public async alert(type: string, dataElement: any = null!) {
    let dataDialog: AlertData = {} as AlertData;
    if (type === 'DELETE') {
      dataDialog = {
        icon: "warning",
        title: "Eliminar Producto",
        description: "¿Está seguro de eliminar este produto del carrito de compra?"
      };
    }else if(type === 'CREATE'){
      dataDialog = {
        icon: "warning",
        title: "Registro de Línea de Solicitud",
        description: "¿Está seguro de registrar estos productos a la línea de solicitud de compra?"
      };
    }

    // Se ejecuta la alerta
    const dialogRef = this._dialog.open(AlertComponent, {
      data: dataDialog,
      disableClose: true,
      width: type === 'DELETE' ? '350px' : '350px',
    });

    // Se obtiene la respuesta obtenida por la alerta
    dialogRef.afterClosed().subscribe((result) => {
      // Se ejecuta la acción según el tipo seleccionado
      if (result && type === 'DELETE') {
        // Se ejecuta el método para eliminar una tabla
        this.deleteArtitle(dataElement);
      }
      // Alerta para registrar
      if(result && type === 'CREATE'){
        this.registerRequestLine(dataElement);
      }else if(!result && type === 'CREATE'){
        this.openModal(dataElement);
      }
    });
    this.isLoadingForm = false;
  }

  // Método: Registro de línea de solicitud de compra
  private async registerRequestLine(description: string) {
    this.isLoading = true;

    let objRequestLine: ObjectRequestLine = {
      line: await this._encService.encriptar('1'),
      user: this._resourcesServices.getUser(),
      description: await this._encService.encriptar(description),
      products: await this._encService.encriptar(JSON.stringify(this.arrShoppingCart))
    }

    await lastValueFrom(this._orderServices.createRequestLine(objRequestLine)).then(
      (data: ResponseDataLine) => {
        if (!data.error) {
          this._resourcesServices.openSnackBar('¡La línea de solicitud se registró correctamente!');
          this._resourcesServices.openSnackBarAfter('La solicitud se encontrará el proceso de validación por el módulo de Gestión de Presupuesto');
          localStorage.removeItem('car_shopping_artitles');
          this._router.navigate(['/sam/purchase-requisition-lines']);
        } else {
          this._resourcesServices.openSnackBar('Ocurrió un error inesperado: ' + data.msg);
        }
      }, (error: HttpErrorResponse) => {
        this._resourcesServices.checkErrors(error);
      }
    );
    this.isLoading = false;
  }

  // Método: Eliminar artículo
  public async deleteArtitle(artitle: DataTableResponse) {
    // Se inicializa el index del carrito en caso de ya no existir contenido
    let indexShoppingCart: number = null!;

    // Se iteran los prodcutos del carrito
    this.arrShoppingCart.map((shoppingCar: ContentArtitle, indexShopping: number) => {
      // Se identifica el artículo seleccionado
      if (shoppingCar.idArtitle === artitle.NUMERO_ARTICULO) {
        // Se obtiene el contenido del artículo
        let arrContentCart: Array<DataTableResponse> = shoppingCar.content;
        // Se itera el contenido de los artículos
        arrContentCart.map((contentCart: DataTableResponse, indexContentCart: number) => {
          // Se identifica el producto del contenido del artículo
          if (contentCart.NUMERO_PRODUCTO === artitle.NUMERO_PRODUCTO) {
            // Se elimina el producto seleccionado
            shoppingCar.content.splice(indexContentCart, 1);
          }
        });
      }
      // En caso de ya no haber contenidos en el artículo entonces se guarda el index del artículo
      if (shoppingCar.content.length === 0) {
        indexShoppingCart = indexShopping;
      }
    });

    // Si el index del carrito es diferente a null entonces significa que ya no hay contenidos en el artículo en el carrito
    if (indexShoppingCart !== null) {
      // Se elimina el artículo mediante el index
      this.arrShoppingCart.splice(indexShoppingCart, 1);
    }

    // El carrito se transforma en una cadena
    let strShoppingCart = JSON.stringify(this.arrShoppingCart);
    // La cadena se encripta
    let encShoppingCart = await this._encService.encriptar(strShoppingCart);
    // La cadena encriptada se guarda en el localstorage
    localStorage.setItem('car_shopping_artitles', encShoppingCart);
    // Se actualiza el carrito de compra
    this.getShoppingCart();
  }

  // Método para regresar a la pantalla anterior
  public goBack() {
    window.history.back();
  }

  public getTotalCost() {
    return this.dataSource.data.map(t => t.PRECIO * t.CANTIDAD).reduce((acc, value) => acc + value, 0);
  }

  // Método de filtrado de datos
  public applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.dataSource.filter = filterValue.trim().toLowerCase();
    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }

  // Método para reajustar la pantalla
  public onResize() {
    if (window.innerWidth <= 1400) {
      this.btnSmall = true;
      this.card_size = 'card-size-small';
    } else if (window.innerWidth > 1400) {
      this.btnSmall = false;
      this.card_size = 'card-size-normal mat-elevation-z8';
    }
  }

}
