import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, OnInit, Output, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { PdfService } from 'src/app/services/pdf.service';
import { Object } from 'src/app/modules/object';
import { Document } from 'src/app/modules/document';
import { Style } from 'src/app/modules/style';
import { CdkDragStart, CdkDragEnd } from '@angular/cdk/drag-drop';
import { SignatureForm } from 'src/app/modules/signataireForm';
import { Constant } from 'src/app/helper/constant';
import { Demande } from 'src/app/modules/demande';
import { UserPosition } from 'src/app/modules/userPosition';
import { Destinataire } from 'src/app/modules/destinataire';
import { ApiService } from 'src/app/services/api.service';
import { DemandeService } from 'src/app/services/demande.service';
import { Router } from '@angular/router';
import { NzMessageService } from 'ng-zorro-antd/message';
import { error } from '@ant-design/icons-angular';
import { NgxSpinnerService } from 'ngx-spinner';
import Konva from 'konva';
import { Transformer } from 'konva/lib/shapes/Transformer';


@Component({
  selector: 'app-edit-document',
  templateUrl: './edit-document.component.html',
  styleUrls: ['./edit-document.component.scss'],
})
export class EditDocumentComponent implements OnInit {

  pdfSrc = "https://vadimdez.github.io/ng2-pdf-viewer/assets/pdf-test.pdf";

  @Input() signataireForm : SignatureForm = new SignatureForm() ;
  @Output() changerStatut: EventEmitter<void> = new EventEmitter<void>();

  @ViewChildren('drops') divs!: QueryList<ElementRef>;
  @ViewChildren('drags') drags!: QueryList<ElementRef>;
  @ViewChild('stage', { static: false }) stageRef!: ElementRef;

  page = 1;

  signataires : UserPosition[] = [];
  documents : Document[] = [];
  indexSelected! : number;
  spinner = false;

  constant : Constant= new Constant();
  demande : Demande = new Demande();
 
  screenWidth!: number;
  screenHeight!: number;
  paginationIndex = 1 ;
  paginationTotal = 0 ;
  destinataireSelected = new Destinataire();
  today = Date.now()

  origin : Object [] = [
    {title: 'Signature', type:'file', src : './assets/img/pen_sm.svg', text : "" , selected: false,width : 200, height : 100,transform :"", x : 0, y: 0 },
    {title: 'Cachet', type:'select', src : './assets/img/cachet.svg', text : "" ,selected: false,width : 120, height : 120, transform :"", x : 0, y: 0},
    {title: 'Nom et prénom', type:'text' , src : './assets/img/user.svg',text : "", selected: false,width : 200, height : 60, transform :"", x : 0, y: 0},
    {title: 'Date de signature', type:'date', src : './assets/img/calendar.svg', text : "" , selected: false,width : 200, height : 60, transform :"", x : 0, y: 0},
    {title: 'Bouton de validation', type:'checked', src : './assets/img/checked.svg',text : "", selected: false,width : 200, height : 60, transform :"", x : 0, y: 0},
  ];
  width = 200;
  height = 200;
  select : Object = new Object();

  indexUser = 0;

  itemdeleted : any;
  indexPage = 0;
  pdfFile: File | null = null;
  images: string[] = [];
  style!: { position: string; left: string; top: string; width: string; height: string; };
  isVisible = false;
  transformMatrix: string | undefined;
  canView = false;
  deletedRectangle : any;

  

  stage!: Konva.Stage;
  layer!: Konva.Layer;
  layerText!: Konva.Layer;
  rectangles: Konva.Rect[] = [];
  isVisibleRecap = false;
  

  constructor(private pdfToImageService: PdfService, private apiService: ApiService, private cdr: ChangeDetectorRef,
    private demandeService: DemandeService, private router: Router, private message: NzMessageService, private spinnerTemplate: NgxSpinnerService
  ) {
    console.log(this.signataireForm)
    this.screenWidth = window.innerWidth;
    this.screenHeight = window.innerHeight;

   }
  ngOnInit(): void {
    console.log(this.signataireForm)
    this.convertPdfToImages(this.signataireForm.file!);
    this.destinataireSelected = this.signataireForm.demande.destinataires[0];
  }


   executerMethodeParent() {
     // Exécutez votre méthode ici
     this.changerStatut.emit();
   }

   handleCancel() {
    this.isVisibleRecap = false;
    }


