import { CommonModule } from '@angular/common';
import { ChangeDetectorRef, Component, ComponentFactoryResolver, ElementRef, EventEmitter, Input, Output, Renderer2, ViewChild, ViewContainerRef } from '@angular/core';
import { FormsModule, ReactiveFormsModule, FormGroup, FormControl, NgForm } from '@angular/forms';
import { RouterLink, ActivatedRoute, Router, NavigationStart } from '@angular/router';
import { NgbDropdownModule, NgbModalModule, NgbTooltipModule, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { NgSelectModule } from '@ng-select/ng-select';
import { TranslatePipe } from '@ngx-translate/core';
import { ToastrService } from 'ngx-toastr';
import { debounceTime, Observable, Subject, Subscription, switchMap, takeUntil, timer } from 'rxjs';
import Swal from 'sweetalert2';
import { NgSelectInputComponent } from '../../../../../core/components/input/ng-select-input/ng-select-input.component';
import { TextareaInputComponent } from '../../../../../core/components/input/textarea-input/textarea-input.component';
import { Unsub } from '../../../../../shared/class/unsub.class';
import { AdminService } from '../../../../../shared/services/admin/admin.service';
import { LiveChatService } from '../../../../../shared/services/admin/livechat.service';
import { GuestService } from '../../../../../shared/services/guest.service';
import { LoaderService } from '../../../../../shared/services/loader.service';
import { SharedModule } from '../../../../../shared/shared.module';
import { AgentMessageComponent } from '../agent-message/agent-message.component';
import { CommentMessageComponent } from '../comment-message/comment-message.component';
import { CustomerMessageComponent } from '../customer-message/customer-message.component';
import { EmojiComponent } from '../emoji/emoji.component';
import { FeedbackCommentComponent } from '../feedback-comment/feedback-comment.component';
import { CustomerMessageTypingComponent } from '../customer-message-typing/customer-message-typing.component';
import { LivechatSocketService } from '../../../../../shared/services/livechat-socket.service';
import { TranslatePipes } from '../../../../../shared/pipes/translate/translate.pipe';
import { LivechatDataService } from '../../../../../shared/services/livechat-data.service';

@Component({
  selector: 'app-livechat-view',
  standalone: true,
  imports: [CommonModule, FormsModule, ReactiveFormsModule, RouterLink, SharedModule, NgbDropdownModule, AgentMessageComponent, CustomerMessageComponent, CommentMessageComponent, FeedbackCommentComponent, NgSelectInputComponent, NgbModalModule, NgbTooltipModule, NgSelectModule, TextareaInputComponent, TranslatePipes, EmojiComponent, ],
  templateUrl: './livechat-view.component.html',
  styleUrl: './livechat-view.component.scss'
})
export class LivechatViewComponent extends Unsub {
  @ViewChild('dynamicList', {static: false}) dynamicList!: ElementRef;
  @ViewChild('engageConversation') engageConversation!: ElementRef;
  @ViewChild('textareaDiv') textareaDiv!: ElementRef;
  @ViewChild('supportexpired') supportexpired!: ElementRef;
  @ViewChild('verifysupportexpired') verifysupportexpired!: ElementRef;
  @ViewChild('chatReplyInput', {static: false}) chatReplyInput!:ElementRef;
  public sendingResponse: { [key: string]: boolean } = {};

  @Input() data; //
  @Input() engaged; //
  @Input() settings; //
  // @Input() id = null; //
  @Input() autoUserInfo; //
  @Input() AuthId;//
  // @Input() customerData;//
  livechatcustomerData;
  custId = null;
  chatData;
  @Input()
  get chatDataVal(): any {
    return this.chatData;
  }
  set chatDataVal(value: any) {
    if (value) {
      this.chatData = value;
    }
  }
  @Input()
  get id(): any {
    return this.custId;
  }
  set id(value: any) {
    if (value) {
      this.custId = value;
    }
  }
  @Input()
  get customerData(): any {
    
    return this.livechatcustomerData;
  }
  set customerData(value: any) {
      this.livechatcustomerData = value;
      setTimeout(()=>{
        this.livechatSocketService.setDynamicList(this.dynamicList);
      }, 100)
  }
  @Input() parsedChatFlowMessages: any[] = [];
  // @Input() chatData
  @Input() newVal = ''; 
  @Input() pastMessage = '';
  @Input() subscategory = null;
  @Input() reply = '';
  @Input() isChat = true;
  @Output() updatemenu = new EventEmitter();
  @Output() clearVal = new EventEmitter();
  private typingSubject = new Subject<string>();
  private debounceTimeout = 500; // Debounce time in milliseconds
  admintypingIndicator
  typingList = [];
  adminwriting;
  admintypingStatus
  admintypingEndSubscription: Subscription;
  typingEndSubscription: Subscription;
  writing;
  currentDate;
  operatorUser: any = null;
  typingStatus;
  constructor(private liceChatService: LiveChatService, private elementRef: ElementRef, private adminService: AdminService, private activatedRoute: ActivatedRoute, private guestService: GuestService,private translate: TranslatePipe, private toastr: ToastrService, private router: Router, private liveChatDataService: LivechatDataService, private modalService: NgbModal, private el: ElementRef, 
    private renderer: Renderer2, private livechatSocketService: LivechatSocketService,
    loaderService: LoaderService,private cdr: ChangeDetectorRef, private viewContainerRef: ViewContainerRef) {
    super(loaderService);

    this.typingSubject.pipe(
      debounceTime(this.debounceTimeout),
      switchMap((typingMessage) => {
          return this.sendTypingMessage(typingMessage);
      })
    ).subscribe(
      (data) => {
      },
      (error) => {
      }
    );

    
    this.router.events.pipe(takeUntil(this.unSubscribe$)).subscribe({
      next: (event: any) => {
        if (event instanceof NavigationStart) {
            this.typingList = [];
            this.liveChatDataService.clearWriting();
          }
        }
      })
  }
  typingIndicator = false;
  ngOnInit() {
    
    this.liveChatDataService.data$.subscribe({
      next : res =>{
        if (res.dataUpdate && this.data) { 
          this.data = { ...this.data, filteredLiveCust: res.dataUpdate };
          this.cdr.markForCheck();
        }
        if (res.conversationUpdate && this.chatData && res.conversationUpdate.livechatdata) { 
          if (Object.keys(res.conversationUpdate?.livechatdata)?.length !== 0) {
            this.chatData = { ...this.chatData, livechatdata: [
              ...this.chatData.livechatdata, // Keep existing livechatdata
              res.conversationUpdate.livechatdata // Append new messages from res.conversationUpdate
            ] };            
            this.cdr.markForCheck();
          }
        }
        this.typingList = res.writing;
        this.typingList.map(e =>{
          if(e.typing){
            timer(5000).subscribe(() => {
              e.typing = false;
              this.cdr.markForCheck();
            });
          }
        })
        let liveChatConversation = document.querySelector("#operator-conversation") as HTMLElement;
        if(liveChatConversation){
          liveChatConversation.scrollTop = liveChatConversation.scrollHeight;
        }
      }
    })
  }

  sendTypingMessage(typingMessage: string): Observable<any> {
    const data = {
      message: null,
      username: this.autoUserInfo.name,
      id: this.AuthId,
      customerId: document.querySelector("#operator-conversation").getAttribute("operator-id"),
      typingMessage: typingMessage,
      agentInfo: JSON.stringify(this.autoUserInfo)
    };
    return this.liceChatService.broadcastMessageTyping(data);
  }

  getFileType(value): string {
    let valueStrip = value.split('.');
    let ext = valueStrip[valueStrip.length - 1];    
    return ext?.toLowerCase();
  }
  updateemojiAdded(event){
    const textNode1 = document.createTextNode(event.emoji);
    event.storedRange?.insertNode(textNode1);
    let selection = window.getSelection();
    if(event.storedRange?.commonAncestorContainer.textContent){
      this.newVal = event.storedRange.commonAncestorContainer.textContent;
      setTimeout(() => {
        let newRng = document.createRange();
        newRng.setStartAfter(textNode1)
        newRng.setEndAfter(textNode1)
        selection?.removeAllRanges();
        selection?.addRange(newRng);
      }, 100);
    }
  }
  UploadedImages:string[] = [];
  fileUpload(){
    // conversation Image Upload
    let liveChatFileUpload = this.settings.liveChatFileUpload,
    livechatMaxFileUpload = this.settings.AgentlivechatMaxFileUpload,
    livechatFileUploadMax = this.settings.AgentlivechatFileUploadMax,
    livechatFileUploadTypes = this.settings.AgentlivechatFileUploadTypes;
      var fileInput = document.querySelector("#chat-file-upload") as HTMLInputElement;
      var file:any = fileInput.files?.[0];
      fileInput.value = ""
      var ThereIsError:any = false

      // For check the File Upload permissions
      if(livechatMaxFileUpload <= this.UploadedImages?.length){
          ThereIsError = { errorMessage: "The maximum file upload limit has been exceeded." };
      }else if(file.size > parseInt(livechatFileUploadMax) * 1024 * 1024) {
          ThereIsError = { errorMessage: `File size exceeds ${livechatFileUploadMax} MB. Please choose a smaller file.` };
      }else if(livechatFileUploadTypes && !livechatFileUploadTypes.split(',').some(ext => file.name.toLowerCase().toLowerCase().endsWith(ext.toLowerCase().trim()))) {
          ThereIsError = { errorMessage: `Invalid file extension. Please choose a file with ${livechatFileUploadTypes} extension(s).` };
      }else{
          ThereIsError = false
      }

      // Upload The File
      if (file && !ThereIsError) {
          var formData = new FormData();
          formData.append('chatFileUpload', file);
        this.liceChatService.liveChatImageUpload(formData).subscribe({
          next : res =>{            
            this.UploadedImages.push(res.image);
          }
        })
      }else{
          this.toastr.error(ThereIsError.errorMessage)
      }
  }
  imageRemoveClick(event, image){
    let target = event.target;
    let ele = target.closest('.file-img');
    let data ={
        filename : image,
    }
    this.liceChatService.liveChatImageRemove(data).subscribe({
      next : res =>{
        let indexOfEle = this.UploadedImages.indexOf(image);
        this.UploadedImages.splice(indexOfEle, 1);
      }
    })
  }

  livechatConversationDelete(id) {
    
    Swal.fire({
      icon: 'warning',
      title: this.translate.transform('Are you sure you want to continue?'),
      text: this.translate.transform('This conversation will be deleted'),
      showCancelButton: true,
      confirmButtonColor: '#e64942',
      cancelButtonColor: '#f11541',
      confirmButtonText: this.translate.transform('Delete'),
      cancelButtonText: this.translate.transform('Cancle'),
      reverseButtons: true,
      customClass: {
        confirmButton: 'custom-confirm-button',
        cancelButton: 'custom-cancel-button',
      }
    }).then((result: any) => {
      if (result.isConfirmed) {
        this.liceChatService.livechatConversationDelete(id)
          .pipe(takeUntil(this.unSubscribe$))
          .subscribe({
            next: (res) => {
              this.toastr.success(this.translate.transform('Chat Deleted'));
            localStorage.removeItem('livechatCustomer');
              this.livechatcustomerData = null
              this.chatData = null
              this.parsedChatFlowMessages = []
              this.operatorUser = null;
            },
            error: () => {
            },
          });
      }
    });
  }
  formatDateString(inputDateStr) {
    const inputDate = new Date(inputDateStr);
    const monthNames = [
      "Jan", "Feb", "Mar", "Apr", "May", "Jun",
      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    ];
    const year = inputDate.getFullYear();
    const month = monthNames[inputDate.getMonth()];
    const day = inputDate.getDate();
    const formattedDate = `${day},${month} ${year}`;

    return formattedDate;
  }
  updateValue(val) {
    this.currentDate = this.formatDateString(val)
  }
  parse(val){
    if(val){
      return JSON.parse(val);
    }
    return [];
  }


  reAssign = new FormGroup({
    'custId' : new FormControl(this.custId ?? null)
  });
  cannedRes = new FormGroup({
    'custId' : new FormControl  (this.custId ?? null)
  });

  
  reAssignUserFn(name, main) {
    if (name.valid) {
      let formData = new FormData();
      for (const key in name.value) {
        formData.append(key, name.value[key]);
      }
      formData.append("custId", this.custId);
      this.liceChatService[main](formData).subscribe({
        next: res => {
          this.modalService.dismissAll();          
          localStorage.removeItem('livechatCustomer');
          this.livechatcustomerData = null
          this.chatData = null
          this.parsedChatFlowMessages = []
          this.operatorUser = null;
          this.router.navigateByUrl('/admin/live-chat/new-chats')
        }
      })
    }
  }
  createLivechatTicketFn(ngform, holderId) {
    // // if (name.valid) {
    //   let formData = new FormData();
    //   // for (const key in name.value) {
    //   //   formData.append(key, name.value[key]);
    //   // }
    //   this.liceChatService['main'](formData).subscribe({
    //     next: res => {
    //       this.chatReplyInput.nativeElement.textContent = '';
    //     }
    //   })
    // // }

    
    const formData: any = new FormData();
    
    for (const key of Object.keys(ngform.value)) {
      if (key !== 'envato_id') {
        formData.append(key, ngform.value[key]);
      }
    }
    formData.append('email', this.livechatcustomerData.email);
    formData.append('username', this.livechatcustomerData.username);
    formData.append('message', this.newVal);
    formData.append('agree_terms', 'agreed');
    formData.append('ticket_source', 'Livechat');
    formData.append('envato_id', this.licencekey);
    formData.append('productname', this.envatoName);
    formData.append('envato_support', this.licencesupport);
    for (let i = 0; i < this.UploadedImages.length; i++) {
      formData.append('ticket[]', this.UploadedImages[i]);
    }
    this.guestService
      .openTicketwithoutotp(formData)
      .pipe(takeUntil(this.unSubscribe$))
      .subscribe({
        next: (res) => {
          if (res && res.success) {
            let data ={
                message : `\n ${res.success}  \n\nLink : ${res.data.customer_url}` ,
                cust_id :String(this.livechatcustomerData.id),
                customerId: String(this.livechatcustomerData.id)
            }
            this.liceChatService.broadcastMessage(data).subscribe({
              next : res =>{ 
                this.liceChatService.livechatMarkSolved(this.livechatcustomerData.id).subscribe({
                  next: res =>{
                    this.router.navigate([`/admin/live-chat/solved-chats`], { queryParams: { id: res?.id }});
                    localStorage.removeItem('livechatCustomer');
                  }
                })
              }
            })
            this.toastr.success(this.translate.transform(res.success));
            localStorage.removeItem('admincreateTicket');
          }
          if (res && res.error?.message) {
            this.toastr.error(this.translate.transform(res.error.message));
          }
          else if (res && res.error) {
            this.toastr.error(this.translate.transform(res.error));
          }
        },
        error: () => {
        },
      });
  }
  onEnterKey(event: KeyboardEvent, form: NgForm) {
    if (event.shiftKey) {
      // Allow new line for Shift + Enter
      return;
    }
  
    // Prevent default Enter behavior and submit the form
    event.preventDefault();
    if (form.valid) {
      if(this.isChat){
        this.chatReplyUserFn(form, 'livechatConversationReassign');
      }else{
        this.createLivechatTicketFn(form, 'livechatConversationReassign');
      }
    }
  }
  chatReplyUserFn(ngForm, holderId) {
    this.sendingResponse[holderId] = true;
    if(this.newVal){
      let data = {
        message: this.newVal,
        cust_id : String(this.livechatcustomerData.id),
        customerId:  String(this.livechatcustomerData.id)
      }
      this.liceChatService.broadcastMessage(data).subscribe({
        next : res =>{
          this.sendingResponse[holderId] = false;
          this.clearVal.emit();
          this.newVal = null;
          this.chatReplyInput.nativeElement.textContent = '';
        },
        error : err => this.sendingResponse[holderId] = false
      })
    }
    if(this.UploadedImages.length){
      this.UploadedImages.forEach(ele =>{
        let data ={
          message : ele,
          cust_id :String(this.livechatcustomerData.id),
          customerId: String(this.livechatcustomerData.id),
          messageType: "image"
        }
        this.liceChatService.broadcastMessage(data).subscribe({
          next : res =>{
            this.sendingResponse[holderId] = false;
            let indexOfEle = this.UploadedImages.indexOf(ele);
            this.UploadedImages.splice(indexOfEle, 1);
          },
          error : err => this.sendingResponse[holderId] = false
        })
      });
    }
  }
  
  openAssignModel(content){
    this.modalService.open(content)
  }
  engageChat(){
    localStorage.setItem('custIdEngaged', JSON.stringify(this.livechatcustomerData));
    
    let data = {
      custId : this.custId,
      users: [this.autoUserInfo]
    }
    this.liceChatService.livechatEngageConversation(data).subscribe({
      next: res =>{    
        if(res?.success){
          this.engaged = true;
          // this.updatemenu.emit(this.custId);
        }
      }
    })
  }
  conversationLeave(id){
    this.liceChatService.livechatConversationleave(id).subscribe({next:res => {
      if(res?.success){
        this.toastr.success(this.translate.transform(res.success));
      }
    }})
  }
  removeUserFromUnread(id){
    this.liceChatService.livechatRemoveUserFromUnread(id).subscribe({next:res => {
      if(res?.success){
        this.toastr.success(this.translate.transform(res.success));
      }
    }})
  }
  conversationUnread(id){
    this.liceChatService.livechatConversationUnread(id).subscribe({next:res => {
      if(res?.success){
        this.toastr.success(this.translate.transform(res.success));
      }
    }})
    localStorage.removeItem('livechatCustomer')
  }
  markAsSolved(id){
    this.liceChatService.livechatMarkSolved(id).subscribe({next:res => {
      if(res?.success){
        this.toastr.success(this.translate.transform(res.success));
        this.router.navigate([`/admin/live-chat/solved-chats`], { queryParams: { id: res?.id } })
      }
    }})
  }
  showcreateTikcte(){
    this.reply = this.newVal;
    this.isChat = false;
  }
  showChat(){
    this.reply = this.newVal;
    this.isChat = true;
  }
  onSelectChange(value){
    let newVal = value.messages?.trim();
    if(newVal == this.newVal) return;
    if(this.chatReplyInput){
      this.chatReplyInput.nativeElement.innerHTML = newVal;
    }
    this.reply = newVal;
    this.newVal = newVal;
    this.modalService.dismissAll();
  }
  onTextareaValueChange(value) {
    this.newVal = value || '';
    this.typingSubject.next(this.newVal);
  }

  fileUploadPermission(event, val){
    let ele = event.target;
    let data = {
      permission : ele.checked,
      custUser : val?.id
    }
    this.liceChatService.livechatLiveChatCustFileupload(data).subscribe({
      next: res =>{
      }
    })
  }
  
  categoryStatus = false;
  category = [];
  subcategory = null;
  projects = null;
  userDetails;
  haspurchasecode = [];
  hassubcategoriess = [];
  hasproject = [];
  envatoName;
  envatoId;
  categorychange(id) {
    this.subcategory = null;
    this.projects = null;
    this.licencekey = '';
    this.licencesupport = null;
    this.envatoName = null;
    this.categoryStatus = true;
    const data = {
      "cat_id": id,
    };
    this.adminService.getCatagoryData(data).subscribe({
      next: (res) => {
        this.categoryStatus = false;
        if (res.ENVATO_ON == 'on') {
          this.haspurchasecode = res.envatosuccess;
        }
        this.hasproject = res.projects;
        this.hassubcategoriess = res.subcategories;
      },
    });
  }
  licencekey;
  licencekeyStatus = false;
  licencesupport = null;
  envatoVerify(event, buttonId) {

    if (event.value?.trim().length == 36) {
      this.envatoId = event.value.trim();
      const data = {
        data: event.value,
      };
      this.adminService.envatoverify(data).subscribe({
        next: (res) => {
          if (res?.valid != 'true') {
            if (this.settings?.ENVATO_EXPIRED_BLOCK == 'on') {
              this.toastr.error(this.translate.transform(res.message));
              this.supportexpired?.nativeElement.classList.remove('d-none');
              this.verifysupportexpired?.nativeElement.classList.add('d-none');
            }
            if (this.settings?.ENVATO_EXPIRED_BLOCK == 'off') {
              this.supportexpired?.nativeElement.classList.remove('d-none');
              this.verifysupportexpired?.nativeElement.classList.add('d-none');

              this.toastr.warning(this.translate.transform(res.message));
              this.licencekey = res.key;
              this.envatoName = res.name;
              this.licencekeyStatus = true;
              this.licencesupport = res.valid;
            }
          }
          if (res?.valid == 'true') {
            this.toastr.success(this.translate.transform(res.message));
            this.envatoName = res.name;
            this.licencekey = res.key;
            this.licencekeyStatus = true;
            this.licencesupport = res.valid;
          }
        },
        error: () => {
        },
      });
    }
  }
  override ngOnDestroy(): void {
    this.settings
    this.custId;
    this.currentDate;
    this.operatorUser;
    this.autoUserInfo;
    this.parsedChatFlowMessages;
    this.chatData;
  }
}
