import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort, SortDirection } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { DomainService } from '../rgnt-domain/service/domain.service';
import { Router } from '@angular/router';
import { DomainInvoices } from '../model/domain-invoices.model';
import { DomainInvoiceService } from './service/domain-invoices.service';
import PizZip from 'pizzip';
import Docxtemplater from 'docxtemplater';
import * as FileSaver from 'file-saver';
import { lastValueFrom } from 'rxjs';
import { error } from 'jquery';
import { HttpStatusCode } from '@angular/common/http';
import { jsPDF } from "jspdf";
import * as mammoth from 'mammoth';
// import * as html2pdf from 'html2pdf.js';
import html2pdf from 'html2pdf.js';
import { DomainObject } from '../invoice-generation/service/invoice.service';
import { UserService } from '../user/service/user.service';
import { AssetService } from '../asset.service';
import { OrganisationDetailsService } from '../organisation-details/service/organisation-details.service';
import { DocumentUploadService } from '../document-upload/service/document-upload.service';
import { NameServerService } from '../name-server-form/service/name-server.service';
import { RegistrationService } from '../registration/service/Registration.service';
import { Domain } from '../model/domain.model';
@Component({
    selector: 'app-domain-invoices',
    templateUrl: './domain-invoices.component.html',
    styleUrls: ['./domain-invoices.component.css'],
    standalone: false
})
export class DomainInvoicesComponent implements OnInit {
  
  displayedColumns: string[] = [
    // 'checkbox',
    'id',
    // 'organisationName',
    'domainName',
    'finalAmount',
    'invoice',
    'paymentStatus'
  ]; 

  userId: string = localStorage.getItem('email');
  role: string = localStorage.getItem('userRole');
  organisationId : number  = 0;

  domainsinvoicesList: DomainInvoices[] = [];
  domainsDataSource: MatTableDataSource<any>;
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;
  searchText:String=''
  constructor(private domainService: DomainService, private router: Router, private domainInvoiceService: DomainInvoiceService
    ,private  domainObject : DomainObject, private userService:UserService, private assetService:AssetService,private orgService:OrganisationDetailsService,
    private docService:DocumentUploadService,private nameServerService:NameServerService,private documentService:DocumentUploadService,private registrationService:RegistrationService
  ) {
    this.domainsDataSource = new MatTableDataSource<any>();
  }
  
  isLoadingData:boolean=false;
  maxDataCount:number=0
  async ngOnInit(): Promise<void> {
    // if(this.role === 'IDRBTADMIN'){
    //   this.loadBillingHistories("");
    // }else{
    //   this.loadBillingHistories(this.userId);
    // }
   await this.getLoggedInUserDetails();
   await this.fetchThePriceDetails();
   await this.getOrgTaxDetails();
  
   if(this.organisationId == 0 && this.role == 'IDRBTADMIN'){
     this.getAllInvoicesData();

   }else if(this.organisationId > 0){
     this.getAllInvoicesDataByOrgId(this.organisationId);
     this.getAllDomainsOfOrgId(this.organisationId);
   }
    // await this.fetchOrgDocs(this.organisationId);
    await this.getOrganisationDetails(this.organisationId);
    this.getStaticDataForTds();
    localStorage.setItem('isBoxVisible', 'false');
    
  }

  organisationDetails:any;

async getOrganisationDetails(orgId:number){
  const response = await lastValueFrom(
    this.orgService.getOrganisationDetailsByOrganisationId(orgId)
  );

  this.organisationDetails = response.body;
}
tds:any
getStaticDataForTds(){
  // Assuming 'this.assetService' is where getEmailReqExp is defined
  this.registrationService.getEmailReqExp('tds').subscribe({
    next: (response: string) => { 
      const respo = response[0] as any;
      this.tds = respo.value.trim(); 
    },
    error: (error) => {
      this.tds = 0; // Or null, depending on your default state
    }
  });
}

  loadBillingHistories(userId: string): void {
    this.domainInvoiceService.getAllBillingHistories(userId).subscribe(
      (data) => {
        
        this.domainsinvoicesList = data.map((invoice: DomainInvoices) => ({
          ...invoice,
          invoiceDate: new Date(invoice.invoiceDate), 
          duedate: new Date(invoice.dueDate)          
        }));
        
        this.domainsDataSource.data = this.domainsinvoicesList; 
        this.domainsDataSource.paginator = this.paginator; 
        this.domainsDataSource.sort = this.sort; 
      },
      (error) => {
      }
    );

  }

  
    goToInvoiceDetails(billingId: number){
      this.router.navigate(['/admin-invoice-details'],{queryParams:{billingId:billingId}});
    }

