
import { BsModalService, BsModalRef, ModalOptions } from 'ngx-bootstrap/modal';
import { FileBrowserModalComponent } from '../file-browser-modal/file-browser-modal.component';  // Update the path accordingly
import { AceEditorDirective } from '../ace-editor.directive';
import { MatchService } from '../match.service'
import { Match, PatternResult, MatchedResult} from '../matched-result.model'
import { ActivatedRoute } from '@angular/router';
import { WorkareaService } from '../services/workarea.service';
import { ToastrService } from 'ngx-toastr';
import { SharedService } from '../shared.service';
import { PreviewDialogComponent } from '../preview-dialog/preview-dialog.component';
import { environment } from '../../environments/environment';
import { saveAs } from 'file-saver';
import { DomSanitizer,SafeResourceUrl } from '@angular/platform-browser';
import { HttpClient,HttpParams } from '@angular/common/http';
import { take } from 'rxjs/operators';
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf';
import { NgxSpinnerService } from 'ngx-spinner';
import { PdfViewerComponent } from 'ng2-pdf-viewer';
import {
    Component,
    Input,
    ElementRef,
    ViewChild,
    OnChanges,
    SimpleChanges,
    ChangeDetectorRef,
    AfterViewInit,
    TemplateRef
} from '@angular/core';
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.9.359/pdf.worker.min.js';
@Component({
  selector: 'app-workarea',
  templateUrl: './workarea.component.html',
  styleUrls: ['./workarea.component.css']
})
export class WorkareaComponent implements OnChanges, AfterViewInit {
  @ViewChild(AceEditorDirective,  { static: false }) aceEditorDirective!: AceEditorDirective;
  @ViewChild('canvasContainer', { static: true }) canvasContainer!: ElementRef<HTMLDivElement>;
    @Input() pdfSrc!: string;
    @Input() syncScrollRef: PdfViewerComponent | null = null;
    @Input() isSyncScrollEnabled: boolean = false;
    pdf: any;
    canvasElements = new Map<number, HTMLCanvasElement>();
    private isProgrammaticScroll = false;
    highlightEnabled = true;
    isPdfLoading = false;
    loading = false;
    pdfDoc: any = null;
    currentPage = 1;
    totalPages = 0;
    scale = 1.5;
    gotoPageNumber: number | null = null;
    isDarkMode = false;
    searchQuery: string = '';
    searchMatches: { page: number; text: string; y: number }[] = [];
  matches: Match[] = [];
  matchedResults: MatchedResult[] = []; // Store matched results
  xmlContent = '';
  private apiUrl = `${environment.apiUrl}/WorkAreaApi`;
 // colspan = '6';
  token: any;
  userid: any;
  transid: any;
  pdid: any;
  enviroment: any;
  serverappUrl = environment.serverappUrl;
  p_option: string;  
  urlSafe: SafeResourceUrl;
  loginuserid = 0;
  p_tranid = 0;
  batchid = 0;
  project_subtitle: string;
  jobtitle: string;
  lottitle: string;
  stagename_alias: string;
  jobid: number;
  lotid: number;
  serverpath : string;
  movebackstage: any;
  entity: any;
  fileName:string;
  checkoutAppDetails: any;
  ddlLotListTypeSettings: {};
  mergedlot: number;
  appname: string;
pdfrl: string;
  selectedLotId: string;
  config: ModalOptions = {
    backdrop: 'static',
    keyboard: false,
    animated: true,
    class: 'modal-dialog-centered',
    ignoreBackdropClick: true
  };

  modalRef: BsModalRef;
  workAreaPopUpModalRef: BsModalRef;
  downloadPopUpModalRef: BsModalRef;
  showdownload = true;

  comments: string;
  comments_header: string;
  buttonType: string;
  calltype: string;
  procomment: any;
  itemData: any;
  cflag = '';
  selback = '';
  projectdefnitionid = 0;
  tranid: number;

  lotlist_output = [];
  lotlist = [];
 // lotlistTmp = [];
 // lotlist_filter = [];
  uniqueStageTitles = [];
  lot_comments = [];
islot=true;
  FileOutList: any = [];
  xFileInList: any = [];
  xFileOutList: any = [];
  infilesactive = true;
  outfilesactive = false;
  //@ViewChild('leftColumn', { static: false }) leftCol!: ElementRef;
  //@ViewChild('rightColumn', { static: false }) rightCol!: ElementRef;
  isProcessing: boolean = false;
  loadingIndex: number | null = null;
  searchText = '';
  zoomLevel = 100;
  //isLoading: boolean = false; 

  expandedRows: Set<number> = new Set<number>();
 
  editorData = '<strong>angular 8 and ckeditor 4 with ngModel</strong><p>Some initial data</p>';
  