   nextPage(pageIndex: number) {
    this.paginationIndex = pageIndex;
    this.indexPage = this.paginationIndex - 1;
    this.supprimerTousRectangles(this.layer);
    this.supprimerTousText(this.layerText);
    console.log(this.indexPage);
    if(this.signataires[this.indexUser].documents[this.indexPage].objects.length > 0){
      this.signataires[this.indexUser].documents[this.indexPage].objects.forEach((rect : any) => {
        this.initialzeRectangle(rect);
      })
    }

    console.log(this.signataires);
  
  }


  selected(num:number){
    this.select = this.origin[num];
   // console.log(this.origin[num]);
   
  }

  destination : any[] = [
  ];

  isHovered = false;


  onDropEnded(event: CdkDragStart, index:number) {

  }


  onFileSelected(event: any) {
    this.pdfFile = event.target.files[0];

  }

  onOptionChange(index:number){
    this.indexPage = 0;
    this.paginationIndex = 1;
    this.destinataireSelected = this.signataireForm.demande.destinataires[index];

    this.supprimerTousRectangles(this.layer);
    this.supprimerTousText(this.layerText);
    console.log(this.indexPage);
    if(this.signataires[this.indexUser].documents[this.indexPage].objects.length > 0){
      this.signataires[this.indexUser].documents[this.indexPage].objects.forEach((rect : any) => {
        this.initialzeRectangle(rect);
      })
    }
    console.log(index)
  }

  // Images en format base64
  async convertPdfToImages(file : File) {
    if (!file) {
      console.error('Aucun fichier PDF sélectionné.');
      return;
    }
    try {
      console.log("images")

      this.images = await this.pdfToImageService.convertToImage(file);
      this.paginationTotal = this.images.length

      // j'ai évité la notion de pointeur à ce niveau
      //j"initialise pour chaque signataires, des objects à insérer.

      this.signataireForm.users.forEach((user: any, index :number) => {  
        var u = new UserPosition();
        u.documents = [];
        this.images.forEach((image:string, i:number) => {
          u.documents.push({
            page : i,
            objects : []
          })
        })
        u.email = user.email,
        u.role = user.role,
        this.signataires.push(u)
      })
      // Images en format base64
      console.log(this.signataires); 
    } catch (error) {
      console.error('Une erreur est survenue lors de la conversion du PDF en images:', error);
    }
  }

  createMessage(type: string, messqge: string): void {
    this.message.create(type, messqge);
  }

  selectItem(item : any, index : number) {
    if(!this.itemdeleted){
      this.itemdeleted = item;
    }else{
      this.itemdeleted = null;
    }
    this.signataires[this.indexUser].documents[this.indexPage].objects.map((obj:any) => {
          if(item.title != obj.title){
            obj.selected = false;
          }
    })
    this.indexSelected = index;
    item.selected = !item.selected;
  }

  deleteItem(item:any, index:number) {
   // console.log(index)
   // console.log(item)
  }

  addDemande(){
    this.isVisibleRecap = false;
    this.spinnerTemplate.show();
    this.signataireForm.demande.destinataires.map((userDes:Destinataire) => {
      this.signataires.forEach((signataire: UserPosition) => {
        if(userDes.email == signataire.email){
          var position: any[] = [];
          signataire.documents.forEach(element => {
            var information = {
              id : 0,
              information : {
                  "page" : element.page,
                  "objects" : element.objects
              }
            }
            position.push(information);
          });
          userDes.positions = position;
        }
    })
   
    })


   // console.log(this.signataireForm);
    this.uploadFile(this.signataireForm.file!);


  }

  uploadFile(file: File){
      this.apiService.uploadFile(file).subscribe((data:any) => {
        this.signataireForm.demande.documents = []
        if(data.status_code == "000"){
            this.signataireForm.demande.documents.push(
              {
                directory: data.status_label,
                id: 0,
                demande: new Demande
              }
            )
          this.registryDemande(this.signataireForm.demande);
        }else{
          this.spinnerTemplate.hide();
          this.createMessage("error", "Une erreur est survenue au moment de l'ajout de la demande.");
        }
        console.log(data);
      }, (error) => {
        this.spinnerTemplate.hide();
        this.createMessage("error", "Une erreur est survenue au moment de l'ajout de la demande.");
      });
  }