    applyFilter() {
      this.domainsDataSource.filter = this.searchText.trim().toLowerCase(); 
  
      if (this.domainsDataSource.paginator) {
        this.domainsDataSource.paginator.firstPage();
      }
  }

  
  async getInvoiceDetailAndDisplay(domain : any){
    try{
      //console.log("the invoce Details");
    
      const templateData = await this.loadTemplate('/assets/Invoicetemplate.docx');
      // Create a PizZip instance
     const zip = new PizZip(templateData as ArrayBuffer);
    const doc = new Docxtemplater(zip);
    doc.setData({
       amount : domain.finalAmount
    })
     // Render the document
     doc.render();

     // Generate the document blob
     const out = doc.getZip().generate({ type: "blob" });
       // Save the document
    FileSaver.saveAs(out, 'invoices.docx');
      

    }catch(error){
    }
  }



  async getInvoiceDetailAndDisplayAsPDF(domain: any) {
    console.log("ORG DETAILS", this.organisationDetails);

  console.log("STEP 1: Starting invoice generation", domain);

  try {

    await this.getDomainDetails(domain.domainId);
    console.log("STEP 2: Domain details loaded", this.domainDetail);

    if (this.role == "IDRBTADMIN") {
      await this.getAllDomainsOfOrgId(domain.organizationId);
      console.log("STEP 3: Org domains loaded");
    }

    const carryForwardNsCount = await this.calculateCarryForward(domain.domainId);
    const carryForwardNiCount = await this.calculateCarryForwardForNameIdentifier(domain.domainId);

    console.log("STEP 4: Carry forward calculated", carryForwardNsCount, carryForwardNiCount);

    let templateData;

    if (domain.invoiceType != 'nSRecPurchase' && domain.invoiceType != 'nIRecPurchase') {
      console.log("STEP 5: Fetching template normal");
      templateData = await this.assetService.getInvoiceTemplateBlob();
    } else {
      console.log("STEP 5: Fetching template NS/NI");
      templateData = await this.assetService.getInvoiceTemplateBlobForNSNI();
    }

    console.log("STEP 6: Template Blob received", templateData);

    const arrayBuffer = await new Response(templateData).arrayBuffer();

    console.log("STEP 7: Blob converted to ArrayBuffer", arrayBuffer);

    const html = await this.convertDocxToHtml(arrayBuffer);

    console.log("STEP 8: DOCX converted to HTML", html.substring(0, 500));

    if (!html || html.trim().length === 0) {
      console.error("ERROR: Mammoth returned empty HTML");
      return;
    }

    const rupees = await this.numberToWords(domain.finalAmount);

    const populatedHtml = this.replacePlaceholders(
      html,
      domain,
      rupees,
      "Invoice",
      this.organisationDetails,
      0,
      0,
      0,
      carryForwardNsCount,
      carryForwardNiCount
    );

    console.log("STEP 9: Placeholders replaced");

    const contentWithPadding = this.addPaddingToHTML(populatedHtml);

    console.log("STEP 10: Padding added");

    const cleanedHtml = this.cleanUpHTML(contentWithPadding);

    console.log("STEP 11: HTML cleaned");

    const contentWithTableStyles = this.addTableStyles(cleanedHtml);

    console.log("STEP 12: Table styles added");

    this.generatePDF(contentWithTableStyles);

  } catch (error) {
    console.error("FATAL ERROR DURING INVOICE GENERATION", error);
  }
}
  async loadTemplate(url: string): Promise<ArrayBuffer> {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error(`Failed to fetch template: ${response.statusText}`);
    }
    return response.arrayBuffer();
  }
  invoiceDetailsList : any[] =[]
  async getAllInvoicesData(){
    this.isLoadingData=true
    if(localStorage.getItem('jwtToken')==null||localStorage.getItem('jwtToken')==''){
      this.isLoadingData=false;
      this.navigateToSessionTimeout()
    }
    this.loadPaginationState()
    await lastValueFrom(this.domainInvoiceService.getAllInvoiceDetails()).then(
     (response) => {
       if(response.status === HttpStatusCode.Ok){
        this.invoiceDetailsList = response.body;
        //console.log(this.invoiceDetailsList)
        this.domainsDataSource.data = this.invoiceDetailsList; 
        this.maxDataCount=this.domainsDataSource.data.length;
        //console.log(this.domainsDataSource.data)
       setTimeout(() => {
        // Set paginator state BEFORE assigning
        this.paginator.pageIndex = this.pageIndex;
        this.paginator.pageSize = this.pageSize;

        // Assign paginator and sort
        this.domainsDataSource.paginator = this.paginator;
       

        // Force MatPaginator to render correct page
        this.paginator._changePageSize(this.pageSize);

        // Subscribe to future page changes
        this.paginator.page.subscribe((event: PageEvent) => {
          this.handlePageEvent(event);
        });

        
        //  this.domainsDataSource.sort = this.sort;
     
      });
      setTimeout(() => {
         this.domainsDataSource.sort=this.sort;
          this.sort.sortChange.subscribe(() => {
  this.savePaginationState();
});
      });
      this.isLoadingData=false;

       }

     }, (error) =>{
      //console.log(error)
        if(error.status == HttpStatusCode.Unauthorized){
           this.router.navigateByUrl("/session-timeout")
        }

     }

    );
  }

  // Load DOCX template
  async loadTemplate1(url: string): Promise<ArrayBuffer> {
    const response = await fetch(url);
    const buffer = await response.arrayBuffer();
    return buffer;
  }
  
  // Convert DOCX to HTML using Mammoth
  async convertDocxToHtml(templateData: ArrayBuffer): Promise<string> {
    return new Promise((resolve, reject) => {
      mammoth.convertToHtml({ arrayBuffer: templateData })
        .then(result => resolve(result.value)) // Returning HTML string
        .catch(error => reject(error));
    });
  }

  // Add padding (especially left padding) to the HTML content