  ckeConfig = {
    allowedContent: false,
    forcePasteAsPlainText: true,
    font_names: 'Arial;Times New Roman;Verdana',
    toolbarGroups: [
      { name: 'document', groups: ['mode', 'document', 'doctools'] },
      { name: 'clipboard', groups: ['clipboard', 'undo'] },
      { name: 'editing', groups: ['find', 'selection', 'spellchecker', 'editing'] },
      { name: 'forms', groups: ['forms'] },
      '/',
      { name: 'basicstyles', groups: ['basicstyles', 'cleanup'] },
      { name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align', 'bidi', 'paragraph'] },
      { name: 'links', groups: ['links'] },
      { name: 'insert', groups: ['insert'] },
      '/',
      { name: 'styles', groups: ['styles'] },
      { name: 'colors', groups: ['colors'] },
      { name: 'tools', groups: ['tools'] },
      { name: 'others', groups: ['others'] },
      { name: 'about', groups: ['about'] }
    ],
    removeButtons: 'Source,Save,NewPage,Preview,Print,Templates,Cut,Copy,Paste,PasteText,PasteFromWord,Undo,Redo,Find,Replace,SelectAll,Scayt,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,Strike,Subscript,Superscript,CopyFormatting,RemoveFormat,Outdent,Indent,CreateDiv,Blockquote,BidiLtr,BidiRtl,Language,Unlink,Anchor,Image,Flash,Table,HorizontalRule,Smiley,SpecialChar,PageBreak,Iframe,Maximize,ShowBlocks,About'
  };
  
  //previewResults: any[] = [];
  previewResults: MatchedResult
  pdfPaths: string[] = [];
  lotTitles: string[] = [];
  doctype: { id: number; val: string }[] = [];
  formattedLotTitles: string = '';
  reportid: string;
 
  constructor(private modalService: BsModalService,private cdr: ChangeDetectorRef,private sanitizer: DomSanitizer, private route: ActivatedRoute, private workareaservice: WorkareaService,   private toastr: ToastrService, private matchService: MatchService, private sharedService: SharedService,private SpinnerService: NgxSpinnerService,    private http: HttpClient

  ) { }
  ngAfterViewInit(): void {
        this.canvasContainer.nativeElement.addEventListener('scroll', this.onScroll.bind(this));
    }

  ngOnInit(): void {
    this.route.params.subscribe(params => {
      this.token = params['token'];
      this.loginuserid = +params['userid'];
      this.p_tranid = +params['transid'];
      this.pdid = +params['pdid'];
      this.enviroment = params['enviroment'];   
    });

    this.getcurrentjobdetails();    

    this.matchService.matches$.subscribe(matches => {   
      this.matchedResults = matches;       
    });

    this.sharedService.setProjectDefinitionId(this.pdid)
  }  
 ngOnChanges(changes: SimpleChanges): void {
        if (changes['pdfSrc'] && this.pdfSrc) {
            this.loadPdf(this.pdfSrc);
        }
    }


async loadPdf(url: string) {
  debugger;
   this.fileName = this.getFileNameFromUrl(url);
  console.log('File name extracted:', this.fileName);
    this.isPdfLoading = true;
    try {
        this.pdfDoc = await pdfjsLib.getDocument({ url }).promise;
        //this.fitToWidth();
        this.totalPages = this.pdfDoc.numPages;
        this.currentPage = 1;
        await this.renderAllPages();
    } catch (error) {
        console.error('Error loading PDF:', error);
    } finally {
        this.isPdfLoading = false;
        this.cdr.detectChanges();
    }
}


observePages() {
  const observer = new IntersectionObserver(async (entries) => {
    for (const entry of entries) {
      if (entry.isIntersecting) {
        const pageNum = parseInt(entry.target.id.replace("page-", ""), 10);
        const alreadyRendered = entry.target.getAttribute("data-rendered");
        if (!alreadyRendered) {
          await this.renderPage(pageNum);
          entry.target.setAttribute("data-rendered", "true");
        }
      }
    }
  }, { root: null, rootMargin: "100px", threshold: 0.1 });

  for (let i = 1; i <= this.totalPages; i++) {
    const el = document.getElementById(`page-${i}`);
    if (el) observer.observe(el);
  }
}
async renderPage(pageNum: number) {
  const page = await this.pdfDoc.getPage(pageNum);

  const scale = 1.0; // adjust for faster rendering
  const viewport = page.getViewport({ scale });

  const canvas: HTMLCanvasElement = document.createElement("canvas");
  const context = canvas.getContext("2d")!;
  canvas.height = viewport.height;
  canvas.width = viewport.width;

  const renderContext = { canvasContext: context, viewport };
  await page.render(renderContext).promise;

  const container = document.getElementById("pdf-container");
  container!.innerHTML = ""; // clear previous page
  container!.appendChild(canvas);
}



// Utility method to extract filename
getFileNameFromUrl(url: string): string | null {
  try {
    const urlObj = new URL(url);
    const pathParam = urlObj.searchParams.get('path');
    if (!pathParam) return null;

    const decodedPath = decodeURIComponent(pathParam);
    const parts = decodedPath.split('\\');
    let fileName = parts[parts.length - 1];

    // Remove .pdf extension if present (case insensitive)
    if (fileName.toLowerCase().endsWith('.pdf')) {
      fileName = fileName.slice(0, -4);
    }

    return fileName;
  } catch (error) {
    console.error('Invalid URL:', error);
    return null;
  }
}
// Start with one empty row
// Start with one row
// Start with one row
// Initialize data with unique ID
// Initial table data
// Initial table data
// Initial table data
tableData = [
  { id: this.generateId(), report: '', volume: '', edition: '', issue: '', range: '', printpage: '' }
];

// Generate unique IDs
generateId(): string {
  return Math.random().toString(36).substr(2, 9);
}

// Add new blank row (no auto report/issue)
addRow() {
  const newRow = {
    id: this.generateId(),
    report: '',
    volume: '',
    edition: '',
    issue: '',
    range: '',
    printpage: ''
  };
  this.tableData.push(newRow);
}

// Remove a row
removeRow(index: number) {
  if (this.tableData.length > 1) {
    this.tableData.splice(index, 1);
  }
}

// Copy row and increment issue suffix
copyRow(index: number) {
  const rowToCopy = this.tableData[index];

  const baseIssue = this.getBaseIssue(rowToCopy.printpage);
  const currentSuffix = this.getIssueSuffix(rowToCopy.printpage);
  const nextSuffix = this.incrementSuffix(currentSuffix);

  const newRow = {
    id: this.generateId(),
    report: rowToCopy.report, // copy as-is
    volume: rowToCopy.volume,
    edition: rowToCopy.edition,
    issue:rowToCopy.issue,
    //issue: baseIssue ? `${baseIssue} ${nextSuffix}` : '', // if no base, keep blank
    range: rowToCopy.range,
printpage: rowToCopy.printpage? `${baseIssue} ${nextSuffix}` : ''
  };

  this.tableData.splice(index + 1, 0, newRow);
}

// Extract base issue (e.g., "Issue" from "Issue a")
getBaseIssue(printpage: string): string {
  return printpage.split(' ')[0] || '';
}

// Extract suffix (e.g., "a" from "Issue a")
getIssueSuffix(printpage: string): string {
  const parts = printpage.split(' ');
  return parts.length > 1 ? parts[1] : '';
}

// Increment suffix: '' → 'a', 'a' → 'b', ..., 'z' → 'aa', etc.
incrementSuffix(suffix: string): string {
  if (!suffix) return 'a';

  let num = 0;
  for (let i = 0; i < suffix.length; i++) {
    num = num * 26 + (suffix.charCodeAt(i) - 96); // 'a' = 1
  }

  num++; // increment

  let str = '';
  while (num > 0) {
    num--;
    str = String.fromCharCode(97 + (num % 26)) + str;
    num = Math.floor(num / 26);
  }

  return str;
}

// zoomIn() {
//   if (this.zoomLevel < 500) { // max 500%
//     this.zoomLevel += 10; // increase by 10%
//   }
// }

// zoomOut() {
//   if (this.zoomLevel > 10) { // min 10%
//     this.zoomLevel -= 10; // decrease by 10%
//   }
// }

download() {
  fetch(this.pdfrl)
    .then(response => response.blob())
    .then(blob => {
      const blobUrl = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = blobUrl;
      link.download = this.fileName || 'download.pdf';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(blobUrl);
    })
    .catch(err => console.error('Download failed', err));
}


  async renderAllPages() {
        const container = this.canvasContainer.nativeElement;
        container.innerHTML = '';

        for (let i = 1; i <= this.totalPages; i++) {
            const page = await this.pdfDoc.getPage(i);
            const viewport = page.getViewport({ scale: this.scale });

            const canvas = document.createElement('canvas');
            const context = canvas.getContext('2d')!;
            canvas.height = viewport.height;
            canvas.width = viewport.width;
            canvas.setAttribute('data-page-number', i.toString());

            await page.render({ canvasContext: context, viewport }).promise;
            container.appendChild(canvas);
        }

        this.cdr.detectChanges();
    }

   prevPage(): void {
        if (this.currentPage > 1) {
            this.currentPage--;
            this.gotoPageNumber = this.currentPage; // ✅ sync
            this.scrollToPage(this.currentPage);
        }
    }

    nextPage(): void {
        if (this.currentPage < this.totalPages) {
            this.currentPage++;
            this.gotoPageNumber = this.currentPage; // ✅ sync
            this.scrollToPage(this.currentPage);
        }
    }

 async zoomIn() {
  if (this.zoomLevel < 500) { // max 500%
     this.zoomLevel += 10; // increase by 10%
   }
        this.scale += 0.25;
        await this.renderAllPages();
    }

    async zoomOut() {
        if (this.scale > 0.5) {
            this.scale -= 0.25;
            if (this.zoomLevel > 10) { // min 10%
     this.zoomLevel -= 10; // decrease by 10%
   }
            await this.renderAllPages();
        }
    }

  scrollToPage(page: number): void {
        const container = this.canvasContainer.nativeElement;
        const canvases = container.querySelectorAll('canvas');

        if (page >= 1 && page <= canvases.length) {
            const targetCanvas = canvases[page - 1];
            if (targetCanvas) {
                // scroll only inside canvas container, not whole page
                container.scrollTo({
                    top: targetCanvas.offsetTop,
                    behavior: 'smooth'
                });
            }
        }
    }
    onScroll(): void {
        const container = this.canvasContainer.nativeElement;
        const canvases = container.querySelectorAll('canvas');
        const containerTop = container.scrollTop;

        let closestPage = 1;
        let minDistance = Infinity;

        canvases.forEach((canvas, index) => {
            const offsetTop = (canvas as HTMLElement).offsetTop;
            const distance = Math.abs(offsetTop - containerTop);
            if (distance < minDistance) {
                minDistance = distance;
                closestPage = index + 1;
            }
        });

        if (this.currentPage !== closestPage) {
            this.currentPage = closestPage;
            this.gotoPageNumber = closestPage;
            this.cdr.detectChanges();
        }

       // 🔁 Sync scroll only if enabled and not triggered programmatically
        // if (this.isSyncScrollEnabled && this.syncScrollRef && !this.isProgrammaticScroll) {
        //     const ratio = container.scrollTop / (container.scrollHeight - container.clientHeight);
        //     const target = this.syncScrollRef.canvasContainer.nativeElement;
        //     const syncedTop = ratio * (target.scrollHeight - target.clientHeight);
        //     this.syncScrollRef.setScrollPosition(syncedTop);
        // }
    }
  //  setScrollPosition(position: number): void {
  //       this.isProgrammaticScroll = true;
  //       this.canvasContainer.nativeElement.scrollTop = position;

  //       requestAnimationFrame(() => {
  //           this.isProgrammaticScroll = false;
  //       });
  //   }

    goToPage(): void {
        debugger;
        if (
            this.gotoPageNumber &&
            this.gotoPageNumber >= 1 &&
            this.gotoPageNumber <= this.totalPages
        ) {
            this.currentPage = this.gotoPageNumber;
            this.scrollToPage(this.gotoPageNumber);
        }
    }

downloadPdf() {
  debugger;
if (!this.pdfrl) return;

        if (!this.pdfrl) return;

        // Function to extract filename from URL
        const extractFilename = (url: string): string => {
            try {
                const pathname = new URL(url, window.location.href).pathname;
                const name = pathname.substring(pathname.lastIndexOf('/') + 1);
                return name || 'document.pdf';
            } catch {
                return 'document.pdf';
            }
        };

        const filename = extractFilename(this.pdfrl);

        // Handle blob or full URLs
        if (
            this.pdfrl.startsWith('blob:') ||
            this.pdfrl.startsWith('http') ||
            this.pdfrl.startsWith('data:')
        ) {
            const a = document.createElement('a');
            a.href = this.pdfrl;
            a.download = filename;
            a.click();
        } else {
            // Handle relative path (like 'assets/sample.pdf')
            fetch(this.pdfrl)
                .then(response => response.blob())
                .then(blob => {
                    const blobUrl = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = blobUrl;
                    a.download = filename;
                    a.click();
                    URL.revokeObjectURL(blobUrl);
                })
                .catch(err => console.error('Download failed', err));
        }
    }

    setHighlighting(enabled: boolean): void {
        this.highlightEnabled = enabled;
        this.renderAllPages(); // re-render pages with or without highlights
    }

    updateView(): void {
        this.renderAllPages();
        this.scrollToPage(this.currentPage);
    }
    resetZoom(): void {
        this.scale = 1.5; // or your default zoom level
        this.renderAllPages();
    }
    fitToWidth(): void {
        const container = this.canvasContainer.nativeElement;
        const width = container.clientWidth;

        // Temporary page to calculate required scale
        this.pdfDoc.getPage(1).then((page: any) => {
            const viewport = page.getViewport({ scale: 1 });
            const scale = width / viewport.width;

            this.scale = parseFloat(scale.toFixed(2));
            this.renderAllPages();
        });
    }
    fitToPage(): void {
        const container = this.canvasContainer.nativeElement;
        const height = container.clientHeight;

        this.pdfDoc.getPage(1).then((page: any) => {
            const viewport = page.getViewport({ scale: 1 });
            const scale = height / viewport.height;

            this.scale = parseFloat(scale.toFixed(2));
            this.renderAllPages();
        });
    }
    oggleDarkMode(): void {
        this.isDarkMode = !this.isDarkMode;

        const container = this.canvasContainer.nativeElement;
        container.style.backgroundColor = this.isDarkMode ? '#1e1e1e' : '#ffffff';

        // Apply invert filter to canvases
        const canvases = container.querySelectorAll('canvas');
        canvases.forEach(canvas => {
            (canvas as HTMLElement).style.filter = this.isDarkMode ? 'invert(1)' : 'invert(0)';
        });
    }
    printPdf(): void {
        const printWindow = window.open(this.pdfSrc, '_blank');
       if (printWindow) {
  printWindow.addEventListener('load', () => {
    printWindow.print();
  });
}
    }
    toggleDarkMode(): void {
        this.isDarkMode = !this.isDarkMode;

        const container = this.canvasContainer.nativeElement;

        // Set background color of container
        container.style.backgroundColor = this.isDarkMode ? '#1e1e1e' : '#ffffff';

        // Apply invert filter to all canvases inside the viewer
        const canvases = container.querySelectorAll('canvas');
        canvases.forEach((canvas: Element) => {
            (canvas as HTMLElement).style.filter = this.isDarkMode ? 'invert(1) hue-rotate(180deg)' : 'invert(0)';
        });
    }
async onSearch(query: string) {
  debugger
  this.searchQuery = query.trim();
  this.searchMatches = [];

  if (!this.searchQuery || !this.pdfDoc) {
    this.highlightMatches(); // clear highlights
    return;
  }

  for (let pageNum = 1; pageNum <= this.totalPages; pageNum++) {
    const page = await this.pdfDoc.getPage(pageNum);
    const textContent = await page.getTextContent();

    textContent.items.forEach((item: any) => {
      const str = item.str || '';
      if (str.toLowerCase().includes(this.searchQuery.toLowerCase())) {
        this.searchMatches.push({ page: pageNum, text: str, y: item.transform[5] });
      }
    });
  }

  this.highlightMatches();
}

highlightMatches() {
  const query = (this.searchQuery || '').toLowerCase().trim();

  //const query = this.searchQuery?.toLowerCase().trim();
  if (!query) {
    // Clear previous highlights
    document.querySelectorAll('.textLayer div').forEach(div => {
      const el = div as HTMLElement;
      el.innerHTML = el.textContent || '';
    });
    return;
  }

  document.querySelectorAll('.textLayer div').forEach(div => {
    const el = div as HTMLElement;
    const text = el.textContent || '';

    const regex = new RegExp(`(${query})`, 'gi'); // case-insensitive global match
    if (regex.test(text)) {
      el.innerHTML = text.replace(regex, `<span class="highlight">$1</span>`);
    } else {
      el.innerHTML = text;
    }
  });
}




 escapeHtml(text: string): string {
  return text
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}




    //kiruthiga
  getServerPath() {     
    this.workareaservice.ServerPath(this.p_tranid.toString(), this.token).subscribe(
      (path: string) => {
        this.serverpath = path;
        this.sharedService.setServerPath(this.serverpath);      
      },
      (error) => {
        console.error('Error fetching server path', error);
      }
    );
  }
  
    getRepoterKey() {
      debugger;     
  this.workareaservice.getreporterkey(this.jobtitle, this.jobid, this.token).subscribe(
    (res: any) => {
      debugger;
      this.reportid = res.reporterId;   // ✅ get reporterId from API response
      //this.sharedService.setServerPath(res.reporterKey); // if you want to save reporterKey
    },
    (error) => {
      console.error('Error fetching reporter key', error);
    }
  );
}


  
  savestage() {
    debugger;
    if (this.isProcessing) {
      debugger;
      console.log('Click ignored: Request already in progress.');
      return;
    }
    const params = new HttpParams()
      .set('transactionId', this.tranid.toString())
      .set('userId', this.loginuserid.toString())
      .set('env', this.enviroment)
      .set('action', 'open');

    const url = `http://localhost:60024/`;
    this.isProcessing = true;
    this.http.get<any>(url, { params })
      .pipe(take(1))
      .subscribe(
       
        response => {
          debugger;
          
         
          console.log('Tool opened successfully:', response);
          this.isProcessing = false; // Re-enable after success
        },
        error => {
          debugger;
          this.getanlysisfile();
          console.error('Error occurred:', error);
          this.isProcessing = false; // Re-enable after failure
        }
      );
  }
  getanlysisfile() {
debugger;

    

      this.workareaservice.getanalysisfile(this.p_tranid.toString(),this.lotid.toString(),this.loginuserid.toString() ,this.token).subscribe(
        (path: string) => {
           
        },
        (error) => {
          console.error('Error fetching server path', error);
        }
      );
    


  }
  getcurrentjobdetails() {      
    this.p_option = 'getlotdata';
    const inputvalue = [];
    inputvalue.push(
    {
        p_tranid: this.p_tranid.toString(),
        p_userid: this.loginuserid.toString(),
        p_option: this.p_option
    });
    
    this.workareaservice.usrstagemove(inputvalue[0], this.token).subscribe(res => {  
      debugger;  
        const resData = JSON.parse(res.body[0]);    
        this.checkoutAppDetails = resData;          
        this.jobtitle = resData.jobtitle;
        this.lottitle = resData.lottitle;     
        this.project_subtitle = resData.projecttitle;       
        this.stagename_alias = resData.stagename;  
        this.tranid = resData.transactionid;
        this.jobid = resData.jobid;
        this.lotid = resData.lotid;
         this.batchid = resData.batchid;
        this.movebackstage = resData.movebackstage;
        this.mergedlot = resData.merged_lot;
        this.entity = resData.jobmetafields;
        this.projectdefnitionid = resData.projectdefinitionid;
       
        this.sharedService.setTransactionId(this.p_tranid.toString());
        this.sharedService.setJobId(this.jobid.toString());
        this.sharedService.setToken(this.token.toString());
        this.sharedService.setFileName(resData.filename);
        this.appname = resData.appname;
        this.getServerPath();
        this.getRepoterKey();
        this.XmlReviewQC(this.p_tranid.toString(), this.jobid.toString(),this.batchid.toString(),this.islot);

        debugger;
       
    }, (error) => {         
      debugger;
      this.toastr.error('Error while getting data');
    });
  }

  getlottitles(jobid:string){
debugger;
    
this.workareaservice.GetLotTitles(jobid).subscribe(
  (result: any[]) => {
    debugger;
    this.lotTitles = result; // Array of lot titles
    this.selectedLotId = (this.lotTitles[0] as any).lotid;
this.XmlReviewQC(this.p_tranid.toString(), this.jobid.toString(),this.selectedLotId,this.islot);
  },
  (error) => {
    console.error('Error fetching lot titles:', error);
  }
);
debugger;
this.doctype = [
  { id: 0, val: 'txt' },
    { id: 1, val: 'img' },
 
];


  }


  onFieldChange(
    lotid: number,
    mainPage: string,
    //supplementRange: string,
    docType: string,
    field: string
  ): void {


    const payload = {
      JobId: this.jobid,  // Ensure you store the jobId somewhere in your component
      LotId: lotid,
      MainPage: mainPage,
      //SupplementPage: supplementRange,
      DocType: parseInt(docType),
      Mode:field,
      UpdatedBy: this.loginuserid // or however you track the user
    };
  debugger;
    this.workareaservice.InsertlotPageDetails(payload, this.token).subscribe({
      next: () => {
        debugger;
        this.toastr.success('Saved successfully.');
      },
      error: (err) => {
        console.error('Insert failed:', err);
        this.toastr.error('Failed to save.');
      }
    });
  }
  
  


//   onUpdate(lotid: number, mainPage: string, pageCount: string, docType: string) {
// debugger;
// const body = {
//   lotId: lotid,
//   jobId: this.jobid,
//   mainPage: parseInt(mainPage),              // 👈 convert to number
//   supplementPage: parseInt(pageCount),       // 👈 convert to number
//   docType: docType,
//   updatedBy: this.loginuserid
// };


// console.log('Sending body to API:', body); // ✅ Confirm values here

// this.workareaservice.InsertlotPageDetails(body, this.token).subscribe(res => {
//   this.toastr.success('Saved successfully.');
// });

    
//   }

// XmlReviewQC(tranid: string, jobid: string, lotid: string, islot: boolean) {
//   this.workareaservice.XmlReviewQC(tranid, jobid, lotid, islot, this.token)
//     .subscribe((results: any) => {
//       this.pdfPaths = results.map((result: any) => {
//         const encodedPath = encodeURIComponent(result.filePath);
//         const url = `${this.apiUrl}/PreviewPdf?path=${encodedPath}`;
//         this.loadPdf(this.url);
//         return this.sanitizer.bypassSecurityTrustResourceUrl(url);
//       });
//     }, error => {
//       console.error('Error fetching PDF paths:', error);
//     });
// }

// Define a structure to hold both
pdfUrlObjects: { rawUrl: string, sanitizedUrl: any }[] = [];

XmlReviewQC(tranid: string, jobid: string, lotid: string, islot: boolean) {
  debugger;
  this.workareaservice.XmlReviewQC(tranid, jobid, lotid, islot, this.token)
    .subscribe((results: any) => {
      debugger;
      this.pdfUrlObjects = results.map((result: any) => {
        debugger;
        const encodedPath = encodeURIComponent(result.filePath);
        const url = `${this.apiUrl}/PreviewPdf?path=${encodedPath}`;
        this.pdfrl=url;
        // Store raw URL and sanitized URL separately
        return {
          rawUrl: url,
          sanitizedUrl: this.sanitizer.bypassSecurityTrustResourceUrl(url)
        };
      });

      // Load the first PDF using the raw URL
      if (this.pdfUrlObjects.length > 0) {
        this.loadPdf(this.pdfUrlObjects[0].rawUrl);
      }
    }, error => {
      console.error('Error fetching PDF paths:', error);
    });
}

  // XmlReviewQC(tranid: string, jobid : string,lotid : string,islot:boolean) {  
  //   debugger;
  //   //this.isLoading = true;    
  //   this.workareaservice.XmlReviewQC(tranid, jobid,lotid,islot, this.token)
  //     .subscribe((results: any) => {
  //       debugger;
        
  //       this.pdfPaths = results.map(result => {
  //         debugger;
  //         const encodedPath = encodeURIComponent(result.filePath);
  //         //const url = `https://localhost:44300/api/WorkAreaApi/PreviewPdf?path=${encodedPath}`;
  //         const url = `${this.apiUrl}/PreviewPdf?path=${encodedPath}`;

  //         return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  //       });
        
        
          
        
  //       // Assuming the result is an array of objects with 'path' property
       
  //     },
  //     (error) => {       
  //       //console.error('Error fetching data:', error);   
  //       //this.isLoading = false; // Stop loader when data is received       
  //     }
  //   );
  // }
  
  openFileBrowserModal() {
    // Reset the results and editor while open file browser window
 //   this.matchedResults = [];
    this.aceEditorDirective.appAceEditor = "";

    // Open the FileBrowserModalComponent when the button is clicked
    this.modalRef = this.modalService.show(FileBrowserModalComponent, {
      initialState: { token: this.token },
      backdrop: true,  // If true, clicking outside the modal will close it
      class: 'modal-lg',  // Add 'modal-lg' to make the modal large
      animated: true,     // Adds animation for opening the modal
    });
  }

  loadFileContent(index: number): void {
    this.loadingIndex = index;
    this.aceEditorDirective.appAceEditor = "";

    setTimeout(() => {
      
      const matchedResult = this.matchedResults[index];
      this.xmlContent = matchedResult.content;
    
     // Load the file content into the ACE editor
      this.aceEditorDirective.appAceEditor = this.xmlContent;
    
     // Highlight the patterns
      this.highlightPattern(matchedResult.patternResults);
      // Your existing logic to load the file content
      console.log('Loading file content for:', this.matchedResults[index].fileName);
  
      // Reset the loading state after content is loaded
      this.loadingIndex = null;
    }, 1000);

  
  }  
  
  highlightPattern(patternResults: PatternResult[]) {
      // Clear previous highlights before adding new ones
    this.aceEditorDirective.clearMarkers(); 
    this.aceEditorDirective.highlightMatch(patternResults);
  }

  previewChanges(index: number) {       
    const matchedResult = this.matchedResults[index];   
     // Open modal to display preview    
     this.modalRef = this.modalService.show(PreviewDialogComponent, {
      initialState: { previewResults: matchedResult },
      class: 'modal-xl'
    });   
  }

  toggleRow(index: number): void {
    if (this.expandedRows.has(index)) {
      this.expandedRows.delete(index); // Collapse
    } else {
      this.expandedRows.add(index); // Expand
    }
  }

  completeStage(cFlag, template: TemplateRef<any>) {  
    if (this.entity !== null) {
    }
    this.comments_header = 'Comments';
    if (cFlag === 'B') {
      this.buttonType = 'Correction';
    } else {
      this.buttonType = 'Complete';
    }
    this.comments = this.buttonType + ' Comments';
    this.calltype = 'checkout';
    this.itemData = this.checkoutAppDetails;
    this.cflag = cFlag;
    this.workAreaPopUpModalRef = this.modalService.show(template, this.config);
    const aa = document.getElementsByClassName('modal-content');
    aa[0].classList.remove('modal-content');
    this.ddlLotListTypeSettings = {
      singleSelection: false,
      idField: 'lotid',
      textField: 'title',
      selectAllText: 'Select All',
      unSelectAllText: 'UnSelect All',
      itemsShowLimit: 7,
      allowSearchFilter: true
    };
    this.loadJobDetails();

    //this.getChecklistDetail(this.p_tranid,' '); 
  }

  loadJobDetails() {    
    this.lotlist_output = [];
    this.lotlist = [];
   // this.lotlist_filter = [];
    let lotid_lot = 0;
    if (this.mergedlot === 0) {
      lotid_lot = this.lotid;
    }
    const inputData = [];
    inputData.push({
      jobid: this.jobid,
      lotid: lotid_lot,
      projectdefinitionid: this.projectdefnitionid
    })
    this.workareaservice.getJobDetails(inputData[0], this.token).subscribe(res => {
      if (res.body[0] !== undefined && res.body[0] !== null && JSON.parse(res.body[0]).length > 0) {
        this.lotlist = JSON.parse(res.body[0]);
        if (this.mergedlot === 0) {
          this.lotlist.forEach((i, ind) => {
            if (i.lotid === this.lotid) {
              i.ticked = true;
            } else {
              i.ticked = false;
            }
          });
        }
       // this.lotlistTmp = this.lotlist.map(t => ({ lotid: t.lotid, title: t.title }));

      }
      if (res.body[1] !== undefined && res.body[1] !== null && JSON.parse(res.body[1]).length > 0) {      
        this.uniqueStageTitles = this.getUniqueStages(JSON.parse(res.body[1]));

      }
      if (res.body[3] !== undefined && res.body[3] !== null && JSON.parse(res.body[3]).length > 0) {
        this.lot_comments = JSON.parse(res.body[3]);
      }
      if (this.buttonType === 'Hold') {
        this.selback = this.itemData.jobworkflowid.toString();
      } else {
        this.selback = this.itemData.nextstage.toString();
      }
    }, err => { this.toastr.error('Loading Lot detail failed.'); });

  }

  getUniqueStages(stages: any[]): any[] {
    return stages.filter(
      (stage, index, self) =>
        index === self.findIndex((t) => t.jobworkflowid === stage.jobworkflowid)
    );
  }

  fillChecklist() {  
    this.add();
  }

   // method to save the hold or complete stage
   add() {
    let entity_temp = null;
    if (this.entity !== null) {
    }
    if (this.procomment === null) {
      this.procomment = '';
    }
    if ((this.stagename_alias === 'XML Correction') && this.calltype === 'checkout') {
    } else {
      let fields = {
        transid: this.itemData.transactionid, fields: JSON.stringify(entity_temp),
        option: this.calltype, cflag: this.cflag, userid: this.loginuserid
      };     
      let fileData = new FormData();     
      fileData.append('model', JSON.stringify(fields));
      fileData.append('tostage', this.selback);
      fileData.append('jobid', this.itemData.jobid);
      fileData.append('comment', this.procomment);
      if (this.itemData.merged_lot === '1') {
        fileData.append('batchid', this.itemData.lotid);
      } else {
        fileData.append('batchid', '');
        fileData.append('lotid', this.itemData.lotid);
      }
      this.workareaservice.PostUpdateLotTransaction(fileData, this.token).subscribe(res => {        
        if (res.body !== undefined && res.body !== null) {
          //debugger;
         // this.load_tool = '1';
          this.toastr.success('Saved successfully.');
          top.location.href = this.serverappUrl + '/dashboard';
          this.workAreaPopUpModalRef.hide();
        }
      }, err => { this.toastr.error('Error in Start App details'); });

    }
  }

  downloadPopUp(template: TemplateRef<any>, jobid) {
    debugger;
    this.comments_header = 'Download';
    this.comments = 'Stage based Download';
    this.downloadPopUpModalRef = this.modalService.show(template, this.config);
    this.GetInOutFiles();
  }

  GetInOutFiles() {
    this.workareaservice.GetAllFilesForDownload(this.jobid, this.tranid).subscribe(res => {    
      if (res !== undefined && res !== null) {
        debugger;
        this.xFileInList = res;
        console.log(this.xFileInList);
      } else {
        this.xFileInList = [];
      }
    });
    this.workareaservice.GetAllOutputFiles(this.jobid, this.tranid).subscribe(res => {
      if (res !== undefined && res !== null) {
        debugger;
        this.xFileOutList = res;
        console.log(this.xFileOutList);
      } else {
        this.xFileOutList = [];
      }
    });
  }

  selectTab(type) {
    if (type === 'infiles') {
      this.infilesactive = true;
      this.outfilesactive = false;

    }
    if (type === 'outfiles') {
      this.infilesactive = false;
      this.outfilesactive = true;

    }
  }

downloadIndividualFiles(type: string, filepath: string, filename: string) {
  const fileData = { type, path: filepath, jobid: +this.jobid };

  this.workareaservice.DownloadSingleFile(fileData).subscribe({
    next: (res) => {
      if (res.body) {
        const contentType = res.headers.get('Content-Type') || 'application/octet-stream';
        const blob = new Blob([res.body], { type: contentType });
        saveAs(blob, filename); // FileSaver.js
      } else {
        this.toastr.error('Empty response');
      }
    },
    error: (err) => {
      console.error('Download error:', err);
      this.toastr.error('File not found or access denied');
    }
  });
}


  downloadInOutFiles(type, tranid, option) {
    let fileData: any = [];
    fileData.push({
      'jobid': this.jobid, 'tranid': this.tranid, 'pdid': this.pdid, 'option': option, 'jobtitle': this.jobtitle
    });
    this.workareaservice.DownloadInOutFiles(fileData[0]).subscribe(res => {
      var content = res.body.file;
      let objectURL = 'data:application/octet-stream;base64,' + res.body.file;
      saveAs(objectURL, this.jobtitle + '_' + this.tranid + '_' + option + '.zip');
      //this.SpinnerService.hide();
    },
      error => {
        this.toastr.error('File not found');
        // this.SpinnerService.hide();
      });
  }
  downloadIndividualOutFiles(type, filepath, filename) {
    let fileData: any = [];
    fileData.push({
      'type': type, 'path': filepath, 'jobid': this.jobid
    });
    this.workareaservice.DownloadSingleOutFile(fileData[0])
      .subscribe(res => {
        var content = res.body.file;
        let objectURL = 'data:application/octet-stream;base64,' + res.body.file;
        saveAs(objectURL, filename);
        // this.SpinnerService.hide();
      },
        error => {
          this.toastr.error('File not found');
          // this.SpinnerService.hide();
        });
  }
  RemovingIOFiles(filepath) {
    let fileData: any = [];
    fileData.push({
      'path': filepath, 'jobid': this.jobid
    });
    this.workareaservice.RemoveIOFiles(fileData[0]).subscribe(res => {
      if (res.body !== undefined && res.body !== null) {
        if (res.body.result === true) {
          this.toastr.success('File removed sucessfully');
          this.GetInOutFiles();
          this.getallOutFiles();
        }
        else {
          this.toastr.error('File not removed');
        }
      }
    }, err => { console.log(err); });
  }

  getallOutFiles() {
    this.workareaservice.GetAllOutFilesForDownload(this.jobid, this.tranid).subscribe(res => {
      if (res !== undefined && res !== null) {
        this.FileOutList = res;
      }
    });
  }
 holdStage(template: TemplateRef<any>) {
    debugger;
    this.comments = 'Hold Comments';
    this.comments_header = 'Comments';
    this.buttonType = 'Hold';
    this.calltype = 'hold';
    this.itemData = this.checkoutAppDetails;
    console.log('test');
    console.log(this.itemData);
    this.workAreaPopUpModalRef = this.modalService.show(template, this.config);
    const aa = document.getElementsByClassName('modal-content');
    aa[0].classList.remove('modal-content');
    this.ddlLotListTypeSettings = {
      singleSelection: false,
      idField: 'lotid',
      textField: 'title',
      selectAllText: 'Select All',
      unSelectAllText: 'UnSelect All',
      itemsShowLimit: 7,
      allowSearchFilter: true
    };
    this.loadJobDetails();
  }



clearHighlights() {
  const highlights = document.querySelectorAll('.textLayer div');
  highlights.forEach(div => {
    (div as HTMLElement).style.backgroundColor = '';
    (div as HTMLElement).style.color = '';
  });
}


saveTableData() {
  debugger;
   this.loading = true;
  this.SpinnerService.show();
  const payload = this.tableData.map(row => ({
    jobId: this.jobid,
    //userid:this.loginuserid,
    //lotid:this.selectedLotId,
    //lotId: row.lotId !== undefined && row.lotId !== null ? row.lotId : null,
    report: this.reportid.toString(),
    volume: row.volume,
    edition: row.edition,
    issue: row.issue,
    range: row.range,
    printpage: row.printpage
  }));

  this.workareaservice.saveLots(payload).subscribe(res => {
     this.loading = false;
      this.SpinnerService.hide();
    alert(res.message);  // "All lots and transactions saved successfully!"
  }, err => {
    console.error(err);
       this.loading = false;
      this.SpinnerService.hide();
    alert("Error while saving lots!");
  
  });
}





}