  registryDemande(demand: Demande){
    console.log
    this.demandeService.addDemande(demand).subscribe((data : any) => {
      if(data.status_code=="000"){
        this.spinnerTemplate.hide();
        console.log(data);
        this.isVisible = true
        setTimeout(() => {
          this.isVisible = false;
            this.router.navigate(["home/signature"])
        }, 2000);
      }else{
        this.spinnerTemplate.hide();
        this.createMessage("error", "Une erreur est survenue au moment de l'ajout de la demande.");
      }
    
    },  (error) => {
      this.spinnerTemplate.hide();
      this.createMessage("error", "Une erreur est survenue au moment de l'ajout de la demande.");
    })
  }

  addRectangle(event: CdkDragEnd, id : string, obejt: Object) {

    const groupe = new Konva.Group({
      x: event.dropPoint.x/3,
      y: event.dropPoint.y/3,
    });
    const rect = new Konva.Rect({
      x: event.dropPoint.x/3,
      y: event.dropPoint.y/3,
      width: obejt.width,
      height: obejt.height,
      fill: "#ffd65bb7",
      stroke: "green",
      strokeWidth: 3,
      draggable: true,
      title : "",
      name: obejt.title,
      id: id
    });
    this.layer.add(rect); 
    this.ajouterTitre(this.layerText, rect);
    rect.on('dragend', () => {
      console.log('Rectangle resized: x : ', rect.x(), ' y : ', rect.y());

    });
    rect.on('click', () => {
     // rect.draggable(rect.draggable() === true ? false : true);
     console.log(rect);
     // rect.strokeWidth(rect.strokeWidth() === 3 ? 5 : 3);
     this.deletedRectangle = rect;
     this.deleteTransformation(rect);
      if(rect.stroke() == "green"){
        console.log('Rectangle id : ', rect.id());
        rect.stroke("black");
        this.addTransform(rect);
        this.layer.batchDraw();
      }else if(rect.stroke() == "black"){
        rect.stroke("green");
      }
    });
    this.signataires[this.indexUser].documents[this.indexPage].objects.push(rect.attrs);
    console.log(this.signataires)
    this.layer.draw();
  }


  initialzeRectangle(rectangle : any) {
    const rect = new Konva.Rect(rectangle);
    this.layer.add(rect); 
    this.ajouterTitre(this.layerText, rect);
    rect.on('dragend', () => {
      console.log('Rectangle resized: x : ', rect.x(), ' y : ', rect.y());

    });
    rect.on('click', () => {
      console.log(rect);
     // rect.strokeWidth(rect.strokeWidth() === 3 ? 5 : 3);
     this.deletedRectangle = rect;
     this.deleteTransformation(rect);
      if(rect.stroke() == "green"){
        console.log('Rectangle id : ', rect.id());
        rect.stroke("black");
        this.addTransform(rect);
        this.layer.batchDraw();
      }else if(rect.stroke() == "black"){
        console.log("delete")
        rect.stroke("green");

      }
    });
    this.layer.draw();
  }


  ajouterTitre(layer: any, rect: any) {
    const text = new Konva.Text({
      x: rect.x() , // Position x correspondant au rectangle
      y: rect.y() + rect.height()*0.41, // Position y correspondant au rectangle
      text: rect.name(),
      fontSize: 20,
      align: 'center',
      fill: 'black',
       width: rect.width()
    });
    text.setAttr('rectId', rect.id());
    layer.add(text);
    layer.draw();
  }

  testMe(event: any, index:number){
    let object = this.origin[index];
    var stateData = false;
    if(this.signataires[this.indexUser].documents.length > 0){
      this.signataires[this.indexUser].documents.forEach((doc : Document) => {
        if(doc.page == this.indexPage){
          var dataFilter = doc.objects.filter((element:any) => object.title == element.name);
          if(dataFilter.length > 0){
            this.createMessage("info", "Cet objet existe déjà");
            stateData = true;
          }
        }
      })
    }
    if(stateData == false){
      this.addRectangle(event, this.generateUniquekey(), this.origin[index]);
    }

  }

  ngAfterViewInit() {
    console.log(this.stageRef)
    this.stage = new Konva.Stage({
      container: "container",
      width: 793,
      height: 1123
    });

    this.layer = new Konva.Layer();
    this.layerText = new Konva.Layer();
    this.stage.add(this.layer);
    this.stage.add(this.layerText);

    this.layer.on('dragmove', () => {
    this.detectPostion();
    });
  }