addPaddingToHTML(html: string): string {
  // You can either add a specific CSS class or inline styles
  const style = `
    <style>
      .pdf-content {
        padding-left: 25px; /* Set the left padding here */
        padding-top: 20px;
        padding-right :10px;
      }
    </style>
  `;
   // Wrap the HTML content inside a container with the class
   return style + `<div class="pdf-content">${html}</div>`;
}


addTableStyles(html: string): string {
  const tableStyles = `
  <style>
    .pdf-content table {
      width: 100%;
      border-collapse: collapse; /* Ensures table borders collapse properly */
    }
    .pdf-content table, .pdf-content th, .pdf-content td {
      border: 1px solid black;
    }
    .pdf-content th, .pdf-content td {
      padding: 8px;
      text-align: left;
    }
    .pdf-content th {
      background-color: #f2f2f2; /* Light gray background for table header */
    }
    .pdf-content p, .pdf-content div {
      margin: 0;
      padding: 0;
    }
  .pdf-content td:has(.price-align-right) {
  text-align: right;
}
  .pdf-content td:has(.price-align-center) {
  text-align: center;
}
  </style>
`;
    
return tableStyles + `<div class="pdf-content">${html}</div>`;
}

// Clean up unwanted HTML elements and styles
cleanUpHTML(html: string): string {
  // Remove empty paragraphs or divs that might be causing extra lines
  html = html.replace(/<p>\s*<\/p>/g, ''); // Remove empty paragraphs
  html = html.replace(/<div>\s*<\/div>/g, ''); // Remove empty divs

  // Remove any unwanted inline styles that may be causing borders or padding
  html = html.replace(/style=".*?"/g, ''); // Remove all inline styles

  return html;
}
  
rupee : string =""
  // Replace placeholders in HTML with dynamic data
 replacePlaceholders(html: string, domain: any, rupee : string, invoiceTitle: string,orgDetails:any,nameServerCount,aliasCount,nametotalPriceBeforeGst,carryForwardNsCount,carryForwardNiCount): string {



const gst = orgDetails?.organisationGstin || '';
const code = gst ? gst.substring(0,2) : '';


     //console.log("enxetedc 2")
     const year = new Date().getFullYear(); // Gets the current year like 2025
 
  //  html=this.modifySlNoColspan(html)
  //  console.log(this.gstPercentage)
  //  let code=gst.
  let domainCount=1;
  const gstAmount=this.calculateGst(domain.domainPrice,this.domainDetail.aliasPrice,domain.nsRecordPrice,domain)
    //console.log("enxetedc 3")
    let populatedHtml = html.replace(/{amount}/g, `<span class="price-align-right">${this.formatRupees(domain.finalAmount)}</span>`);
    //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{rupee}/g, rupee);
    //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{id}/g, domain.id);
    //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{title}/g,`<b>${invoiceTitle}</b>`);
    //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{domainPrice}/g,`<span class="price-align-right">${this.formatRupees(domain.domainPrice-(domain.rebateAmount??0))}</span>`);
    //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{aliasPrice}/g,`<span class="price-align-right"> ${this.formatRupees(domain.aliasPrice)}</span>`);
    //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{nsRecordPrice}/g,`<span class="price-align-right"> ${this.formatRupees(domain.nsRecordPrice)}</span>`);
    //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{organisationName}/g,domain.organisationName);
    //console.log("ex1")
  populatedHtml = populatedHtml.replace(/{add}/g, orgDetails?.address || '');
populatedHtml = populatedHtml.replace(/{stateName}/g, orgDetails?.state || '');
populatedHtml = populatedHtml.replace(/{gstIn}/g, orgDetails?.organisationGstin ?? '');
 populatedHtml = populatedHtml.replace(/{code}/g, code);
     //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{nsCount}/g,`<span class="price-align-center"> ${nameServerCount}</span>`);
     //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{aliasCount}/g,`<span class="price-align-center"> ${aliasCount}</span>`);
     //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{gst}/g,`<span class="price-align-right"> ${this.formatRupees(gstAmount)}</span>`);
     //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{domainCount}/g,`<span class="price-align-center"> ${domainCount}</span>`);
     //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{gstPercentage}/g,(domain.gstPercent?domain.gstPercent:this.gstPercentage).toString());
     //console.log("ex1")
    populatedHtml = populatedHtml.replace(/{totalPrice}/g,this.formatRupees(nametotalPriceBeforeGst));
    populatedHtml = populatedHtml.replace(/{taxRupee}/g,this.numberToWords(gstAmount));
    populatedHtml =populatedHtml.replace(/{panNo}/g,this.orgTaxDetails.orgPan.toString());
    populatedHtml =populatedHtml.replace(/{tanNo}/g,this.orgTaxDetails.orgTan.toString());
    populatedHtml =populatedHtml.replace(/{telephoneNo}/g,this.orgTaxDetails.stdNumber.toString());
    populatedHtml =populatedHtml.replace(/{mobileNo}/g,this.orgTaxDetails.mobileNumber.toString());
    populatedHtml =populatedHtml.replace(/{email}/g,this.orgTaxDetails.orgEmail.toString());
   // populatedHtml =populatedHtml.replace(/{entityPan}/g,this.entityPanNumber.toString());
   populatedHtml = populatedHtml.replace(/{entityPan}/g, orgDetails.panNumber ?? '');
    populatedHtml =populatedHtml.replace(/{carryForwardNs}/g,carryForwardNsCount);
    populatedHtml =populatedHtml.replace(/{carryForwardNi}/g,carryForwardNiCount);
    //console.log("ex1")
    populatedHtml =populatedHtml.replace(/{tdsPercentage}/g,(domain.tdsPercent ? domain.tdsPercent : this.tds*100).toString());
    //console.log("ex1")
    populatedHtml =populatedHtml.replace(/{tdsAmount}/g,`<span class="price-align-right">${(domain.tdsAmount?this.formatRupees(domain.tdsAmount):0).toString()}</span>`);
    populatedHtml = populatedHtml.replace(
  /{penaltyAmount}/g,
  `<span class="price-align-right">
     ${this.formatRupees(domain.penaltyAmount || 0)}
   </span>`
);
    populatedHtml = populatedHtml.replace(/{year}/g, year.toString());
      if(domain.invoiceType=='nSRecPurchase'||domain.invoiceType=='nIRecPurchase'){
    if(domain.invoiceType=='nIRecPurchase'){
    populatedHtml =populatedHtml.replace(/{nsni}/g,"Reserved Name Identifier");
    populatedHtml =populatedHtml.replace(/{nsniCount}/g,aliasCount);
    populatedHtml =populatedHtml.replace(/{nsniPrice}/g,domain.aliasPrice);
    }else{
    populatedHtml =populatedHtml.replace(/{nsni}/g,"Name Server");
    populatedHtml =populatedHtml.replace(/{nsniCount}/g,nameServerCount);
    populatedHtml =populatedHtml.replace(/{nsniPrice}/g,domain.nsRecordPrice);
    }
  }
    const dateObj = new Date(domain.createdDateTime);

    // Format the date
    const formattedDate = new Intl.DateTimeFormat("en-GB", { 
        day: "2-digit", month: "short", year: "numeric" 
    }).format(dateObj);

    populatedHtml = populatedHtml.replace(/{date}/g, formattedDate);
     populatedHtml = populatedHtml.replace(/{slNo}/g,`<span class="price-align-center">Sl NO</span>`);
     populatedHtml = populatedHtml.replace(/{particulars}/g, `<span class="price-align-center">Particulars</span>`);
     populatedHtml = populatedHtml.replace(/{quantity}/g,`<span class="price-align-center">Quantity</span>`);
     populatedHtml = populatedHtml.replace(/{rateHeading}/g, `<span class="price-align-center">Rate</span>`);
     populatedHtml = populatedHtml.replace(/{perHeading}/g, `<span class="price-align-center">per</span>`);
     populatedHtml = populatedHtml.replace(/{amountHeading}/g, `<span class="price-align-center">Amount</span>`);

    // Add more replacements if needed
    //console.log("enxetedc 4")
    return populatedHtml;
  }


  generatePDF(htmlContent: string) {

  console.log("STEP 13: Entered generatePDF");

  const pdfContainer = document.createElement('div');
  pdfContainer.className = 'pdf-content';
  pdfContainer.innerHTML = htmlContent;

  document.body.appendChild(pdfContainer);

  console.log("STEP 14: HTML inserted into DOM");

  setTimeout(() => {

    console.log("STEP 15: Starting html2pdf");

    html2pdf()
      .set({
        margin: 10,
        filename: 'invoice.pdf',
        html2canvas: {
          scale: 2,
          logging: true
        },
        jsPDF: {
          unit: 'mm',
          format: 'a4',
          orientation: 'portrait'
        }
      })
      .from(pdfContainer)
      .save()
      .then(() => {

        console.log("STEP 16: PDF GENERATED SUCCESSFULLY");

        document.body.removeChild(pdfContainer);

      })
      .catch(err => {

        console.error("ERROR DURING PDF GENERATION", err);

      });

  }, 200);

}
  getDomainObjectandPasstoComponent(domain : any){
    this.domainObject.setDomain(domain);

  }
  formatRupees(amount: number | string): string {
  if (amount == null || amount === '') return '₹0';
 
  // Convert to number if string
  const num = typeof amount === 'string' ? parseFloat(amount) : amount;
 
  // Format using Indian locale
  return '₹' + num.toLocaleString('en-IN', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  });
}
 numberToWords(num: number): string {
  if (num === 0) return "Zero";

  const ones: string[] = [
    "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
    "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
  ];
  const tens: string[] = [
    "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
  ];
  const thousands: string[] = ["", "thousand", "million", "billion", "trillion"];

  // Round to 2 decimals first
  num = parseFloat(num.toFixed(2));
  let [integerPart, decimalPart] = num.toString().split(".");
  let intNum = parseInt(integerPart);

  let words = "";
  let chunkIndex = 0;

  const helper = (n: number): string => {
    let currentWords = "";
    if (n >= 100) {
      currentWords += ones[Math.floor(n / 100)] + " hundred";
      n %= 100;
      if (n > 0) currentWords += " ";
    }
    if (n > 0) {
      if (n < 20) {
        currentWords += ones[n];
      } else {
        currentWords += tens[Math.floor(n / 10)];
        if (n % 10 !== 0) {
          currentWords += " " + ones[n % 10];
        }
      }
    }
    return currentWords;
  };

  const capitalizeWords = (sentence: string): string =>
    sentence
      .split(" ")
      .map(word => word.charAt(0).toUpperCase() + word.slice(1))
      .join(" ");

  while (intNum > 0) {
    if (intNum % 1000 !== 0) {
      let currentChunkWords = helper(intNum % 1000);
      let thousandName = thousands[chunkIndex];
      let part = capitalizeWords(currentChunkWords);

      if (thousandName) {
        part += " " + capitalizeWords(thousandName);
      }

      words = (words ? part + " " + words : part);
    }
    intNum = Math.floor(intNum / 1000);
    chunkIndex++;
  }

  // Handle decimals
  if (decimalPart && parseInt(decimalPart) > 0) {
    let decimalWords = decimalPart
      .split("")
      .map(d => capitalizeWords(ones[parseInt(d)]))
      .join(" ");
    words += " Point " + decimalWords;
  }

  return words.trim();
}