  detectPostion(rectnew?: any){
    this.layerText.children.forEach(text => {
      const rectId = text.getAttr('rectId');
          if(rectnew){
            console.log("check")
          if(rectnew.id() == rectId){
          const rectangle = rectnew;
        //  console.log(rectangle)
            if (rectangle) {
              this.signataires[this.indexUser].documents[this.indexPage].objects.map((rect : any) => {
                  if(rect.id == rectId){
                    rect.x = rectangle.x();
                    rect.y = rectangle.y();
                  }
              })
              text.width(rectangle.width())
              text.position({
                x: rectangle.x(),
                y: rectangle.y() + rectangle.height()*0.41 // Ajustez la position verticale du texte si nécessaire
              });
            }
        }
      }else{
        const rectangle = this.layer.findOne('#' + rectId);
        if (rectangle) {
          this.signataires[this.indexUser].documents[this.indexPage].objects.map((rect : any) => {
              if(rect.id == rectId){
                rect.x = rectangle.x();
                rect.y = rectangle.y();
              }
          })
          text.position({
            x: rectangle.x(),
            y: rectangle.y() + rectangle.height()*0.41 // Ajustez la position verticale du texte si nécessaire
          });
        }
      }
    });
  }

  deleteComposant(){
    console.log(this.signataires);
    console.log(this.deletedRectangle);
    let objts = this.signataires[this.indexUser].documents[this.indexPage].objects.filter((obj:any) => obj.id != this.deletedRectangle.attrs.id);
    this.signataires[this.indexUser].documents[this.indexPage].objects = objts;
  }

  deleteOneRect(rect : any){
    this.deleteTransformation(rect);
    const rectangles = this.getAllElements(this.layer);
     rectangles.forEach((rectangle: any) => {
      if(rect.id() == rectangle.id())
         rectangle.remove();
     });
     this.layer.batchDraw(); 
     this.layer.draw();
     this.deleteOneText(rect);
  }  

  deleteOneText(rect : any){
   const textes = this.getAllElements(this.layerText);
   textes.forEach((text: any) => {
    if(text.attrs.rectId == rect.attrs.id)
      text.remove();
    });
    this.layerText.batchDraw(); 
    this.layerText.draw();
    this.deleteComposant();
  } 

  supprimerTousRectangles(layer: any) {
    const rectangles = this.getAllElements(layer);
    rectangles.forEach((rectangle: any) => {
        rectangle.remove();
    });
    layer.batchDraw(); 
    layer.draw();
  }

  getAllElements(layer: any): any[] {
    let elements: any[] = [];
    layer.getChildren().forEach((element: any) => {
        if (element.isGroup) {
            elements = elements.concat(this.getAllElements(element));
        } else {
            elements.push(element);
        }
    });
    return elements;
}

  supprimerTousText(layer: any) {
    const elements = this.getAllElements(layer);
    elements.forEach((text: any) => {
      text.remove();
    });
    layer.batchDraw(); 
    layer.draw();
     console.log(layer.getChildren())
  }


  addTransform(rect : any){
    var tr = new Konva.Transformer();
    tr.nodes([rect]);
    tr.on('transform', () => {
      var width = rect.width() * rect.scaleX();
      var height = rect.height() * rect.scaleY();
      console.log(rect)
      rect.width(width);
      rect.height(height);
      this.detectPostion(rect);
      if (width > 300) {
        tr.stopTransform();
        var scaleX = 300 / rect.width();
        rect.scaleX(scaleX);
      }
    });
    this.layer.add(tr);
    console.log(this.layer);
  }


  deleteTransformation(rect : any){
    const elements = this.getAllElements(this.layer);
    elements.map((tr: Transformer) => {
      console.log(tr.attrs);
      if(tr.attrs.stroke == "black"){
        tr.attrs.stroke = "green";
      }
      if(tr._nodes){
          tr.remove()
      }
    });
    this.layer.batchDraw(); 
    this.layer.draw();
    console.log(elements);
  } 


  @HostListener('mousemove', ['$event'])
  onMouseMove(event: MouseEvent) {
    
    //console.log(event);
  }

  @HostListener('document:keydown', ['$event'])
  handleKeyboardEvent(event: KeyboardEvent) {
    console.log(event)
    console.log("deleted");
    console.log(this.deletedRectangle);
    if(this.deletedRectangle){
      this.deleteOneRect(this.deletedRectangle);
    }

  }


  generateUniquekey() {
      const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
      let key = '';
      const charactersLength = characters.length;
      for (let i = 0; i < 16; i++) {
          key += characters.charAt(Math.floor(Math.random() * charactersLength));
      }
      return key;
  }

}