async getAllInvoicesDataByOrgId(orgId : number){
  this.isLoadingData=true;
  if(localStorage.getItem('jwtToken')==null||localStorage.getItem('jwtToken')==''){
    this.isLoadingData=false;
    this.navigateToSessionTimeout()
  }
  this.loadPaginationState();
  await lastValueFrom(this.domainInvoiceService.getAllInvoiceDetailsByOrgId(orgId)).then(
   (response) => {
     if(response.status === HttpStatusCode.Ok){
      this.invoiceDetailsList = response.body;
      this.domainsDataSource.data = this.invoiceDetailsList; 
     setTimeout(() => {
        // Set paginator state BEFORE assigning
        this.paginator.pageIndex = this.pageIndex;
        this.paginator.pageSize = this.pageSize;

        // Assign paginator and sort
        this.domainsDataSource.paginator = this.paginator;
       

        // Force MatPaginator to render correct page
        this.paginator._changePageSize(this.pageSize);

        // Subscribe to future page changes
        this.paginator.page.subscribe((event: PageEvent) => {
          this.handlePageEvent(event);
        });

        
        //  this.domainsDataSource.sort = this.sort;
     
      });
      setTimeout(() => {
         this.domainsDataSource.sort=this.sort;
          this.sort.sortChange.subscribe(() => {
  this.savePaginationState();
});
      });
      this.isLoadingData=false;

     }

   }, (error) =>{
    this.isLoadingData=false;
      if(error.status == HttpStatusCode.Unauthorized){
         this.router.navigateByUrl("/session-timeout")
      }

   }

  );
}
async getLoggedInUserDetails(){
  await lastValueFrom(this.userService.getUserByEmailId(localStorage.getItem('email'))).then(
    response => {
      if(response.status === HttpStatusCode.Ok){
       this.organisationId=response.body.organisationId;
       if(this.role !== 'IDRBTADMIN'){
       // console.log('exe')
       // console.log(this.organisationId)

      }
      }
    }, error => {
      if(error.status === HttpStatusCode.Unauthorized){
        this.navigateToSessionTimeout();
      }
    }
  )
}

navigateToSessionTimeout() {
  this.router.navigateByUrl('/session-timeout');
}

pageIndex = 0;
pageSize = 10;
private loadPaginationState(): void {
  const savedPageIndex = localStorage.getItem('InvoicePageIndex');
  const savedPageSize = localStorage.getItem('InvoicePageSize');
  const savedSortActive = localStorage.getItem('InvoiceSortActive');
  const savedSortDirection = localStorage.getItem('InvoiceSortDirection') as SortDirection;

  this.pageIndex = savedPageIndex ? +savedPageIndex : 0;
  this.pageSize = savedPageSize ? +savedPageSize : 10;

  setTimeout(() => {
    if (this.sort) {
      if (savedSortActive && savedSortDirection) {
        this.sort.active = savedSortActive;
        this.sort.direction = savedSortDirection;
      } else {
        // Default sort
        this.sort.active = 'domainId';
        this.sort.direction = 'desc';
      }

      this.sort.sortChange.emit({
        active: this.sort.active,
        direction: this.sort.direction,
      });
    }
  });
}

private savePaginationState(): void {
  localStorage.setItem('InvoicePageIndex', this.pageIndex.toString());
  localStorage.setItem('InvoicePageSize', this.pageSize.toString());

  if (this.sort) {
    localStorage.setItem('InvoiceSortActive', this.sort.active);
    localStorage.setItem('InvoiceSortDirection', this.sort.direction);
  }
}

handlePageEvent(event: PageEvent): void {
  this.pageIndex = event.pageIndex;
  this.pageSize = event.pageSize;
  this.savePaginationState();
}

calculateGst(domainPrice,aliasPrice,nsRecordPrice,domain):number{
const total=(domainPrice+aliasPrice+nsRecordPrice)-(domain.rebateAmount??0);
let gstPercentageFromInvoice = domain.gstPercent;
const gstDecimal=gstPercentageFromInvoice?gstPercentageFromInvoice/100:this.gstPercentage/100;

return total*gstDecimal;
}
gstPercentage:number=0
fetchThePriceDetails(){
    this.domainService.getAllPriceDetails().subscribe({
      next:(response)=>{
        // this.priceDetails=response.body;
        const priceDetail=response.body.find(plan => plan.typeForPrice == "nameserver");
        //console.log(priceDetail+"fetchThePriceDetails")
        // this.priceforNameServer=priceDetail.price*this.domain.numberOfYears;
        // this.freeNSRecord=priceDetail.nsRecordCount
        this.gstPercentage=priceDetail.gst;
        // if(this.nameServers.length+this.nameServerLength>0){
        // this.updatePrice()
        // }
      },error:(error)=>{
        // //console.log(error)
      }
    })
  }

  modifySlNoColspan(htmlString: string): string {
    const parser = new DOMParser();
    const doc = parser.parseFromString(htmlString, 'text/html');

    // Find the <p>{slNo}</p> element
    // We can iterate through all <p> tags or be more specific if its parent is known
    const slNoPElement = Array.from(doc.querySelectorAll('p')).find(p => p.textContent === '{slNo}');

    if (slNoPElement) {
        // Find the parent <td> of the <p>{slNo}</p>
        const parentTd = slNoPElement.closest('td');

        if (parentTd) {
            // Set the colspan attribute
            parentTd.setAttribute('colspan', '1');
        } else {
        }
    } else {
    }
    return doc.body.innerHTML;
}
orgTaxDetails:any
async getOrgTaxDetails() {
  try {
    const response = await lastValueFrom(this.orgService.getOrgTaxDetails());
    this.orgTaxDetails = response.body; // assuming the actual data is in response.body
    //console.log(this.orgTaxDetails);
  } catch (error) {
    //console.error('Failed to fetch IDRBT details:', error);
  }
}

domainDetail:Domain=new Domain();
async getDomainDetails(id){
 const resp = await lastValueFrom(this.domainService.getDomainByDomainId(id));
 this.domainDetail=resp.body;
 //console.log(this.domainDetail)
}
domainList:any
domainIdList:any
async getAllDomainsOfOrgId(organisationId){
  this.domainService.getAllDomainsByOrgIdAsc(organisationId).subscribe({
    next:(resp)=>{
      this.domainList = resp.body;
      this.domainIdList = this.domainList.map(domain => domain.domainId);
      //console.log(resp.body)
    }
  })
}
carryForwardCount:number=0;
TOTAL_FREE_NS_QUOTA=5
TOTAL_FREE_NI_QUOTA=5

async calculateCarryForward(currentDomainId: number): Promise<number> {
    let totalUsedFreeNs = 0;
    for (const domain of this.domainList) {
        const usedCount = domain.countOfFreeNameServersUsed || 0;
        totalUsedFreeNs += usedCount;

        if (domain.domainId === currentDomainId) {
            break;
        }
    }

    const remainingCount = Math.max(0, this.TOTAL_FREE_NS_QUOTA - totalUsedFreeNs);
    
    // The 'async' keyword automatically handles this for us:
    return remainingCount;
    // (This is equivalent to: return Promise.resolve(remainingCount);)
  }
async calculateCarryForwardForNameIdentifier(currentDomainId: number): Promise<number> {
    let totalUsedFreeNi = 0;

    // The calculation itself is synchronous.
    // We can simply return its value directly, and 'async' will automatically
    // wrap it in a resolved Promise.
    for (const domain of this.domainList) {
        const usedCount = domain.countOfFreeNameIdentifiersUsed || 0;
        totalUsedFreeNi += usedCount;

        if (domain.domainId === currentDomainId) {
            break;
        }
    }

    const remainingCount = Math.max(0, this.TOTAL_FREE_NI_QUOTA - totalUsedFreeNi);
    
   
    return remainingCount;
    
  }
  

}