import { Component, DoCheck, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';

import { HttpClient, HttpHeaders, HttpResponse, HttpStatusCode } from '@angular/common/http';
import { DomainService } from '../rgnt-domain/service/domain.service';
import { debounceTime, firstValueFrom, last, lastValueFrom, Subject, takeUntil } from 'rxjs';
import { NameServerService } from '../name-server-form/service/name-server.service';
import { ContactDetailsFormService } from '../contact-details-form/service/contact-details-form.service';
import { Router } from '@angular/router';
import { OrganisationDetailsService } from '../organisation-details/service/organisation-details.service';
import { ToastrService } from 'ngx-toastr';
import { UserService } from '../user/service/user.service';
import { DocumentUploadComponent } from '../document-upload/document-upload.component';
import { NotificationService } from '../notification/service/notification.service';
import { ChangeDetectorRef } from '@angular/core';
import { DscVerificationComponent } from '../dsc-verification/dsc-verification.component';
import * as bootstrap from 'bootstrap';
import { environment } from '../environments/environment';
import { AbstractControl, FormBuilder, FormGroup, NgModel, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { AssetService } from '../asset.service';
import { ContactDocumentUploadService } from '../contact-document-upload/service/contact-document-upload.service';
import { DocumentUploadService } from '../document-upload/service/document-upload.service';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { format } from 'date-fns';
import { PreviewService } from './service/preview.service';
import { error } from 'jquery';
import { RegistrationService } from '../registration/service/Registration.service';
import { DnsSecService } from '../name-server-form/service/dns-sec.service';
import { DnssecDetails } from '../model/DnsSecDetails.model';
import * as CryptoJS from 'crypto-js';
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';


@Component({
    selector: 'app-preview',
    templateUrl: './preview.component.html',
    styleUrls: ['./preview.component.css'],
    standalone: false
})
export class PreviewComponent implements OnInit, OnChanges {
  @Output() formSubmitted: EventEmitter<void> = new EventEmitter<void>();
  @Output() back: EventEmitter<void> = new EventEmitter<void>(); // Emit event after form submission
  @Output() fetchDocs: EventEmitter<any> = new EventEmitter<any>(); // Emit event 
  @Output() fetchOrgDocs: EventEmitter<any> = new EventEmitter<any>(); // Emit event 
  @ViewChild(DocumentUploadComponent, { static: false }) documentUploadComponent?: DocumentUploadComponent;
  @ViewChild(DscVerificationComponent, { static: false }) dscVerificationComponent!: DscVerificationComponent;
  @Input() organisationId: number = 0;
  // @Input() domainId: number = 0;
  @Input() documentUploadError ;
  @Input() adminDocUploadError;
  @Input() techDocUploadError;
  @Input() finDocUploadError;

  signatureVerified: boolean | null = null;
  lastSignedHash: string | null = null;


  fullText = `
  <span>I, hereby confirm that I am authorized to sign legal documents on behalf of my organisation.</span>
  <p>I undertake that I am the authorized signatory of the organisation owning the domain, and I am 
  authorized to undertake, sign, and execute any documents or instruments necessary to obtain and manage the official 
  domain for the organisation. I do hereby agree for and on behalf of the management of the organisation that I will abide 
  by the terms & conditions while applying for registration of the domain name under “bank.in/fin.in” at IDRBT 
  (Institute for Development and Research in Banking Technology).</p>
  
  <p>I also certify and undertake the following:</p>
  <ol>
    <li>That the domain applying organisation is involved in banking and/or finance services (documentary proof is enclosed), 
    recognized by (indicate the respective regulator, like RBI) and will be using the registered domain for banking and/or 
    finance services, transaction and products purpose.</li>
    <li>That I am registering the domain name solely for the lawful purpose and will not use it for any illegal activities.</li>
    <li>That I will not use the domain name in violation of any applicable laws or regulations i.e. IT Act of Government of India 
    or any law or rules applicable.</li>
    <li>That all the contact details of heads, of the said organisation - admin details, billing details, and technical details are 
    being provided in the ‘online registration form’ as well as the documents being uploaded are verified to be correct, 
    accurate, and reliable.</li>
    <li>That to the best of my knowledge, the registration of the domain name will not infringe upon or otherwise violate the 
    rights of any third party. It shall be the responsibility of the registering organisation to ensure compliance with these norms. 
    IDRBT shall not be held responsible or liable in case of any violation by the organisation at any time.</li>
    <li>That ownership of the content uploaded on the website of the domain name, for which the organisation has applied and 
    registered, will be of the organisation. IDRBT will not be responsible for the website content.</li>
    <li>That no illegal, offensive (including but not limited to material that is sexually explicit 
    content or which promotes racism, bigotry, hatred or physical harm), deceptive, misleading, abusive, 
    indecent, harassing, blasphemous, defamatory, libellous, obscene, pornographic, paedophilic or menacing; 
    ethnically objectionable, disparaging content will be uploaded on the website using this domain (domain name).</li>
    <li>That no content will be uploaded that is objectionable or otherwise unlawful in any manner whatsoever; 
    or which consists of or contains software viruses, political campaigning, commercial solicitation, chain 
    letters, mass mailings or any "spam”.</li>
    <li>That no content will be uploaded that infringes upon or violates any third party’s rights including, 
    but not limited to, intellectual property rights, rights of privacy (including without limitation unauthorized
     disclosure of a person’s name, e-mail address, physical address or phone number) or rights of publicity.</li>
    <li>That IDRBT will not be responsible for any hacking of organisation’s website and redirection for any fraudulent activity in terms of the law.</li>
    <li>That it is agreed that any changes in management/head of organization or any other contact details 
    (like Admin, Technical and Billing) will be updated on the Registration Portal and also be informed 
    in writing i.e. on letterhead of the organisation duly signed and stamped by the authorised organization 
    to IDRBT immediately for seamless operation of the domain. </li>
    <li>It shall be responsibility of the organisation to update the Technical & Billing details and name 
    server entries online using User ID and Password, failing which IDRBT will not be held liable for any issue
     like non-functionality of the domain, if it arises due to the inaction. Organization will be responsible for 
     maintaining the ID and password of officials, maintaining the domain and handover of the same to other authorised
      official in case of transfer, resignation, or superannuation or any other reason of any official related to domain contact details.</li>
    <li>IDRBT is absolved and will not be held responsible for any dispute regarding the ownership of domain by the
     organisation. In future, if any dispute arises regarding office bearer/Management/Head of organization etc. 
     in the organisation, the organisation and its current and future management would be bound to absolve IDRBT 
     from any dispute/litigation etc. regarding the ownership or administration of the domain name registered by 
     the organisation. In no circumstances, IDRBT will be made a party in the court/tribunals/appellate etc.</li>
    <li>IDRBT reserves the right to suspend/freeze/delete the domain-name under dispute.</li>
    <li>Domain User/Registrant shall indemnify IDRBT, its management and officers against any and all costs,
     liabilities, losses, and expenses (including, but not limited to, legal expenses) arising out of any claim,
      suit, action or proceeding for any act(s) and/or omissions of the Institution.</li>
    
  </ol>

  <p>I have read the Registration Guidelines and Terms & Conditions for registering a domain name and 
  I agree to the above-mentioned Terms and Conditions on behalf of my organisation.</p>

  <p>Note : This Declaration can only be signed with Digital Signing Certificate as per the requirement</p>
`;

isExpanded = false;

  userId: string = localStorage.getItem('email');
  role: string = localStorage.getItem('userRole');
  notificationList: any[] = [];
  notificationCount = 0;
  notificationError: string | null = null; // Holds error messages if any
  private environmentApiUrl = environment.apiURL;
  formData = {
    name: '',
    organisationName: '',
    designation: '',
  };
  
  tokenPassword = '';
  passwordErrorMessage = '';
  isSigned= false;
  isLoading : boolean = false;
  tokens: any[] = [];
  certificates: any[] = [];

  @Input() currentStep: number;
  
  dataTypes: string[] = [
    'TextPKCS7',
    'TextPKCS1',
    'XML',
    'Sha256HashPKCS7',
    'Sha256HashPKCS1',
    'TextPKCS7ATTACHED'
  ];
  selectedToken: any = "";
  selectedCertificate: any = "";
  selectedDataType: string = '';
  embridgeUrl = 'https://localhost.emudhra.com:26769';
  dscApi = environment.apiURL;
  enable: boolean = true;

  ngDoCheck(): void {
    ////console.log('ngDoCheck detected change:', this.currentStep);
  }

  // ngDoCheck(): void {
  //   //console.log('ngDoCheck detected change:', this.currentStep);
  // }


  async ngOnChanges(changes: SimpleChanges): Promise<void> {
   // //console.log('entered')
    if (changes['organisationId']) {
      this.organisationId = changes['organisationId'].currentValue;
      //console.log('organisationId changed:', changes['organisationId'].currentValue);
      // Add custom logic here for handling the updated data
    }
    if (changes['currentStep']) {
      //console.log(changes['currentStep'].currentValue+'current step');
      //console.log(changes['currentStep'].previousValue+'prev step');
     await this.getLoggedInUserDetails();
     this.getAllStaticData();
     //await this.updateOrganisationIdForUser(this.organisationId);
     this.fetchDataFromAPIs();
   
    }
  }

  private modalInstance: bootstrap.Modal | null = null;
  

  async ngOnInit(): Promise<void> {
    //if(this.organisationId < 1){
      await this.getLoggedInUserDetails();
      //console.log('orgId:'+this.organisationId);
    //}
    this.getDnsAlgorithmType();
    this.getDnsDigestType();
    this.getAllCountryCodes();
    this.getAllStdCodes();
    this.getRegularExpressionForEmail();
    this.getAllStaticData();
    if(this.user.onboardingStepIndex == 3){
      await this.fetchDataFromAPIs(); 
    }
    this.loadNotifications();
    
    if (this.cityOptions.length > 1) {
      this.organisationForm.get('city')?.setValue(this.cityOptions[1].name);
  } else {
      this.clearCityAndState();
  }
    this.getAllDomainsListByOrgId(this.organisationId);
    this.submitPreviewClickSubject.pipe(
      debounceTime(this.DEBOUNCE_TIME),
      takeUntil(this.destroy$) // Ensure subscription is cleaned up
    ).subscribe(() => {
      this.onSubmit(); // Call the actual submission logic after debounce
    });
  }
   ngOnDestroy(): void {
    this.destroy$.next(); // Signal to complete all subscriptions using takeUntil
    this.destroy$.complete(); // Complete the subject itself
  }
   onButtonClickForSaveAndNext(): void {
    // If the checkbox is not checked, provide immediate feedback and prevent debounce.
    if (!this.checkBoxChecked) {
      this.toastr.error("Please ensure you have checked the checkbox before proceeding");
      return; // Stop here, no debounce needed
    }

    // Check if currently loading to prevent triggering debounce
    if (this.isLoading) {
      return; // Already submitting, ignore click
    }

    // If checkbox is checked and not loading, trigger the debounce timer
    this.submitPreviewClickSubject.next();
  }

  cards = [
    {
      heading: 'Domain Applying For',

      details: {
        //domainId: 0,
        applicationId:0,
        bankName: '',
        organizationName:'',
        domainName: '',
        industry:'',
        numberOfYears: '',
        nsRecordStatus:'',
        organisationId:this.organisationId,
        cost: 0,
        paymentStatus:'Payment Not Done',
        registrationDate:'',
        renewalDate:'',
        status:'',
        submissionDate:'',
        userName:'',
        userMailId:'',
        isOnboardingDomain: true,
        isEditing: false,
        applicationStatus: this.assetService.Incomplete,
        onBoardingStepIndex:0,
        isUpdatedInNIXI: false,
        aliasPrice:0,
        domainPrice:0,
        nsRecordPrice:0,
        countOfFreeNameServersUsed:0,
        countOfFreeNameIdentifiersUsed:0,
        tdsAmountDetected:0,
        rebateAmountOfDomain:0,
        isCooperativeBank:false,
        createdDateTime: '',
        gstAmount:0,
        twoLetterDomainDocumentProof: null,
        twoLetterDomainDocumentFileName:''
      },
    },

    {
      heading: 'Entity Details',

      details: {
        organisationDetailsId: 0,
        institutionName: '',
        applicationId:0,
        userMailId:0,
        pincode: '',
        city: '',
        state: '',
        district:'',
        address: '',
        countryCode:'',
        stdCode:'',
        stdTelephone: '',
        mobileNumber: '',
        organisationEmail: '',
        isEditing: false,
        onBoardingCompleted:false,
        remainingFreeNameServers:0,
        remainingFreeNameIdentifiers:0,
        aliasCountForOrganization:0,
         createdDateTime:'',
        createdByEmailId:'',
        organisationGstin: '',
        panNumber: '',
        orgDateIncorp: '',
      },
    },

    {
      heading: 'Administrative Contact',

      details: {
        administrativeContactId:0,
        adminFullName: '',
        adminEmail: '',
        adminPhone: '',
        adminAltPhone: '',
        adminDesignation: '',
        adminAddress: '',
        adminCountryCode:'',
        adminAltCountryCode:'',
        organisationId:this.organisationId,
        adminDocuments: '',
        applicationId:0,
        userMailId:0,
        isEditing: false,
        pincode: 0,
        state: '',
        city: '',
        isContactSentToNixi:false,
        createdByEmailId:''

      },
    },

    {
      heading: 'Technical Contact',

      details: {
        technicalContactId:0,
        techFullName: '',
        techEmail: '',
        techPhone: '',
        techAltPhone: '',
        techDesignation: '',
        techCountryCode:'',
        techAltCountryCode:'',
        techAddress: '',
        applicationId:0,
        userMailId:0,
        techDocuments: '',
        organisationId:this.organisationId,
        isEditing: false,
        pincode: 0,
        state: '',
        city: '',
        isContactSentToNixi:false,
        createdByEmailId:''
      },
    },

    {
      heading: 'Finance Contact',

      details: {
        organisationalContactId:0,
        billFullName: '',
        billEmail: '',
        billPhone: '',
        billAltPhone: '',
        billDesignation: '',
        billCountryCode:'',
        billAltCountryCode:'',
        billAddress: '',
        billDocuments: '',
        applicationId:0,
        userMailId:0,
        organisationId:this.organisationId,
        isEditing: false,
        pincode: 0,
        state: '',
        city: '',
        isContactSentToNixi:false,
        createdByEmailId:''
      },
    },

    
  ];
  organisationForm: FormGroup;
  constructor(private http: HttpClient,
    private sanitizer: DomSanitizer,
    private previewService: PreviewService,
    private domainService: DomainService,
    private namServerService: NameServerService,
    private conatctFormService: ContactDetailsFormService,
    private organisationService: OrganisationDetailsService,
    private router: Router,
    private toastr: ToastrService,
    private userService: UserService,
    private notificationService: NotificationService,
    private cdr: ChangeDetectorRef,
    private fb: FormBuilder,
    private assetService:AssetService,
    private organisationDetailsService: OrganisationDetailsService,
    private contactDocumentsService: ContactDocumentUploadService,
    private organisationDocumentsService: DocumentUploadService,
    private orgDocService:DocumentUploadService,
    private registrationService: RegistrationService,
    private dnsSecService: DnsSecService
  ) {
    if(this.organisationId < 1 || this.organisationId == null || this.organisationId == undefined){
      this.organisationId = this.router.getCurrentNavigation().extras?.state['organisationId'];
    }
     this.organisationForm = this.fb.group({
                organisationDetailsId:0,
                institutionName: ['',[Validators.required]],
                stdCode:['',[Validators.required]],
                countryCode:['',[Validators.required]],
                stdTelephone: [{ value: '' }, [
                  Validators.required,
                  Validators.pattern('^[0-9]*$'),
                  Validators.minLength(5),
                  Validators.maxLength(10)
                ]],
                mobileNumber: [{ value: ''}, [
                  Validators.required,
                  Validators.pattern('^[0-9]*$'),
                  Validators.minLength(8),
                  Validators.maxLength(15)
                ]],
                organisationEmail: ['',[Validators.required,Validators.email,this.customEmailValidator()]],
                address: ['',[Validators.required,Validators.minLength(5),Validators.maxLength(300)]],
                pincode: ['',[Validators.required, Validators.pattern('^[0-9]{6}$')]],
                city: [{ value: '', disabled: true }, Validators.required], 
                district: [''],
                state: ['',Validators.required],
                userMailId:['']
            });
  }
      isChrome(): boolean {
        return this.assetService.isChrome();
      }
      isEdge():boolean{
        return this.assetService.isEdge();
      }
  
  customEmailValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      const value = control.value;
      if (!value) return null;  // Don't validate empty fields

      // Regular expression to check email format
      const emailRegex = new RegExp(this.regExp) // Use the fetched regex pattern

      // If the value does not match the pattern, return an error
      if (!emailRegex.test(value)) {
        return { invalidEmail: 'Please enter a valid email address (e.g., example@gmail.com).' };
      }
      return null;  // Valid email format
    };
  }
  /**
 
   * Fetch data from different APIs and populate card details
 
   */
  goBack(): void {
    this.back.emit();
  }

  private submitPreviewClickSubject = new Subject<void>();
  private destroy$ = new Subject<void>();
  private readonly DEBOUNCE_TIME = 1000; // Debounce time in milliseconds

  async onSubmit(): Promise<void> {
    const currentJson = JSON.stringify(this.buildFinalPreviewJson());
const currentHash = CryptoJS.SHA256(currentJson).toString();

if (!this.signatureVerified || this.lastSignedHash !== currentHash) {
    this.toastr.error("Data changed. Please sign again.");
    return;
}

    if(this.checkBoxChecked){
        await this.getLoggedInUserDetails();
    await this.updateUserOnboardingStep();
    // await this.updateDomainSubmissionDate();
    await this.updateOrganisationDetails();
    await this.updateOnBoardingCompleted();
    this.cards[0].details.organisationId = this.organisationId;
    // Emit form submission event
    this.showError = false;    // Reset error message before validation
  
    // Validate form fields and checkbox
    if (!this.isFormValid(this.cards)) {
      // If form is not valid, show an error message or handle accordingly
      //console.error('Form is invalid. Please correct the errors.');
      return;  // Return early if validation fails
    }
    this.formSubmitted.emit(); 
    try {
      
      // Update preview details
      await this.updatePreviewDetails();
  
      // Synchronize organization name with institution name
      this.cards[0].details.organizationName = this.cards[1].details.institutionName;
  
      // Prepare the notification object
      const notification = {
        message: "Application submitted successfully",
        moduleType: "DocumentUpload",
        moduleRecordId: 102,
        notificationTo: this.userId,
        emailId: this.userId,
        status: "Unread",
        createdDateTime: new Date().toISOString(), // Use ISO 8601 string for date/time
        createdByEmailId: this.userId,
        profilepic: null
      };
  
      // Create notification via the notification service
      const response = await this.notificationService.createNotification(notification).toPromise();
      //console.log('Notification created successfully:', response);
  
      // Load notifications after successful creation
      this.loadNotifications();
    } catch (error) {
      //console.error('Error during submission:', error);
    }
    }else{
      this.toastr.error("Please ensure you have checked the checkbox before proceeding")
    }
  
  }

  // Inside the PreviewComponent
  loadNotifications(): void {
    //console.log(this.userId);
    if (this.userId) {
      this.notificationService.getNotifications(this.userId).subscribe(
        (notifications: any[]) => {
          this.notificationList = notifications; // Bind to the template
          this.notificationCount = notifications.filter(n => n.status === 'Unread').length; // Update count
          this.cdr.detectChanges(); // Ensure view updates
          this.notificationError = null;
          //console.log('Notifications loaded:', this.notificationList);
        },
        error => {
          this.notificationError = 'Error fetching notifications: ' + error.message;
          //console.error('Error fetching notifications:', error);
        }
      );
    }
  }

  async getNameServersOfDomain(){
   
  }

  nameDetails:any

  async getDomainDetails(){
    
  }

  async getOrganisationDetailsById(){
    if(this.organisationId>0){
          await lastValueFrom(this.organisationDetailsService.getOrganisationDetailsByOrganisationId(this.organisationId)).then(
      response => {
        if(response.status === HttpStatusCode.Ok){
          this.cards[1].details.organisationDetailsId = response.body.organisationDetailsId;
          //console.log(response.body)
          //this.cards
          this.cards[1].details.institutionName = response.body.institutionName?.toUpperCase();
          this.cards[1].details.pincode = response.body.pincode;
          this.cards[1].details.city = response.body.city;
          this.cards[1].details.state = response.body.state;
          this.cards[1].details.district = response.body.district;
          this.cards[1].details.address = response.body.address;
          this.cards[1].details.district = response.body.district;
          this.cards[1].details.stdTelephone = response.body.stdTelephone;
          this.cards[1].details.mobileNumber = response.body.mobileNumber;
          this.cards[1].details.organisationGstin = response.body.organisationGstin;
          this.cards[1].details.panNumber = response.body.panNumber;
          this.cards[1].details.orgDateIncorp = response.body.orgDateIncorp;
          this.cards[1].details.organisationEmail = response.body.organisationEmail;
          this.cards[1].details.organisationId= this.organisationId;
          this.cards[1].details.userMailId = response.body.userMailId;
          this.cards[1].details.userName = response.body.userName;
         // this.cards[1].details.applicationId = response.body.applicationId;
          this.cards[1].details.countryCode=response.body.countryCode;
          this.cards[1].details.stdCode=response.body.stdCode;
         this.cards[1].details.remainingFreeNameServers=response.body.remainingFreeNameServers;
          this.cards[1].details.aliasCountForOrganization=response.body.aliasCountForOrganization;
          this.cards[1].details.remainingFreeNameIdentifiers=response.body.remainingFreeNameIdentifiers;
          this.cards[1].details.createdDateTime=response.body.createdDateTime;
          this.cards[1].details.createdByEmailId=response.body.createdByEmailId;
          this.cards[1].details.submissionDate=response.body.submissionDate;
          //  this.cards[1].details.aliasCountForOrganization=response.body.aliasCountForOrganization;

          // for signing
          this.formData.organisationName=response.body.institutionName;
        }
      }
    )
    }
  
  }

  async fetchAdministrativeContact(){
    await lastValueFrom(this.conatctFormService.getAdminOfficerDetailsByOrgId(this.organisationId)).then(
      response => {
        //console.log(response)
        this.cards[2].details.administrativeContactId = response.body[0].administrativeContactId;
          this.cards[2].details.adminFullName = response.body[0].adminFullName;
          this.cards[2].details.adminEmail = response.body[0].adminEmail;
          this.cards[2].details.adminPhone = response.body[0].adminPhone;
          this.cards[2].details.adminAltPhone = response.body[0].adminAltPhone;
          this.cards[2].details.adminDesignation = response.body[0].adminDesignation;
          this.cards[2].details.adminAddress = response.body[0].adminAddress;
          this.cards[2].details.adminDocuments = response.body[0].documents;
          this.cards[2].details.organisationId= this.organisationId;
          this.cards[2].details.userMailId = response.body[0].userMailId;
          this.cards[2].details.userName = response.body[0].userName;
          this.cards[2].details.applicationId = response.body[0].applicationId;
          this.cards[2].details.adminCountryCode =response.body[0].adminCountryCode;
          this.cards[2].details.adminAltCountryCode=response.body[0].adminAltCountryCode;
          this.cards[2].details.pincode= this.cards[1].details.pincode
          this.cards[2].details.city= this.cards[1].details.city;
          this.cards[2].details.state= this.cards[1].details.state;
          this.cards[2].details.isContactSentToNixi = response.body[0].isContactSentToNixi;
          this.cards[2].details.createdByEmailId=response.body[0].createdByEmailId;
          // for siginng
          this.formData.name=response.body.adminFullName;
          this.formData.designation=response.body.adminDesignation;
      }
    )
  }

  async fetchTehcnicalContact(){
    await lastValueFrom(this.conatctFormService.getTechnicalOfficerDetailsByOrgId(this.organisationId)).then(
      response => {
        //console.log(response)
        this.cards[3].details.technicalContactId = response.body.technicalContactId
          this.cards[3].details.techFullName = response.body.techFullName;
          this.cards[3].details.techEmail = response.body.techEmail;
          this.cards[3].details.techPhone = response.body.techPhone;
          this.cards[3].details.techAltPhone = response.body.techAltPhone;
          this.cards[3].details.techDesignation = response.body.techDesignation;
          this.cards[3].details.techAddress = response.body.techAddress;
          this.cards[3].details.techDocuments = response.body.documents;
          this.cards[3].details.organisationId= this.organisationId;
          this.cards[3].details.userMailId = response.body.userMailId;
          this.cards[3].details.userName = response.body.userName;
          this.cards[3].details.applicationId = response.body.applicationId;
          this.cards[3].details.techCountryCode=response.body.techCountryCode;
          this.cards[3].details.techAltCountryCode=response.body.techAltCountryCode;
          this.cards[3].details.pincode= this.cards[1].details.pincode
          this.cards[3].details.city= this.cards[1].details.city;
          this.cards[3].details.state= this.cards[1].details.state;
          this.cards[3].details.isContactSentToNixi = response.body.isContactSentToNixi;
          this.cards[3].details.createdByEmailId=response.body.createdByEmailId;
      }
    )
  }

  async fetchBillingContact(){
    await lastValueFrom(this.conatctFormService.getBillingOfficerDetailsByOrgId(this.organisationId)).then(
      response => {
        this.cards[4].details.organisationalContactId = response.body.organisationalContactId;
          this.cards[4].details.billFullName = response.body.billFullName;
          this.cards[4].details.billEmail = response.body.billEmail;
          this.cards[4].details.billPhone = response.body.billPhone;
          this.cards[4].details.billAltPhone = response.body.billAltPhone;
          this.cards[4].details.billDesignation = response.body.billDesignation;
          this.cards[4].details.billAddress = response.body.billAddress;
          this.cards[4].details.billDocuments = response.body.documents;
          this.cards[4].details.organisationId= this.organisationId;
          this.cards[4].details.userMailId = response.body.userMailId;
          this.cards[4].details.userName = response.body.userName;
          this.cards[4].details.applicationId = response.body.applicationId;
          this.cards[4].details.billCountryCode=response.body.billCountryCode;
          this.cards[4].details.billAltCountryCode=response.body.billAltCountryCode;
          this.cards[4].details.pincode= this.cards[1].details.pincode
          this.cards[4].details.city= this.cards[1].details.city;
          this.cards[4].details.state= this.cards[1].details.state;
          this.cards[4].details.isContactSentToNixi = response.body.isContactSentToNixi;
          this.cards[4].details.createdByEmailId=response.body.createdByEmailId;
      }
    )
  }

  async fetchDataFromAPIs() {
    
    await this.getOrganisationDetailsById();
     this.fetchAdministrativeContact();
     this.fetchTehcnicalContact();
     this.fetchBillingContact();
    // this.getNameServersOfDomain();
    //  this.getDNSSECRrcordsByDomainId(this.domainId);
     this.getinitialEmailsofOrgAndContact();
   //  this.fetchThePriceDetails();
    //console.log(this.domainId);
  }
  emailFields: { [key: string]: string } = {}; 
  initialEmailFields: { [key: string]: string } = {}; 
  getEmailsofOrgAndContact(): boolean {
    this.emailFields= {}; // A map to store email types and values
  
    // Add logged-in user's email
    const userEmail = localStorage.getItem("email");
    if (userEmail) {
      this.emailFields['Super Admin'] = userEmail;
    }
  
    // Iterate over cards and add emails to the map based on contact types
    this.cards.forEach(card => {
      const details = card.details;
  
      switch (card.heading) {
        case 'Administrative Contact':
          if (details.adminEmail) {
            this.emailFields['Administrative Contact'] = details.adminEmail;
          }
          break;
  
        case 'Technical Contact':
          if (details.techEmail) {
            this.emailFields['Technical Contact'] = details.techEmail;
          }
          break;
  
        case 'Finance Contact':
          if (details.billEmail) {
            this.emailFields['Finance Contact'] = details.billEmail;
          }
          break;
      }
    });
  
    //console.log(this.emailFields);
  
    // Check for duplicate emails (more than twice)
    const emailCountMap: { [email: string]: number } = {};
    
    // Count occurrences of each email
    for (const contactType in this.emailFields) {
      const email = this.emailFields[contactType];
      if (email) {
        emailCountMap[email] = (emailCountMap[email] || 0) + 1;
      }
    }
  
    // Check for emails used more than twice
    for (const email in emailCountMap) {
      if (emailCountMap[email] > 2) {
        this.orgEmailError = "The email is used more than twice";
        return false; // Return false if a duplicate email is found more than twice
      }
    }
  
    return true; // Return true if no email appears more than twice
  }

  getinitialEmailsofOrgAndContact(): boolean {
     this.initialEmailFields= {}; // A map to store email types and values
  
    // Add logged-in user's email
    const userEmail = localStorage.getItem("email");
    if (userEmail) {
      this.initialEmailFields['Super Admin'] = userEmail;
    }
  
    // Iterate over cards and add emails to the map based on contact types
    this.cards.forEach(card => {
      const details = card.details;
  
      switch (card.heading) {
        case 'Administrative Contact':
          if (details.adminEmail) {
            this.initialEmailFields['Administrative Contact'] = details.adminEmail;
          }
          break;
  
        case 'Technical Contact':
          if (details.techEmail) {
            this.initialEmailFields['Technical Contact'] = details.techEmail;
          }
          break;
  
        case 'Finance Contact':
          if (details.billEmail) {
            this.initialEmailFields['Finance Contact'] = details.billEmail;
          }
          break;
      }
    });
  
    //console.log(this.initialEmailFields);
  
    // Check for duplicate emails (more than twice)
    const emailCountMap: { [email: string]: number } = {};
    
    // Count occurrences of each email
    for (const contactType in this.initialEmailFields) {
      const email = this.initialEmailFields[contactType];
      if (email) {
        emailCountMap[email] = (emailCountMap[email] || 0) + 1;
      }
    }
  
    // Check for emails used more than twice
    for (const email in emailCountMap) {
      if (emailCountMap[email] > 2) {
        // this.orgEmailError = "The email is used more than twice";
        return false; // Return false if a duplicate email is found more than twice
      }
    }
  
    return true; // Return true if no email appears more than twice
  }
  async getEmailisAvailable(email: string, type: string): Promise<boolean> {
    if (this.orgEmailError !== "") {
      return false; // Exit early if there's an error with the email
    }
  
    try {
      //console.log('Current emailFields:', this.emailFields);
      //console.log('Initial emailFields:', this.initialEmailFields);
      //console.log('Checking email:', email, 'for type:', type);
  
      // Check if the current email is the same as the initial email for this type
      if (this.initialEmailFields && this.initialEmailFields[type] === email) {
        //console.log(`Email '${email}' for type '${type}' is the same as initial. Skipping database check.`);
        return true; // Email hasn't changed for this contact type
      }
  
      // Count the occurrences of the email in the emailFields map
      let emailCountInFields = 0;
      for (const key in this.emailFields) {
        if (this.emailFields.hasOwnProperty(key) && this.emailFields[key] === email) {
          emailCountInFields++;
        }
      }
  
      //console.log(`Count of '${email}' in emailFields:`, emailCountInFields);
  
      // If the email exists two or more times in emailFields (even if it's modified), skip DB check
      if (emailCountInFields >= 2) {
        //console.log(`Email '${email}' already exists ${emailCountInFields} time(s) in emailFields. Skipping database check.`);
        return true; // Skip DB check because it already exists 2 times or more
      }
  
      // If the email is new or modified and is not present twice, check the database
      //console.log(`Email '${email}' is not present twice or has been modified. Checking database.`);
      const response: HttpResponse<boolean> = await firstValueFrom(this.conatctFormService.isEmailAvailableToUse(email,this.organisationId));
      //console.log('Database availability response:', response.body);
      if(response.body==false){
        this.orgEmailError="This email is already used"
      }
      return response.body ?? false; // Return the boolean from the database
  
    } catch (error) {
      //console.error("Error checking email availability:", error);
      return false; // Default to false if there's an error in the API call
    }
  }
  
  clickedcard:any;
  hideEditButton:boolean=false;
      
      @ViewChild('orgCountryCode') orgCountryCode!: ElementRef;
      @ViewChild('orgStdCode') orgStdCode!: ElementRef;
      @ViewChild('adminCode') adminCode!: ElementRef;
      @ViewChild('adminAltCode') adminAltCode!: ElementRef;
      @ViewChild('techCountryCode') techCountryCode!: ElementRef;
      @ViewChild('techAltContryCode') techAltContryCode!: ElementRef;
      @ViewChild('billCountryCode') billCountryCode!: ElementRef;
      @ViewChild('billAltCountryCode') billAltCountryCode!: ElementRef;
  
      adminCC:string="adminCC"
      adminAltCC:string="adminAltCC"
      techCC:string="techCC"
      techAltCC:string="techAltCC"
      billCC:string="billCC"
      billAltCC:string="billAltCC"
      orgCountry:string="orgCountry"
      orgStdCountry:string="orgStdCountry"
      adjustCountryCodeWidth(element) {
     
        let countryCodeInput ;
        if(element==this.adminCC){
          countryCodeInput=this.adminCode.nativeElement;
        }else if(element==this.adminAltCC){
          countryCodeInput=this.adminAltCode.nativeElement;
        }else if(element==this.techCC){
          countryCodeInput=this.techCountryCode.nativeElement;
        }else if(element==this.techAltCC){
          countryCodeInput=this.techAltContryCode.nativeElement;
        }else if(element==this.billCC){
          countryCodeInput=this.billCountryCode.nativeElement;
        }else if(element ==this.billAltCC){
          countryCodeInput=this.billAltCountryCode.nativeElement;
        }else if(element == this.orgCountry){
          countryCodeInput=this.orgCountryCode.nativeElement;
        }else if(element == this.orgStdCountry){
          countryCodeInput=this.orgStdCode.nativeElement;
        }
        
        if (countryCodeInput) {
          let inputValue = countryCodeInput.value;
      
          // Allow only numbers, + (only at the start), and -
          inputValue = inputValue.replace(/[^0-9]/g, '');
      
      
          // Limit total length to 5 characters
          inputValue = inputValue.substring(0, 5);
      
         
      
          countryCodeInput.value = inputValue; // Update input field
      
          const inputLength = inputValue.length > 0 
            ? inputValue.length
            : countryCodeInput.placeholder.length;
      
          countryCodeInput.style.width = `${(inputLength * 12) + (inputValue.length ? 20 : 0)}px`; // Adjust width dynamically
        }
      }
      beforeEditemailForAdmin:String=''
      beforeEditemailForTech:String=''
      beforeEditemailForBill:String=''
  toggleEdit(card: any) {
    this.hideEditButton=true;
    //console.log(card);
    //console.log(card.mobileNumber)
    if(card.heading === 'Name Server Details'){
      this.clickedcard=JSON.stringify(this.nameDetails)
    }else{
      if(card.heading === 'Entity Details'){
        // this.getAllCountryCodes();
        // this.getAllStdCodes();
        for (const controlName in this.organisationForm.controls) {
          const control = this.organisationForm.get(controlName);
          if (control) { // Check if the control exists
            //console.log(`${controlName}: ${control.value}`); // Or control.getRawValue() for disabled controls
          }
        }
        
        this.organisationForm.patchValue({
          organisationDetailsId: this.cards[1].details.organisationId,
          institutionName: this.cards[1].details.institutionName ,
          stdCode:this.cards[1].details.stdCode,
          countryCode:this.cards[1].details.countryCode,
          stdTelephone: this.cards[1].details.stdTelephone,
          mobileNumber:this.cards[1].details.mobileNumber,
          organisationEmail: this.cards[1].details.organisationEmail,
          address:this.cards[1].details.address,
          pincode:this.cards[1].details.pincode,
          city:this.cards[1].details.city,
          state:this.cards[1].details.state,
          district:this.cards[1].details.district,
          userMailId:this.cards[1].details.userMailId
        });
        
      //console.log(this.organisationForm.get('city').value)
        //this.cards
        this.fetchCityState(this.organisationForm.get('pincode').value)
       
        this.selectedStdCode=this.organisationForm?.get('stdCode').value;
        this.selectedCountryCode=this.organisationForm?.get('countryCode').value;
      }else if(card.heading === 'Administrative Contact'){
        this.beforeEditemailForAdmin=card.details.adminEmail;
        this.selectedAdminAltCountryCode=card.details.adminAltCountryCode
        this.selectedAdminCountryCode=card.details.adminCountryCode
      }else if(card.heading === 'Technical Contact'){
        this.beforeEditemailForTech=card.details.techEmail;
        //console.log(card.details.techAltCountryCode)
        this.selectedTechAltCountryCode=card.details.techAltCountryCode
        this.selectedTechCountryCode=card.details.techCountryCode
      }

      else if(card.heading === 'Finance Contact'){

        this.beforeEditemailForBill=card.details.billEmail;

        this.selectedBillAltCountryCode=card.details.billAltCountryCode
        this.selectedBillCountryCode=card.details.billCountryCode
      }
      this.clickedcard=JSON.stringify(card);
    }
 
  //console.log(this.clickedcard)
    card.details.isEditing = !card.details.isEditing;
    
  }

  // Save changes for a specific card
  formSubmittedd=false;
  adminDocErrors="";
  techDocErrors="";
  billDocErrors="";
  orgDocErrors="";
  boardApprovalDocErrors="";
  async onSave(card: any) {
    
    //DNS SEC CHECK
   //console.log(card)
    if(card.heading === 'DNS SEC Details'){
      if(await this.isFormValid(card)){
       this.updateAllDnsSecRecords();
       card.details.isEditing = false;
       this.hideEditButton = false;
      }
      
    }


    // Check if the form is valid before saving
   if (card.heading === 'Name Server Details') {
  let duplicateIps: string[] = []; // This will only track IPv4 DB duplicates as per original logic

  // Clear previous DB-related errors for both IPv4 and IPv6
  this.nameDetails.forEach(item => {
    item.duplicateIPError = null; // Clear IPv4 DB error
    item.duplicateIPV6Error = null; // Clear IPv6 DB error
    
  });

 
  // Your original saving logic remains unchanged
  if ( await this.isFormValid(card)) {
    // //console.log(this.isFormValid(card))
    // return
    // If no duplicate IPs (only IPv4 DB duplicates captured by `duplicateIps`), proceed with saving
    if (duplicateIps.length === 0 && !this.vailidationNameServerHostName.includes(false)) {
      this.vailidationNameServerHostName = [];
      this.updateNameServers();
      card.details.isEditing = false;
      this.hideEditButton = false;
    } else {
      // Form is invalid due to IPv4 DB duplicates or hostname validation
     //console.warn("Form invalid due to IPv4 DB duplicates or hostname validation.");
    }
  }
  } else if(card.heading === 'Administrative Contact'){
      if(this.adminDocDetails.length<2){
        this.adminDocErrors="Pleae add the required documents"
        return;
      }
      const formValid = await this.isFormValid(card); // Await the promise
      if(formValid){
      // this.getContactOfficerDocuments("Administrative",this.cards[1].details.organisationId,this.beforeEditemailForAdmin)
      if(this.beforeEditemailForAdmin!=card.details.adminEmail){
       this.updateEmailForDocs(this.beforeEditemailForAdmin,card.details.adminEmail,'Administrative');
      }
      
      this.updateAdministrativeContactDetails();
      card.details.isEditing = false;
      this.hideEditButton=false; 
      }
    }else if(card.heading === 'Technical Contact'){
      if(this.techDocDetails.length<2){
        this.techDocErrors="Pleae add the required documents"
        return
      }
      const formValid = await this.isFormValid(card); // Await the promise
      if(formValid){
        if(this.beforeEditemailForTech!=card.details.techEmail){
          this.updateEmailForDocs(this.beforeEditemailForTech,card.details.techEmail,'Technical');
         }
      this.updateTechnicalContactDetails();
      card.details.isEditing = false;
      this.hideEditButton=false; 
      }
    }else if(card.heading === 'Finance Contact'){
      if(this.billDocDetails.length<2){
        this.billDocErrors="Pleae add the required documents"
        return;
      }
      const formValid = await this.isFormValid(card); // Await the promise
      if(formValid){
        if(this.beforeEditemailForBill!=card.details.billEmail){
          this.updateEmailForDocs(this.beforeEditemailForBill,card.details.billEmail,'Billing');
         }
      this.updateBillingContactDetails();
      card.details.isEditing = false;
      this.hideEditButton=false; 
      }
    }else if(card.heading === 'Entity Details'){
      if(this.orgDocDetails.length<2){
        this.orgDocErrors="Pleae add the required documents"
        return;
      }
      var pincodeErrorMessage  = this.onPincodeChange();
      //console.log(pincodeErrorMessage)
      //console.log(this.organisationForm.get('city').value)
      this.cards[1].details.organisationId=this.organisationForm.get('organisationDetailsId').value,
         this.cards[1].details.institutionName =this.organisationForm.get('institutionName').value.toUpperCase() ,
          this.cards[1].details.stdCode =this.organisationForm.get('stdCode').value,
          this.cards[1].details.countryCode=this.organisationForm.get('countryCode').value,
          this.cards[1].details.stdTelephone=this.organisationForm.get('stdTelephone').value,
          this.cards[1].details.mobileNumber=this.organisationForm.get('mobileNumber').value,
          this.cards[1].details.organisationEmail=this.organisationForm.get('organisationEmail').value,
          this.cards[1].details.address=this.organisationForm.get('address').value,
          this.cards[1].details.pincode=this.organisationForm.get('pincode').value,
          this.cards[1].details.city=this.organisationForm.get('city').value,
          this.cards[1].details.district=this.organisationForm.get('district').value,
          this.cards[1].details.state=this.organisationForm.get('state').value,
          this.cards[1].details.userMailId=this.organisationForm.get('userMailId').value
          const formValid = await this.isFormValid(card); // Await the promise
          if(formValid&& this.pincodeErrMsg == ''){
    
        //console.log('valid')
          this.updateOrganisationDetails();
          card.details.isEditing = false;
          this.hideEditButton=false; 
      }else{
        card.details.isEditing = true;
        this.hideEditButton=true; 
      }
      
    }else if(card.heading === 'Domain Applying For'){
       //console.log("entered to sve this")
        if(card.details?.twoLetterDomainDocumentFileName!=''&&card.details.twoLetterDomainDocumentProof!=null){
            await this.updateDomainDetailsWithDoc();
           card.details.isEditing = false;
          this.hideEditButton=false;
        }else{
          this.boardApprovalDocErrors="Please upload the required document"
        }
        
    }
      
  }

 updateEmailForDocs(existingEmail,newEmail,type){
  this.contactDocumentsService.updateEmailForTheDocuments(existingEmail,newEmail,type).subscribe({
    next:(response)=>{
      //console.log("email updated successfully");
    },error:(error)=>{
      //console.log("error occured in updatingEmail")
    }
  })
 }
 

 async isFormValid(card: any): Promise<boolean> {
   if (card.length !== 7) {
     if (card.heading === 'Entity Details') {
       const orgMobileValid = await this.validatemobileNumber(card.details.mobileNumber, 'orgMobile');
       const orgStdValid = this.validatestdNumber(card.details.stdTelephone, 'orgStd');
       //console.log(card.details.institutionName, card.details.pincode, card.details.state, card.details.city, card.details.address, card.details.stdTelephone, orgStdValid, card.details.mobileNumber, orgMobileValid, card.details.organisationEmail);
 
       if (!this.organisationForm.invalid || !orgMobileValid) {
         return card.details.institutionName && card.details.pincode && card.details.state && card.details.city && card.details.address && card.details.stdTelephone && orgStdValid && card.details.mobileNumber && orgMobileValid && card.details.organisationEmail;
       } else {
         return false;
       }
     } else if (card.heading === 'Administrative Contact') {
       const adminAltMobileValid = await this.validatemobileNumber(card.details.adminAltPhone, 'adminMobile');
       const adminStdValid = this.validatestdNumber(card.details.adminPhone, 'adminStd');
 
       //console.log(adminAltMobileValid);
 
       return card.details.adminFullName && card.details.adminEmail &&
         card.details.adminCountryCode && card.details.adminAltCountryCode &&
         card.details.adminPhone && adminStdValid &&
         card.details.adminAltPhone && adminAltMobileValid &&
         card.details.adminDesignation && this.orgEmailError === '' &&
         card.details.adminAddress && card.details.adminAddress.length>4 && this.getEmailsofOrgAndContact()&& this.getEmailisAvailable(card.details.adminEmail,"Administrative Contact");
     } else if (card.heading === 'Finance Contact') {
       const billAltMobileValid = await this.validatemobileNumber(card.details.billAltPhone, 'billMobile');
       const billStdValid = this.validatestdNumber(card.details.billPhone, 'billStd');
 
       return card.details.billDesignation &&
         card.details.billCountryCode &&
         card.details.billAltCountryCode &&
         card.details.billAltPhone &&
         card.details.billAddress && card.details.billAddress.length>4 && 
         billAltMobileValid &&
         card.details.billPhone && billStdValid &&
         card.details.billEmail && card.details.billFullName && this.orgEmailError === ''&& this.getEmailsofOrgAndContact() && this.getEmailisAvailable(card.details.billEmail,"Finance Contact");
     } else if (card.heading === 'Technical Contact') {
       const techAltMobileValid = await this.validatemobileNumber(card.details.techAltPhone, 'techMobile');
       const techStdValid = this.validatestdNumber(card.details.techPhone, 'techStd');
 
       //console.log(card.details);
 
       return card.details.techFullName && card.details.techEmail &&
         card.details.techCountryCode && card.details.techAltCountryCode &&
         card.details.techPhone && card.details.techAltPhone &&
         techStdValid && techAltMobileValid &&
         card.details.techDesignation && this.orgEmailError === '' &&
         card.details.techAddress && card.details.techAddress.length>4 && this.getEmailsofOrgAndContact()&&this.getEmailisAvailable(card.details.techEmail,"Technical Contact");
     }  else if (card.heading === 'Name Server Details') {
  //console.log("🔍 Validating Name Server Details");

  const seenIPv4s = new Set<string>();
  const seenIPv6s = new Set<string>();
  const seenHostNames = new Set<string>();
  let hasError = false;

  // Step 1: Clear previous errors
  this.nameDetails.forEach((item, index) => {
    //console.log(`🔄 Clearing errors for item ${index + 1}`);
    item.duplicateIPError = null;
    item.duplicateIPV6Error = null;
    item.duplicateHostNameError = null;
    item.invalidIPv4FormatError = null;
    item.invalidIPv6FormatError = null;
    item.missingFieldError = null;
    item.tooManyDualIPsError=null;
    item.atLeastOneIPRequiredError = null;
  });

  
  const entriesWithBothIPs = this.nameDetails.filter(
  (item) => item.ipAddress?.trim() && item.ipv6Address?.trim()
);

if (entriesWithBothIPs.length > this.minimumCombinedIPS) {
  hasError = true;
 //console.warn("⚠️ More than 3 name servers have both IPv4 and IPv6 addresses.");
  entriesWithBothIPs.forEach((item, index) => {
    if (index >= this.minimumCombinedIPS) {
      item.tooManyDualIPsError = "Only up to 3 name servers can have both IPv4 and IPv6.";
    }
  });
}

  //console.log(`📋 Final Validation Result: hasError = ${hasError}`);
  return !hasError;
}else if(card.heading === 'DNS SEC Details'){
  // this.dnsSecRecordsOfDomain
   if (!this.dnsSecRecordsOfDomain || this.dnsSecRecordsOfDomain.length === 0) {
        return true;
      }

  for (let i = 0; i < this.dnsSecRecordsOfDomain.length; i++) {
    const dnsSec = this.dnsSecRecordsOfDomain[i];

    // 1. Key Tag: required & numeric
    if (!dnsSec.keyTag || !/^[0-9]+$/.test(dnsSec.keyTag)) {
      return false;
    }
    const keyTagValue = parseInt(dnsSec.keyTag, 10);
    if (isNaN(keyTagValue) || keyTagValue > 65535) {
      return false;
    }

    // 2. Algorithm Type: must have a code selected
    if (!dnsSec.algorithmTypeCode) {
      return false;
    }

    // 3. Digest Type: must have a code selected
    if (!dnsSec.digestTypeCode) {
      return false;
    }

    // 4. Digest: required
    if (!dnsSec.digest) {
      return false;
    }

    // 5. Digest must be unique
    const duplicate = this.dnsSecRecordsOfDomain.some(
      (other, j) => j !== i && other.digest?.trim() === dnsSec.digest?.trim()
    );
    if (duplicate) {
      return false;
    }
  }

  return true;
}else{
  return true
}
   } else if (card.length === 6) {
     const orgMobileValid = await this.validatemobileNumber(card[1].details.mobileNumber, 'orgMobile');
     const orgStdValid = this.validatestdNumber(card[1].details.stdTelephone, 'orgStd');
     const adminAltMobileValid = await this.validatemobileNumber(card[2].details.adminAltPhone, 'adminMobile');
     const adminStdValid = this.validatestdNumber(card[2].details.adminPhone, 'adminStd');
     const techAltMobileValid = await this.validatemobileNumber(card[3].details.techAltPhone, 'techMobile');
     const techStdValid = this.validatestdNumber(card[3].details.techPhone, 'techStd');
     const billAltMobileValid = await this.validatemobileNumber(card[4].details.billAltPhone, 'billMobile');
     const billStdValid = this.validatestdNumber(card[4].details.billPhone, 'billStd');
 
    
 
     return card[1].details.institutionName && card[1].details.pincode && card[1].details.city && card[1].details.state && card[1].details.address && card[1].details.stdTelephone && card[1].details.mobileNumber &&
       card[1].details.organisationEmail && card[2].details.adminFullName && card[2].details.adminEmail && card[2].details.adminPhone && card[2].details.adminAltPhone && card[2].details.adminDesignation &&
       card[3].details.techFullName && card[3].details.techEmail && card[3].details.techPhone && card[3].details.techAltPhone && card[3].details.techDesignation &&
       card[4].details.billDesignation && card[4].details.billAltPhone && card[4].details.billPhone && card[4].details.billEmail && card[4].details.billFullName && this.isNameServerDetailsInvalid();
   } else {
     return false;
   }
 }


minimumCombinedIPS:number=0;
getAllStaticData() {
  this.registrationService.getAllStaticData().subscribe({
    next: (response: any[]) => { // Add a type annotation for better safety
      //console.log(response);

      // Iterate through the response array and assign values
      response.forEach(item => {
        switch (item.type) { 
          
            case 'minimumCombinedIps':
            this.minimumCombinedIPS = Number(item.value);
            break;
          // Add other cases if you need to assign other values later
        }
        // this.populateCostItems();
        
      });

      

    },
    error: (error) => {
     //console.error('Error fetching static data:', error);
      if(error.status == HttpStatusCode.Unauthorized){
         this.router.navigateByUrl('/session-timeout');
      }
      // Handle error appropriately, e.g., show a user-friendly message
    }
  });
}

globalNameServerError:string=''
vailidationNameServerHostName: any[] = []



async validateNameServerDetails(): Promise<boolean> {
  const seenIPv4s = new Map<string, number>();
  const seenIPv6s = new Map<string, number>();
  const seenHostNames = new Map<string, number>();

  let hasError = false;
  let dualStackCount = 0;

  //console.log("🔄 Starting Name Server Validation");

  // Clear previous errors
  this.nameDetails.forEach((item, index) => {
    item.duplicateIPError = null;
    item.duplicateIpV6Error = null;
    item.duplicateHostNameError = null;
    item.invalidIPv4FormatError = null;
    item.invalidIPv6FormatError = null;
    item.missingFieldError = null;
    item.atLeastOneIPRequiredError = null;
    item.hostNameFormatError = null;
    item.tooManyDualIPsError = null;
    //console.log(`🚿 Cleared previous errors for row ${index}`);
  });

  this.globalNameServerError = null;

  for (let i = 0; i < this.nameDetails.length; i++) {
    const item = this.nameDetails[i];
    const hostName = item.hostName?.trim() || "";
    const ipAddress = item.ipAddress?.trim() || "";
    const ipv6Address = item.ipv6Address?.trim() || "";
    const ipServiceProvider = item.ipServiceProvider?.trim() || "";
    const dnsServiceProvider = item.dnsServiceProvider?.trim() || "";

    //console.log(`\n🔍 Validating entry [${i}]`);
    //console.log("Host:", hostName);
    //console.log("IPv4:", ipAddress);
    //console.log("IPv6:", ipv6Address);

    let isIPv4FormatValid = true;
    let isIPv6FormatValid = true;
    let isHostNameFormatValid = true;

    // --- A. Required Fields ---
    if (!hostName || !ipServiceProvider || !dnsServiceProvider) {
      item.missingFieldError = "Host Name, IP Service Provider, and DNS Service Provider are required.";
     //console.warn(`⚠️ Missing required fields at index ${i}`);
      hasError = true;
    }

    if (!ipAddress && !ipv6Address) {
      item.atLeastOneIPRequiredError = "At least one IP address (IPv4 or IPv6) is required.";
     //console.warn(`⚠️ No IP provided at index ${i}`);
      hasError = true;
    }

    if (ipAddress && !this.isValidIP(ipAddress)) {
      item.invalidIPv4FormatError = "Invalid IPv4 Address format.";
      //console.error(`❌ Invalid IPv4 at index ${i}:`, ipAddress);
      isIPv4FormatValid = false;
      hasError = true;
    }

    if (ipv6Address && !this.isValidIPV6(ipv6Address)) {
      item.invalidIPv6FormatError = "Invalid IPv6 Address format.";
      //console.error(`❌ Invalid IPv6 at index ${i}:`, ipv6Address);
      isIPv6FormatValid = false;
      hasError = true;
    }

    if (ipAddress && ipv6Address && isIPv4FormatValid && isIPv6FormatValid) {
      dualStackCount++;
      //console.log(`✅ Dual-stack detected at index ${i}`);

      if (dualStackCount > 3) {
        item.tooManyDualIPsError = "Only 3 name servers can have both IPv4 and IPv6 addresses.";
        hasError = true;
       //console.warn(`⚠️ Dual-stack limit exceeded at index ${i}`);
      }
    }

    const hostFormatError = this.validateHostNameFormat(hostName, i);
    if (hostFormatError) {
      item.hostNameFormatError = hostFormatError;
      //console.error(`❌ Hostname format error at index ${i}:`, hostFormatError);
      isHostNameFormatValid = false;
      hasError = true;
    }

    // --- B. Local Duplicate Checks ---
    if (ipAddress && isIPv4FormatValid) {
      if (seenIPv4s.has(ipAddress)) {
        const firstIndex = seenIPv4s.get(ipAddress)!;
        this.nameDetails[firstIndex].duplicateIPError = "Duplicate IPv4 Address found!";
        item.duplicateIPError = "Duplicate IPv4 Address found!";
       //console.warn(`⚠️ Duplicate IPv4 found at index ${i}, first at index ${firstIndex}`);
        hasError = true;
      } else {
        seenIPv4s.set(ipAddress, i);
        //console.log(`🧠 Storing IPv4 in seenIPv4s map: ${ipAddress}`);
      }
    }

    if (ipv6Address && isIPv6FormatValid) {
      if (seenIPv6s.has(ipv6Address)) {
        const firstIndex = seenIPv6s.get(ipv6Address)!;
        this.nameDetails[firstIndex].duplicateIpV6Error = "Duplicate IPv6 Address found!";
        item.duplicateIpV6Error = "Duplicate IPv6 Address found!";
       //console.warn(`⚠️ Duplicate IPv6 found at index ${i}, first at index ${firstIndex}`);
        hasError = true;
      } else {
        seenIPv6s.set(ipv6Address, i);
        //console.log(`🧠 Storing IPv6 in seenIPv6s map: ${ipv6Address}`);
      }
    }

    if (hostName && isHostNameFormatValid) {
      const lowerHost = hostName.toLowerCase();
      if (seenHostNames.has(lowerHost)) {
        const firstIndex = seenHostNames.get(lowerHost)!;
        this.nameDetails[firstIndex].duplicateHostNameError = "Duplicate Host Name Found!";
        item.duplicateHostNameError = "Duplicate Host Name Found!";
       //console.warn(`⚠️ Duplicate hostname '${hostName}' found at index ${i}, first at index ${firstIndex}`);
        hasError = true;
      } else {
        seenHostNames.set(lowerHost, i);
        //console.log(`🧠 Storing hostname: ${lowerHost}`);
      }
    }

    // --- C. DB Validations ---
    //new
    // if (ipAddress && isIPv4FormatValid) {
    //   try {
    //     const exists = await lastValueFrom(this.previewService.validateIpAdress(ipAddress, item.domainId));
    //     if (exists) {
    //       item.duplicateIPError = "IPv4 Address already used by another domain.";
    //       hasError = true;
    //      //console.warn(`⚠️ DB IPv4 exists for ${ipAddress} at index ${i}`);
    //     }
    //   } catch (error) {
    //     item.duplicateIPError = "IPv4 Address is reserved.";
    //     hasError = true;
    //     //console.error("❌ DB IPv4 check failed:", error);
    //   }
    // }
//new
    // if (ipv6Address && isIPv6FormatValid) {
    //   try {
    //     const exists = await lastValueFrom(this.previewService.validateIpV6Adress(ipv6Address, item.domainId));
    //     if (exists) {
    //       item.duplicateIpV6Error = "IPv6 Address already used by another domain.";
    //       hasError = true;
    //      //console.warn(`⚠️ DB IPv6 exists for ${ipv6Address} at index ${i}`);
    //     }
    //   } catch (error) {
    //     item.duplicateIpV6Error = "IPv6 Address is reserved";
    //     hasError = true;
    //     //console.error("❌ DB IPv6 check failed:", error);
    //   }
    // }
  }

  //console.log(`📊 Total dual-stack name servers: ${dualStackCount}`);
  //console.log("✅ Validation completed. hasError =", hasError);
  return hasError;
}





   async validatemobileNumber(mobileNumber: string, contactMobileType: string): Promise<boolean> {
  //console.log("Mobile number :", mobileNumber);
  let isValid = false; 

  try {
    if (contactMobileType === "techMobile") {
      const validMobileFormat = await lastValueFrom(
        this.organisationDetailsService.validateCodeAndNumber(
          this.cards[3].details.techAltCountryCode,
          mobileNumber
        )
      );
      //console.log(validMobileFormat);
      if (!validMobileFormat) {
        this.techMobileNumberError = "Please enter a valid STD code or number.";
        isValid = false; // Set isValid to false when validation fails
      } else {
        this.techMobileNumberError = "";
        isValid = true; // Set isValid to true when validation succeeds
      }
    } else if (contactMobileType === "billMobile") {
      const validMobileFormat = await lastValueFrom(
        this.organisationDetailsService.validateCodeAndNumber(
          this.cards[4].details.billAltCountryCode,
          mobileNumber
        )
      );
      //console.log(validMobileFormat);
      if (!validMobileFormat) {
        this.billMobilenumberError = "Please enter a valid STD code or number.";
        isValid = false;
      } else {
        this.billMobilenumberError = "";
        isValid = true;
      }
    } else if (contactMobileType === "adminMobile") {
      const validMobileFormat = await lastValueFrom(
        this.organisationDetailsService.validateCodeAndNumber(
          this.cards[2].details.adminAltCountryCode,
          mobileNumber
        )
      );
      //console.log(validMobileFormat);
      if (!validMobileFormat) {
        this.adminMobileNumberError = "Please enter a valid STD code or number.";
        isValid = false;
      } else {
        this.adminMobileNumberError = "";
        isValid = true;
      }
    } else if (contactMobileType === "orgMobile") {
      //console.log()
      const validMobileFormat = await lastValueFrom(
        this.organisationDetailsService.validateCodeAndNumber(
          this.cards[1].details.countryCode,
          mobileNumber
        )
      );
      //console.log(validMobileFormat);
      if (!validMobileFormat) {
        this.orgMobileNumberError = "Please enter a valid STD code or number.";
        isValid = false;
      } else {
        this.orgMobileNumberError = "";
        isValid = true;
      }
    }
  } catch (error) {
    //console.error("Validation error:", error);
    if (contactMobileType === "techMobile") {
      this.techMobileNumberError = "Please try again.";
    } else if (contactMobileType === "billMobile") {
      this.billMobilenumberError = "Please try again.";
    } else if (contactMobileType === "adminMobile") {
      this.adminMobileNumberError = "Please try again.";
    } else if (contactMobileType === "orgMobile") {
      this.orgMobileNumberError = "Please try again.";
    }
    isValid = false; // Set isValid to false on error
  }

  //console.log("Mobile number valid:", isValid);
  return isValid;
}
  techStdNumberError=''
  adminStdNumberError=''
  billStdnumberError=''
  orgStdNumberError=''
  techMobileNumberError=''
  adminMobileNumberError=''
  billMobilenumberError=''
  orgMobileNumberError=''
  validatestdNumber(mobileNumber: string,contactStdType): boolean {
    //console.log("STD number length:", mobileNumber);
    //console.log("Mobile number length:", mobileNumber);
    if(contactStdType=="techStd"){
      try {
        const validMobileFormat = lastValueFrom(
          this.organisationDetailsService.validatestdCodeAndNumber(
            this.cards[3].details.adminCountryCode,mobileNumber
          )
        );
       //console.log(validMobileFormat)
        if (!validMobileFormat) { // Check for false, not truthy
          this.techStdNumberError = "Please enter a valid STD code or number.";
        } else {
          this.isMobileNumberValid =this.techStdNumberError=="";
          this.techStdNumberError = ""; // Clear the error if valid
        }
      } catch (error) {
        //console.error("Validation error:", error);
        this.techStdNumberError = "Please try again.";
      }

      }

      else if(contactStdType=="billStd"){
        try {
          const validMobileFormat = lastValueFrom(
            this.organisationDetailsService.validatestdCodeAndNumber(
              this.cards[4].details.billCountryCode,mobileNumber
            )
          );
         //console.log(validMobileFormat)
          if (!validMobileFormat) { // Check for false, not truthy
            this.billStdnumberError = "Please enter a valid STD code or number.";
            this.isMobileNumberValid=false
          } else {
            this.isMobileNumberValid =this.billStdnumberError=="";
            this.billStdnumberError = ""; // Clear the error if valid
          }
        } catch (error) {
          //console.error("Validation error:", error);
          this.billStdnumberError = "Please try again.";
        }
  
        } else if(contactStdType=="adminStd"){
          try {
            const validMobileFormat = lastValueFrom(
              this.organisationDetailsService.validatestdCodeAndNumber(
                this.cards[2].details.billCountryCode,mobileNumber
              )
            );
           //console.log(validMobileFormat)
            if (!validMobileFormat) { // Check for false, not truthy
              this.adminStdNumberError = "Please enter a valid STD code or number.";
              this.isMobileNumberValid=false
            } else {
              this.isMobileNumberValid =this.adminStdNumberError=="";
              this.adminStdNumberError = ""; // Clear the error if valid
            }
          } catch (error) {
            //console.error("Validation error:", error);
            this.adminStdNumberError = "Please try again.";
          }
    
          }else if(contactStdType=="orgStd"){
            try {
              const validMobileFormat = lastValueFrom(
                this.organisationDetailsService.validatestdCodeAndNumber(
                  this.cards[1].details.billCountryCode,mobileNumber
                )
              );
             //console.log(validMobileFormat)
              if (!validMobileFormat) { // Check for false, not truthy
                this.orgStdNumberError = "Please enter a valid STD code or number.";
                this.isMobileNumberValid=false
              } else {
                this.isMobileNumberValid =this.orgStdNumberError=="";
                this.orgStdNumberError = ""; // Clear the error if valid
              }
            } catch (error) {
              //console.error("Validation error:", error);
              this.orgStdNumberError = "Please try again.";
            }
      
            }
    
    

   
    return this.isMobileNumberValid;
  }
  nameServerError:string=''
  duplicateIPError:string=''
  duplicateIpV6Error:string=''
  duplicateHostName: string = ''
 isNameServerDetailsInvalid(): boolean {
  const seenIPv4s = new Set<string>();
  const seenIPv6s = new Set<string>();
  const seenHostNames = new Set<string>();
  let hasError = false;

  let dualStackItems: any[] = []; // Stores items that have both valid IPv4 and IPv6

  // Step 1: Clear all previous validation errors
  this.nameDetails.forEach(item => {
    item.duplicateIPError = null;
    item.duplicateIPV6Error = null;
    item.duplicateHostNameError = null;
    item.invalidIPv4FormatError = null;
    item.invalidIPv6FormatError = null;
    item.missingFieldError = null;
    item.atLeastOneIPRequiredError = null;
    item.tooManyDualIPsError = null;
  });

  // Step 2: Loop through nameDetails to validate each row
  for (let i = 0; i < this.nameDetails.length; i++) {
    const item = this.nameDetails[i];

    const hostName = item.hostName?.trim() || "";
    const ipv4 = item.ipAddress?.trim() || "";
    const ipv6 = item.ipv6Address?.trim() || "";
    const ipSP = item.ipServiceProvider?.trim() || "";
    const dnsSP = item.dnsServiceProvider?.trim() || "";

    // Required fields
    if (!hostName || !ipSP || !dnsSP) {
      item.missingFieldError = "Host Name, IP Service Provider, and DNS Service Provider are required.";
      hasError = true;
    }

    // At least one IP
    if (!ipv4 && !ipv6) {
      item.atLeastOneIPRequiredError = "At least one IP address (IPv4 or IPv6) is required.";
      hasError = true;
    }

    // IPv4 format & duplication
    let isIPv4Valid = false;
    if (ipv4) {
      if (!this.isValidIP(ipv4)) {
        item.invalidIPv4FormatError = "Invalid IPv4 Address format.";
        hasError = true;
      } else {
        isIPv4Valid = true;
        if (seenIPv4s.has(ipv4)) {
          item.duplicateIPError = "Duplicate IPv4 Address found!";
          hasError = true;
        } else {
          seenIPv4s.add(ipv4);
        }
      }
    }

    // IPv6 format & duplication
    let isIPv6Valid = false;
    if (ipv6) {
      if (!this.isValidIPV6(ipv6)) {
        item.invalidIPv6FormatError = "Invalid IPv6 Address format.";
        hasError = true;
      } else {
        isIPv6Valid = true;
        if (seenIPv6s.has(ipv6)) {
          item.duplicateIPV6Error = "Duplicate IPv6 Address found!";
          hasError = true;
        } else {
          seenIPv6s.add(ipv6);
        }
      }
    }

    // Hostname duplication
    if (hostName) {
      if (seenHostNames.has(hostName)) {
        item.duplicateHostNameError = "Duplicate Host Name found!";
        hasError = true;
      } else {
        seenHostNames.add(hostName);
      }
    }

    // Track items with both valid IPv4 and IPv6
    if (isIPv4Valid && isIPv6Valid) {
      dualStackItems.push(item);
    }
  }

  // Step 3: Enforce the rule — max 3 items with both IPv4 and IPv6
  if (dualStackItems.length > 3) {
    hasError = true;
    dualStackItems.slice(3).forEach(item => {
      item.tooManyDualIPsError = "Cannot have more than 3 Name Servers with both IPv4 and IPv6 addresses.";
    });
  }

  return hasError;
}
  isValidIP(ip: string): boolean {
    const ipPattern = /^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$/
    return ipPattern.test(ip);
  }
  
   isValidIPV6(ip: string): boolean {
    const ipPattern =   /^((?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?=(?:.*::.*)(?!.*::.*))((?:[0-9a-fA-F]{1,4}:)*:([0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4})?)$/
    return ipPattern.test(ip);
  }
  

  // Cancel changes for a specific card

  async getOrgDocs(){
    this.orgDocDetails=[]
    this.orgDocService.getOrgDoucumentsById(this.user.organisationId).subscribe({
          next: (response) => {
            if(response.body.length > 0){
             //console.log(response.body)
             response.body.forEach(orgDoc => {
               var doc = { type: '', fileName: '', file: new Blob(),value: '',fileSize:0  };
               doc.type = orgDoc.documentType;
               //console.log(doc.type)
               doc.fileName = orgDoc.fileName;
               doc.value = 'xyz'
              
               if (doc.type === 'PAN') {
                //console.log(orgDoc.panDocument)
                doc.value = orgDoc.panNumber;
                if(doc.fileName.endsWith('.pdf')){
                  doc.file = this.base64ToBlob(orgDoc.panDocument,'application/pdf');
                   doc.fileSize=doc.file.size
                }else if(doc.fileName.endsWith('.jpg')){
                  doc.file = this.base64ToBlob(orgDoc.panDocument,'image/jpg');
                  doc.fileSize=doc.file.size 
                }else if(doc.fileName.endsWith('jpeg')){
                  doc.file = this.base64ToBlob(orgDoc.panDocument,'image/jpeg'); 
                  doc.fileSize=doc.file.size
                }
              
               } else if (doc.type === 'License Given By RBI') {
                doc.value = orgDoc.licenseNumber;
                //console.log(orgDoc.licenseDocument);
                if (doc.fileName.endsWith('.pdf')) {
                    doc.file = this.base64ToBlob(orgDoc.licenseDocument, 'application/pdf');
                    doc.fileSize=doc.file.size
                } else if (doc.fileName.endsWith('.jpg')) {
                    doc.file = this.base64ToBlob(orgDoc.licenseDocument, 'image/jpg');
                    doc.fileSize=doc.file.size
                } else if (doc.fileName.endsWith('.jpeg')) {
                    doc.file = this.base64ToBlob(orgDoc.licenseDocument, 'image/jpeg');
                    doc.fileSize=doc.file.size
                }
               } else if(doc.type === 'Board Resolution') {
                //console.log(orgDoc.boardResolutionDocument);
                doc.value = '';
                if (doc.fileName.endsWith('.pdf')) {
                    doc.file = this.base64ToBlob(orgDoc.boardResolutionDocument, 'application/pdf');
                    doc.fileSize=doc.file.size
                } else if (doc.fileName.endsWith('.jpg')) {
                    doc.file = this.base64ToBlob(orgDoc.boardResolutionDocument, 'image/jpg');
                    doc.fileSize=doc.file.size
                } else if (doc.fileName.endsWith('.jpeg')) {
                    doc.file = this.base64ToBlob(orgDoc.boardResolutionDocument, 'image/jpeg');
                    doc.fileSize=doc.file.size
                }
               }else if(doc.type === 'Organization GSTIN'){
                // //console.log(orgDoc.organisationDocument);
               
                if (doc.fileName.endsWith('.pdf')) {
                    doc.file = this.base64ToBlob(orgDoc.organisationGstinDocument, 'application/pdf');
                    doc.fileSize=doc.file.size
                } else if (doc.fileName.endsWith('.jpg')) {
                    doc.file = this.base64ToBlob(orgDoc.organisationGstinDocument, 'image/jpg');
                    doc.fileSize=doc.file.size
                } else if (doc.fileName.endsWith('.jpeg')) {
                    doc.file = this.base64ToBlob(orgDoc.organisationGstinDocument, 'image/jpeg');
                    doc.fileSize=doc.file.size
                }
               }
               
               //console.log(doc); 
      
             
               this.orgDocDetails.push(doc);
             })
            }
          }   
        });
  }
  base64ToBlob(base64: string, contentType: string = '') {
    const byteCharacters = atob(base64);
    const byteArrays = [];
  
    for (let offset = 0; offset < byteCharacters.length; offset += 512) {
      const slice = byteCharacters.slice(offset, offset + 512);
  
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
  
      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
  
    return new Blob(byteArrays, { type: contentType });
  }
  getExistingDocsOfAOBOTOofficers(){
    //console.log('enetered')
  this.contactDocumentsService.getContactOfficerDocuments('Administrative', this.organisationId).subscribe({
    next: (response) => {
      //this.techUploadedDocs = response.body;
      if(response.body.length > 0){
       //console.log(response.body)
       response.body.forEach(adminDoc => {
         var doc = { type: '', filename: '', file: new Blob(), value:'' };
         //console.log(adminDoc.fileName.endsWith('pdf'))
         if(adminDoc.fileName.endsWith('pdf')){
          doc.type = 'application/pdf';
         }else if(adminDoc.fileName.endsWith('png')){
          doc.type = 'image/png';
         }else if(adminDoc.fileName.endsWith('jpg')){
          doc.type = 'image/jpg';
         }else if(adminDoc.fileName.endsWith('jpeg')){
          doc.type = 'image/jpeg';
         }
         //doc.type = adminDoc.documentType;
         doc.filename = adminDoc.fileName;
         //console.log(adminDoc.documentType)
         if (adminDoc.documentType === 'Aadhaar') {
          
           doc.file = this.base64ToBlob(adminDoc.aadharDocument, doc.type);
           doc.value = adminDoc.aadharNumber;
         } else if (adminDoc.documentType === 'PAN') {
           doc.file = this.base64ToBlob(adminDoc.panDocument, doc.type);
           doc.value = adminDoc.panNumber;
         } else if(adminDoc.documentType === 'Organization Identity Card') {
           doc.file =  this.base64ToBlob(adminDoc.organisationIdDocument, doc.type);
           doc.value = '';
         }
         
         //console.log(doc); 
         
         const file = new File([doc.file],adminDoc.fileName,{type:doc.type})
         
         const uploadedDoc = {
          type: adminDoc.documentType,
          fileName: doc.filename,
          fileSize: file.size, // Optional for extra checks
          value: doc.value ,
          organisationId: adminDoc.organisationId,
          contactType:'Administrative',
          file: file
        };
        this.adminDocDetails.push(uploadedDoc);
         
       })
     
      }
    }   
  });

  this.contactDocumentsService.getContactOfficerDocuments('Billing', this.organisationId).subscribe({
    next: (response) => {
      if(response.body.length > 0){
        //console.log(response.body);
        
        response.body.forEach(billDoc => {
          var doc = { type: '', filename: '', file: new Blob(), value: '' };

          // Set MIME type based on file extension
          if(billDoc.fileName.endsWith('pdf')){
            doc.type = 'application/pdf';
          } else if(billDoc.fileName.endsWith('png')){
            doc.type = 'image/png';
          } else if(billDoc.fileName.endsWith('jpg')){
            doc.type = 'image/jpg';
          } else if(billDoc.fileName.endsWith('jpeg')){
            doc.type = 'image/jpeg';
          }

          doc.filename = billDoc.fileName;

          // Assign corresponding file and value
          if (billDoc.documentType === 'Aadhaar') {
            
            doc.file = this.base64ToBlob(billDoc.aadharDocument, doc.type);
            doc.value = billDoc.aadharNumber;
          } else if (billDoc.documentType === 'PAN') {
           
            doc.file =  this.base64ToBlob(billDoc.panDocument, doc.type);
            doc.value = billDoc.panNumber;
          } else if(billDoc.documentType === 'Organization Identity Card') {
            
            doc.file = this.base64ToBlob(billDoc.organisationIdDocument, doc.type);
            doc.value = '';
          }

          //console.log(doc);

          // Convert Blob to File
          const file = new File([doc.file], billDoc.fileName, { type: doc.type });

        
          const uploadedDoc = {
            type: billDoc.documentType,
            fileName: doc.filename,
            fileSize: file.size, // Optional for extra checks
            value: doc.value||null,
            organisationId: billDoc.organisationId,
            file: file,
            contactType: 'Billing'
          };

          this.billDocDetails.push(uploadedDoc)
        });
        // this.billDocDetails.emit(this.billingUploadedDocs);
      }
    }
});


this.contactDocumentsService.getContactOfficerDocuments('Technical', this.organisationId).subscribe({
  next: (response) => {
    if(response.body.length > 0){
      //console.log(response.body);

      response.body.forEach(techDoc => {
        var doc = { type: '', filename: '', file: new Blob(), value: '' };

        // Set MIME type based on file extension
        if (techDoc.fileName.endsWith('pdf')) {
          doc.type = 'application/pdf';
        } else if (techDoc.fileName.endsWith('png')) {
          doc.type = 'image/png';
        } else if (techDoc.fileName.endsWith('jpg')) {
          doc.type = 'image/jpg';
        } else if (techDoc.fileName.endsWith('jpeg')) {
          doc.type = 'image/jpeg';
        }

        doc.filename = techDoc.fileName;

        // Assign corresponding file and value
        if (techDoc.documentType === 'Aadhaar') {
          doc.file = this.base64ToBlob(techDoc.aadharDocument, doc.type);
          // doc.file = techDoc.aadharDocument;
          doc.value = techDoc.aadharNumber;
        } else if (techDoc.documentType === 'PAN') {
          doc.file = this.base64ToBlob(techDoc.panDocument, doc.type);
          // doc.file = techDoc.panDocument;
          doc.value = techDoc.panNumber;
        } else if (techDoc.documentType === 'Organization Identity Card') {
          doc.file = this.base64ToBlob(techDoc.organisationIdDocument, doc.type);
          // doc.file = techDoc.organisationIdDocument;
          doc.value = '';
        }

        //console.log(doc);

        // Convert Blob to File
        const file = new File([doc.file], techDoc.fileName, { type: doc.type });

        const uploadedDoc = {
          type: techDoc.documentType,
          fileName: doc.filename,
          fileSize: file.size, // Optional for extra checks
          value: doc.value,
          organisationId: techDoc.organisationId,
          contactType: 'Technical',
          file: file
        };

        this.techDocDetails.push(uploadedDoc);
        // //console.log(uploadedDoc);
        // //console.log(this.techUploadedDocs);
      });
      // this.techDocDetails.emit(this.techUploadedDocs);
    }
  }
});

  }
  onCancel(card: any) {
    // Reset to original state (could use original data if needed)
    // card=this.clickedcard
    card.details.isEditing = false;
    this.validFullName=true
    if(card.heading === 'Name Server Details'){
      const cards=JSON.parse(this.clickedcard);
      Object.assign(this.nameDetails,cards);
      this.nameDetails.forEach(item => item.duplicateIPError = null);
      this.nameDetails.forEach(item => item.duplicateHostNameError = null);
    }else if(card.heading==="DNS SEC Details"){
      //  this.getDNSSECRrcordsByDomainId(this.domainId);
      // this.nameDetails.forEach(item => item.duplicateIPError = null);
      // this.nameDetails.forEach(item => item.duplicateHostNameError = null);
      } else{
      const cards=JSON.parse(this.clickedcard);
      Object.assign(card,cards);
      if(card.heading=== 'Entity Details'){
        // this.getOrgDocs();
        this.orgDocErrors='';
        this.documentUploadError=null;
        this.fetchOrgDocs.emit();
      }else if (card.heading!='Name Server Details'&&card.heading != 'Entity Details'){
       
       this.adminDocErrors='';
       this.techDocErrors='';
       this.billDocErrors='';
       this.adminDocUploadError=null;
       this.techDocUploadError=null;
       this.finDocUploadError=null;
       this.fetchDocs.emit();
      }
      
      
    }
   this.orgEmailError='';
   this.hideEditButton=false;
  
    //console.log(JSON.parse(this.clickedcard));
  }

  async updateDomainDetails(){
    //console.log("orgid in previw page"+this.organisationId)
    //console.log(this.cards[1].details.institutionName);
    this.cards[0].details.organisationId=this.organisationId;
    this.cards[0].details.organizationName = this.cards[1].details.institutionName;
    this.cards[0].details.submissionDate = format(new Date(), "yyyy-MM-dd'T'HH:mm:ss");
    this.cards[0].details.paymentStatus = 'Payment Not Done';
    this.cards[0].details.onBoardingStepIndex = 4;
    //this.cards[0].details.isOnboardingDomain = true;
    //this.cards[0].details.
    await lastValueFrom(this.domainService.updateDomainDetails(this.cards[0].details)).then(
      response => {
        if(response.status === HttpStatusCode.PartialContent){
          //console.log('Domain details updated successfully.'+this.cards[0]);
        }
      }, error => {
        if(error.status === HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
      }
    )
  }

  async navigateToSessionTimeout(){
    this.router.navigateByUrl('/session-timeout');
  }

  async updateOrganisationDetails(){
    //console.log(this.cards[1].details);
  //  this.cards[1].details.remainingFreeNameServers = Math.max(0, this.freeNSRecord - this.nameDetails.length);
  //  this.cards[1].details.aliasCountForOrganization = this.aliasCount;
    await lastValueFrom(this.organisationService
      .updateOrganisationDetails(this.cards[1].details)).then(
      response => {
        if(response.status === HttpStatusCode.Created){
          //console.log('Organization detail updated'+response.body);
        }
      }
    )
  }

  async updateAdministrativeContactDetails(){
    await lastValueFrom(this.conatctFormService.updateAdminDetails(this.cards[2].details)).then(
      response => {
        if(response.status === HttpStatusCode.Ok){
          //console.log('Admin details save successfully...'+response.body);
        }
      }
    )
  }

  async updateTechnicalContactDetails(){
    await lastValueFrom(this.conatctFormService.updateTechDetails(this.cards[3].details)).then(
      response => {
        if(response.status === HttpStatusCode.Ok){
          //console.log('Technical details save successfully...'+response.body)
        }
      }
    )
  }

  async updateBillingContactDetails(){
    await lastValueFrom(this.conatctFormService.updateBillDetails(this.cards[4].details)).then(
      response => {
        if(response.status === HttpStatusCode.Ok){
          //console.log('Finance details save successfully...'+response.body)
        }
      }
    )
  }

  async updateNameServers(){
   // this.nameDetails.array.forEach(element => {
     // element.organisationId=this.organisationId;
    //});
    //console.log(this.nameDetails)
   try {
  await lastValueFrom(this.namServerService.updateListNameServer(this.nameDetails))
    .then(
      response => {
        if (response.status === HttpStatusCode.Ok) {
          //console.log('Name Server details saved successfully', response.body);
          // Optional: Add logic here to display a success message to the user
          // this.toastr.success('Name Server details saved successfully!', 'Success');
        } else {
          // Handle cases where status is not OK but not an error (e.g., 204 No Content)
         //console.warn('Name Server details update completed with status:', response.status);
          // You might still want to show a success message or specific feedback
          // this.toastr.info('Name Server details update process completed.', 'Info');
        }
      }
    )
    .catch(
      error => {
        //console.error('Error saving Name Server details:', error);
        // Determine the type of error and provide user-friendly feedback
        if (error.status) {
          if (error.status === HttpStatusCode.BadRequest) {
            // Server-side validation error or malformed request
            //console.error('Bad Request (400):', error.error); // error.error might contain specific server errors
            // this.toastr.error(' Please check your inputs.', 'Error');
          } else if (error.status === HttpStatusCode.Unauthorized || error.status === HttpStatusCode.Forbidden) {
            // Authentication/Authorization error
            //console.error('Authentication/Authorization Error:', error);
            // this.toastr.error('You are not authorized to perform this action.', 'Access Denied');
          } else if (error.status === HttpStatusCode.InternalServerError) {
            // Generic server error
            //console.error('Internal Server Error (500):', error);
            // this.toastr.error('An unexpected server error occurred. Please try again later.', 'Server Error');
          } else {
            // Other HTTP errors
            // this.toastr.error(`An error occurred: ${error.status} - ${error.message || error.statusText}`, 'Error');
          }
        } else {
          // Network error or client-side error before request was sent
          //console.error('Network or client-side error:', error);
          // this.toastr.error('Could not connect to the server. Please check your internet connection.', 'Network Error');
        }
        // Optional: Add logic to display an error message to the user, e.g., using a Toastr service
        // this.toastr.error('Failed to save Name Server details. Please try again.', 'Error');
      }
    );
} catch (outerError) {
  
}
  }

  user: any;
  async getLoggedInUserDetails(){
    await lastValueFrom(this.userService.getUserByEmailId(this.userId)).then(
      response => {
        if(response.status === HttpStatusCode.Ok){
          this.user = response.body;
          //console.log(this.user);
          this.organisationId = this.user.organisationId;
          //this.updateOrganisationIdForUser(this.organisationId);
        }
      }, error => {
        if(error.status === HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
      }
    )
  }

  async updateUserOnboradingStatus(){
    this.user.onboardingStepIndex = 4;
    this.user.isOnboardingCompleted = true;
    await lastValueFrom(this.userService.updateUser(this.user)).then(
      response => {
        if(response.status === HttpStatusCode.PartialContent){
          //console.log(this.user);
        }
      }, error => {
        if(error.status === HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
      }
    )
  }

  async updatePreviewDetails(){
   await this.getAllDomainsListByOrgId(this.organisationId)
    //await this.getLoggedInUserDetails();
    //console.log(this.organisationId);
    //await this.updateUserOnboradingStatus();
    this.cards[0].details.applicationStatus = this.assetService.Submitted;
    await this.updateDomainDetails();
    this.updateOrganisationDetails();
    this.updateAdministrativeContactDetails();
    this.updateTechnicalContactDetails();
    this.updateBillingContactDetails();
    //this.updateNameServers();
    // await this.createInvoiceforDomain(this.domainId);
   
    this.toastr.success('Details updated successfully');
   // if(this.role === 'IDRBTADMIN'){
      this.router.navigateByUrl('/app-sbms');
    //}
  }

  

  async updateOrganisationIdForUser(organisationId: number){
    this.user.organisationId = organisationId;
    await lastValueFrom(this.userService.updateUser(this.user)).then(
        response => {
            if(response.status === HttpStatusCode.PartialContent){
                //console.log('org id updated for the user');
            }
        }, error => {
            if(error.status === HttpStatusCode.Unauthorized){
                this.router.navigateByUrl('/session-timeout');
            }
        }
    )
 }
  submissionAttempted=false;
  orgUploadedDocs=localStorage.getItem('orgDoc')?JSON.parse(localStorage.getItem('orgDoc')):[];
  @Input()adminDocDetails=[]
  @Input()techDocDetails =[]
  @Input()billDocDetails =[]
  @Input()orgDocDetails=[]
  @Output() setAdminUploadedDocs = new EventEmitter<any[]>();
  handleRemoveAdminDoc(index: number): void {
    this.submissionAttempted = false;
    this.adminDocDetails.splice(index, 1);
    // localStorage.setItem('admindocs',(JSON.stringify(this.adminDocDetails)))
   // this.setAdminUploadedDocs.emit(this.adminUploadedDocs);
  }
  handleRemovetechDoc(index: number): void {
    this.submissionAttempted = false;
    this.techDocDetails.splice(index, 1);
    // localStorage.setItem('techdocs',(JSON.stringify(this.techUploadedDocs)))
   // this.setAdminUploadedDocs.emit(this.adminUploadedDocs);
  }
  handleRemoveBillDoc(index: number): void {
    this.submissionAttempted = false;
    this.billDocDetails.splice(index, 1);
   // this.setAdminUploadedDocs.emit(this.adminUploadedDocs);
  //  localStorage.setItem('billdocs',(JSON.stringify(this.billUploadedDocs)))
  }
  handleRemoveOrgDoc(index: number): void {
    this.submissionAttempted = false;
    this.orgDocDetails.splice(index, 1);
    // localStorage.setItem('techdocs',(JSON.stringify(this.techUploadedDocs)))
   // this.setAdminUploadedDocs.emit(this.adminUploadedDocs);
  }
  handleTechValidationChange(isValid: boolean): void {
    //console.log('Validation status:', isValid);
  }

  setTechUploadedDocuments(docs: any[]): void {
      this.techDocDetails = docs;
      //console.log('Uploaded documents updated:', this.techDocDetails);
  }

  handleAdminValidationChange(isValid: boolean): void {
    //console.log('Validation status:', isValid);
  }

  setAdminUploadedDocuments(docs: any[]): void {
    this.adminDocDetails = docs;
    //console.log('Uploaded documents updated:', this.adminDocDetails);
  }

  handleBillingValidationChange(isValid: boolean): void {
    //console.log('Validation status:', isValid);
  }

  setBillingUploadedDocuments(docs: any[]): void {
    //console.log(docs)
    this.billDocDetails = docs;
    //console.log('Uploaded documents updated:', this.billDocDetails);
  }
  handleOrganisationValidationChange(isValid: boolean): void {
    //console.log('Validation status:', isValid);
}

setOrganisationUploadedDocuments(docs: any[]): void {
    this.orgDocDetails = docs;
    // localStorage.setItem('orgDoc',JSON.stringify(this.organisationUploadedDocs));
    //console.log('Uploaded documents updated:', this.orgDocDetails);
}

pdfUrl:any;
imagUrl:any;
pdfFile: any;
imagefile: any;
preview:string="preview"
onPdfViewClick(dataUrl) {
  //console.log(dataUrl);
  this.imagUrl = null;
  this.pdfUrl = dataUrl;
}

onImageViewClick(dataUrl) {
  //console.log(dataUrl);
  this.pdfUrl = null;
  this.imagUrl = dataUrl;
}

checkBoxChecked:boolean=false
toggleModal(): void {
  const checkbox = event.target as HTMLInputElement; 
  if (checkbox.checked) { // Only execute when checkbox is selected
    this.checkBoxChecked = true;
    this.isLoading = true;
    this.getDscResponse();
    
    const modalElement = document.getElementById('passwordModal');
    if (modalElement) {
      this.modalInstance = new bootstrap.Modal(modalElement, {
        backdrop: 'static',  
        keyboard: false      
      });
      this.modalInstance.show(); // Show modal
    }
  }
}

closePasswordModal() {
 //console.log(this.isSigned)
  if (!this.isSigned) {
    this.checkBoxChecked = false; // Uncheck the checkbox if not signed
  }
  this.modalInstance.hide();  // Hide the modal
  this.tokenPassword = '';
  this.passwordErrorMessage = '';
  this.tokens = [];
  this.certificates = [];
  this.selectedToken = "";
  this.selectedCertificate = "";
}
navigateToAuthenticationError() {
  this.router.navigateByUrl("/authentication-error"); // Navigate to the session-timeout route
}
getDscResponse() {
  this.isLoading = true;
  this.http.get(`${this.dscApi}/dsc/getTokenRequest`).subscribe(
    (response: any) => {
      //console.log('Response from getTokenRequest API:', response);
      if (response && response.encryptedData && response.encryptionKeyID) {
        const payload = {
          encryptedRequest: response.encryptedData,
          encryptionKeyID: response.encryptionKeyID
        };
        this.http.post(`${this.embridgeUrl}/DSC/ListToken`, payload).subscribe(
          (embridgeListTokenAPI: any) => {
            //console.log('Response from embridge ListToken API:', embridgeListTokenAPI);
            if (embridgeListTokenAPI) {
              const embridgeListTokenAPIData = embridgeListTokenAPI.responseData;
              this.http.get(`${this.dscApi}/dsc/getTokenList?data=${encodeURIComponent(embridgeListTokenAPIData)}`).subscribe(
                  (response: any) => {
                      //console.log('Response from getTokenList API:', response);
                      if(response.tokenNames != null && response.tokenNames.length != 0){
                        this.tokens = response.tokenNames;
                        this.isLoading = false;
                        this.passwordErrorMessage = '';
                        this.modalInstance.show();
                        this.toastr.success("Fetched tokens successfully");
                      }
                      else{
                        this.tokens = [];
                        this.isLoading = false;
                        this.passwordErrorMessage = '';
                        this.toastr.error("Failed to fetch tokens");
                        this.toastr.warning("If DSC token is not inserted, please insert your DSC Token");
                      }
                      //console.log('====================================>'+this.selectedToken);
                  },
                  (error) => {
                      //console.error('Failed to get valid tokens.', error);
                      this.isLoading = false;
                      this.tokens = [];
                      this.toastr.warning("If DSC token is not inserted, please insert your DSC Token");
                  }
              );

            }
            else{
              this.isLoading = false;
              this.tokens = [];
            }
          },
          (embridgeListTokenAPIError) => {
            //console.error('Failed to get valid tokens. Error in embridge ListToken API: ', embridgeListTokenAPIError);
            this.passwordErrorMessage = 'Failed to get valid tokens.';
            this.isLoading = false;
            this.toastr.warning(
              "Please check if Embridge is installed and in running state. If not please install Embridge and run it!!!",
              "Warning",
              {
                timeOut: 20000,
                progressBar: true,
                closeButton: true
              }
            );
          }
        );
      } else {
        this.passwordErrorMessage = 'Failed to get valid tokens.';
        this.isLoading = false;
        this.tokens = [];
        this.toastr.warning("If DSC token is not inserted, please insert your DSC Token");
      }
    },
    (error) => {
      //console.error('Error occurred while fetching tokens from the getTokenRequest API:', error);
      this.isLoading = false;
      this.tokens = [];
      this.toastr.warning("If DSC token is not inserted, please insert your DSC Token");
      this.toastr.warning(
        "Please check if Embridge is installed and in running state. If not please install Embridge and run it!!!",
        "Warning",
        {
          timeOut: 20000,
          progressBar: true,
          closeButton: true
        }
      );
    }
  );
}
showPassword = false;

togglePasswordVisibility() {
  this.showPassword = !this.showPassword;
}
onTokenSelect(){
  this.isLoading = true;
  //console.log('Selected Token:', this.selectedToken);
  this.http.get(`${this.dscApi}/dsc/getCertificateRequest?keyStoreDisplayName=${encodeURIComponent(this.selectedToken)}`).subscribe(
    (response: any) => {
      //console.log('Response from getCertificateRequest API:', response);
      if (response && response.encryptedData && response.encryptionKeyID) {
        const payload = {
          encryptedRequest: response.encryptedData,
          encryptionKeyID: response.encryptionKeyID
        };
        this.http.post(`${this.embridgeUrl}/DSC/ListCertificate`, payload).subscribe(
          (embridgeListCertificate: any) => {
            //console.log('Response from embridge ListCertificate API:', embridgeListCertificate);
            if (embridgeListCertificate) {
              const embridgeListCertificateData = {
                encryptedCertificateData: embridgeListCertificate.responseData
              };
              this.http.post(`${this.dscApi}/dsc/getCertificateList`, embridgeListCertificateData).subscribe(
                (response: any) => {
                    //console.log('Response from getCertificateList API:', response);
                    if(response.certificates != null && response.certificates.length != 0){
                      ////console.log(response.certificates[0].emailAddress);
                      //console.log(localStorage.getItem('email'));
                      const storedEmail = localStorage.getItem('email')?.trim().toLowerCase();
                      let emailMatched = false;
                      for (let certificate of response.certificates) {
                        const certificateEmail = certificate.emailAddress.trim().toLowerCase();
                        if(environment.isDSCEnabled){
                          if(certificateEmail === storedEmail){
                          //console.log('Email matches:', certificate.emailAddress);
                            this.certificates = response.certificates;
                            this.isLoading = false;
                            this.passwordErrorMessage = '';
                            this.toastr.success("Fetched certificates successfully");
                          emailMatched = true;
                          break;
                        }
                        else{
                          // //console.error('Emails do not match:', certificateEmail, storedEmail);
                          this.isLoading = false;
                          this.certificates = [];
                          this.navigateToAuthenticationError();
                            
                           break;
                        }
                        }else{
                          // if(certificateEmail === storedEmail){
                          // //console.log('Email matches:', certificate.emailAddress);
                            this.certificates = response.certificates;
                            this.isLoading = false;
                            this.passwordErrorMessage = '';
                            this.toastr.success("Fetched certificates successfully");
                          // emailMatched = true;
                          // break;
                       // }
                        //else{
                          // //console.error('Emails do not match:', certificateEmail, storedEmail);
                          //this.isLoading = false;
                          //this.certificates = [];
                          //this.navigateToAuthenticationError();
                            
                          // break;
                       // }
                        }
                       }
                    }
                      else{
                        this.certificates = [];
                        this.isLoading = false;
                        this.passwordErrorMessage = '';
                        this.toastr.error("Failed to fetch certificates from token");
                      }
                      //console.log(this.certificates);
                  },
                  (error) => {
                      //console.error('Error occurred while calling getCertificateList API:', error);
                      this.isLoading = false;
                      this.certificates = [];
                      this.passwordErrorMessage = '';
                      this.toastr.error("Failed to fetch certificates from token");
                  }
              );
            }
          },
          (embridgeListCertificateAPIError) => {
            //console.error('Error occurred while calling the embridge ListCertificate API:', embridgeListCertificateAPIError);
            this.isLoading = false;
            this.certificates = [];
            this.toastr.warning(
              "Please check if Embridge is installed and in running state. If not please install Embridge and run it!!!",
              "Warning",
              {
                timeOut: 20000,
                progressBar: true,
                closeButton: true
              }
            );
          }
        );  
      } else {
        this.isLoading = false;
        this.certificates = [];
        this.toastr.error("Failed to fetch certificates from token");
      }
    },
    (error) => {
      //console.error('Error occurred while fetching tokens from the getCertificateRequest API:', error);
      this.isLoading = false;
      this.certificates = [];
      this.toastr.error("Failed to fetch certificates from token");
    }
  );
}

buildFinalPreviewJson() {
  return {
    domainDetails: this.cards[0]?.details || {},
    organisationDetails: this.cards[1]?.details || {},
    administrativeContact: this.cards[2]?.details || {},
    technicalContact: this.cards[3]?.details || {},
    financeContact: this.cards[4]?.details || {},
    nameServerDetails: this.nameDetails || [],
    dnsSecDetails: this.dnsSecRecordsOfDomain || []
  };
}



onSign(){
  this.isLoading = true;
    //console.log('Selected Token:', this.selectedCertificate);
   const previewJson = this.buildFinalPreviewJson();
const jsonString = JSON.stringify(previewJson);
const hash = CryptoJS.SHA256(jsonString).toString();   // ✅ Generate hash properly


const signingRequestData = {
  keyId: this.selectedCertificate.keyId,
  keyStoreDisplayName: this.selectedToken,
  keyStorePassPhrase: this.tokenPassword,
  dataType: 'TextPKCS7',
  dataToSign: hash
};

    const encodedSigningRequestData = encodeURIComponent(JSON.stringify(signingRequestData));
    this.http.post(`${this.dscApi}/dsc/getSigningRequest`, signingRequestData).subscribe(
      (response: any) => {
        //console.log('Response from getSigningRequest API:', response);
        if (response && response.encryptedData && response.encryptionKeyID) {
          const payload = {
            encryptedRequest: response.encryptedData,
            encryptionKeyID: response.encryptionKeyID
          };
          this.http.post(`${this.embridgeUrl}/DSC/PKCSSign`, payload).subscribe(
            (embridgePKCSSignResponse: any) => {
              //console.log('Response from embridge PKCSSign API:', embridgePKCSSignResponse);
              if (embridgePKCSSignResponse) {
                const previewJson = this.buildFinalPreviewJson();
const payloadToSign = JSON.stringify(previewJson);

const embridgePKCSSignResponseData = {
  user: this.formData.name,
  userMailId: localStorage.getItem('email'),
  declaration: this.fullText,
  designation: this.formData.designation,
  organisation: this.formData.organisationName,
  isSigned: '',
  certificate: JSON.stringify(this.selectedCertificate),

  // 🔥 VERY IMPORTANT
  signedText: jsonString,
  payloadHash: hash,   
  
  encryptedSignedData: embridgePKCSSignResponse.responseData,
    organisationId: this.user.organisationId
};

                //console.log('==========================>   '+embridgePKCSSignResponseData.declaration);
                this.http.post(`${this.dscApi}/dsc/getSignedResponse`, embridgePKCSSignResponseData).subscribe(
                    (response: any) => {
                      this.closePasswordModal();
                        this.isLoading = false;
                      if (response.verificationStatus === "VERIFIED") {
      this.isSigned = true;
      this.signatureVerified = true;
      this.checkBoxChecked = true;
      this.lastSignedHash = hash;
      this.toastr.success("Signature Verified Successfully");
  } else {
      this.isSigned = false;
      this.signatureVerified = false;
      this.toastr.error("Signature Verification Failed");
  }

                        // this.isSigned=true;
                        //this.toastr.success("Signed using DSC successfully");
                        //this.isSigned=true;
                        //console.log('Response from third API:', response);
                       //this.checkBoxChecked=true;
                       
                        //console.log(response);
                       
                        // this.checkBoxChecked=true;
                        // this.router.navigateByUrl('/rgnt-domains');
                    },
                    (error) => {
                      const err = error?.error;
                      console.log(err)
                      if (err.errorCode === 'ERR001') {
                        this.isLoading = false;
                        this.toastr.warning("There is an issue with token, cannot proceed further.");
                      } else if(err.errorCode === 'ERR002'){
                        this.isLoading = false;
                        this.toastr.warning("Please use only the DSC issued by IDRBT. To obtain a DSC, kindly contact: casahyog@idrbt.ac.in, cahelp@idrbt.ac.in");
                      }
                      // ✅ 🔴 ADD THIS — REVOKED CERTIFICATE
                  else if (err?.errorCode === 'ERR006') {
                   this.toastr.error("Your DSC certificate has been REVOKED. Please contact your Certifying Authority.");
                  }
                      else {
                        //console.error('Error occurred while calling third API:', error);
                        this.isLoading = false;
                        this.toastr.warning("Make sure the Token PIN entered was right");
                      }                     
                    }
                );

              }
            },
            (embridgePKCSSignAPIError) => {
              //console.error('Error occurred while calling the embridge PKCSSign API:', embridgePKCSSignAPIError);
              this.isLoading = false;
              this.toastr.warning(
                "Please check if Embridge is installed and in running state. If not please install Embridge and run it!!!",
                "Warning",
                {
                  timeOut: 20000,
                  progressBar: true,
                  closeButton: true
                }
              );
            }
          );
        } else {
          this.isLoading = false;
          this.toastr.error("Enter token pin")
        }
      },
      (error) => {
        //console.error('Error occurred while fetching tokens from the getSigningRequest API:', error);
        this.isLoading = false;
        this.toastr.warning("Please ensure the all fields entered are correct");
      }
    );
}
isDisabled: boolean = true; 

   

// }

toggleModalCheckbox: boolean = false;  // Track the checkbox state
  isAuthorized: boolean = false;  // Whether the user has checked the box
  showError: boolean = false; 

preventSpecialChars(event: KeyboardEvent): void {
  const regex = /^[a-zA-Z\s]+$/; // Allows only alphabets and spaces
  const key = event.key;
  const inputElement = event.target as HTMLInputElement;

  // Prevent invalid characters
  if (!regex.test(key)) {
    event.preventDefault(); // Prevent the default behavior if the character is not allowed
  }

  // Prevent leading spaces (no space at the start of the input)
  if (key === ' ' && inputElement.value === '') {
    event.preventDefault(); // Block spaces if the input is empty
  }

  // Prevent consecutive spaces (no space after another space)
  if (key === ' ' && inputElement.value[inputElement.value.length - 1] === ' ') {
    event.preventDefault(); // Block an additional space if the last character is already a space
  }

  // Prevent space if no other characters have been entered yet
  if (key === ' ' && inputElement.value.length === 0) {
    event.preventDefault(); // Block space if the input is still empty
  }

  // Ensure at least one character (not just space) before allowing space
  if (key === ' ' && !/[a-zA-Z]/.test(inputElement.value)) {
    event.preventDefault(); // Block space if there are no alphabetic characters in the input yet
  }
}

isMobileNumberValid;
restrictNonNumeric(event: any): void {
  // Replace any non-numeric character with an empty string
  event.target.value = event.target.value.replace(/[^0-9]/g, '');


}

pincodeErrorMessage: string = ''
async onPincodeChange(): Promise<string> {
  // //console.log("+++++++++++++++++++++++++"+this.organisationForm.get('pincode')?.value)
  const pincode =this.organisationForm.get('pincode')?.value;
  //var pincodeErr = ''
  if (pincode && /^\d{6}$/.test(pincode)) {
      let isValidPincode= await this.fetchCityState(pincode);
      //console.log(this.pincodeErrMsg);
  } else {
    this.pincodeErrorMessage = 'Please enter valid pincode.'
    this.clearCityAndState();
  }
  //console.log(this.pincodeErrMsg);
  return this.pincodeErrorMessage;
  
}

pincodeErrMsg = '';
cityOptions: Array<{ name: string; district: string; state: string }> = [];
loading = false;
async fetchCityState(pincode: string) {
  this.loading = true;
  const pincodeMap = {
      "160034": { city: "Chandigarh", state: "Chandigarh" },
    };
    if(pincode!='160034'){
      //console.log("entered the fetchcity")
      this.organisationDetailsService.getPinCodeData(pincode).subscribe(
          (response: any) => {
              //console.log('API Response:', response);
              this.loading = false;

              if (response.body.length>0) {
                  const places = response.body

                  this.cityOptions = places.map((place: any) => ({
                    name: place.city + ', ' + place.district,
                    district: place.district,
                    state: place.state,
                }));
                 //console.log("cityOptions",this.cityOptions.length)
                  if (this.cityOptions.length > 0) {
                      this.organisationForm.patchValue({
                          city: this.cityOptions[0].name || '',
                          state: this.cityOptions[0].state || '',
                          district: this.cityOptions[0].district ||''
                      });
                      this.enableCityDropdown(); 
                      this.pincodeErrMsg = ''
                      //return true;
                  } else {
                      this.clearCityAndState();
                      //return false;
                  }
                 // return true;
              } else {
                  // //console.log("entered")
                    this.pincodeErrMsg = 'Invalid Pincode.'
                  this.clearCityAndState();
                  //return false;
              }
             // return true;
            //  if(response[0]?.Status === 'Error'){
            
            //  }else{
            //   this.pincodeErrMsg = '';
            //  }
          },
          (error) => {
              //console.error('Error fetching pincode details:', error);
              this.loading = false;
              this.clearCityAndState();
              //return false;
              
          }
      );
      //return true;
    }else if(pincode=="160034"){
       this.cityOptions = [{ name: 'Chandigarh', district: 'Chandigarh', state: 'Chandigarh' }];
            this.organisationForm.patchValue({
                city: this.cityOptions[0].name || '',
                state: this.cityOptions[0].state || '',
                district: this.cityOptions[0].district || '',
            });
      this.enableCityDropdown(); 
      //return true;
    }
    //return false;
  
}
enableCityDropdown(): void {
  // Enable city form control programmatically
  this.organisationForm.get('city')?.enable();
  this.organisationForm.get('state')?.enable();
  this.organisationForm.get('district')?.enable(); // Enable state form control as well
}
clearCityAndState(): void {
  this.cityOptions = [];

  this.organisationForm.patchValue({
      city: '',
      state: '',
  });
  this.organisationForm.get('city')?.disable();
  this.organisationForm.get('state')?.disable();
  this.organisationForm.get('district')?.disable();
}
orgEmailError=''
validateEmail(event) { // Pass the NgModel directive
  const email = event.target.value.trim();
  const emailRegex = new RegExp(this.regExp);

  if (email && !emailRegex.test(email)) {
    this.orgEmailError="Please enter valid email"
  } else {
    this.orgEmailError="" // Clear any previous error
  }
}
fullForm: FormGroup;
countryCodes:any;
async getAllCountryCodes(){
  this.organisationDetailsService.getAllCountryCodes().subscribe({
    next:(response)=>{
      this.countryCodes=response.body
      //console.log(this.countryCodes)
    }
  })
}

selectedAdminCountryCode: string='';  // For billPhone
selectedAdminAltCountryCode: string = ''; 
updateAdminCountryCode(event) {
  this.selectedAdminCountryCode = `${event.target.value}`;
  if (this.selectedAdminCountryCode) {
    this.fullForm.patchValue({ adminCountryCode: this.selectedAdminCountryCode });
  }
}
updateAdminAltCountryCode(event) {
  this.selectedAdminAltCountryCode = `${event.target.value}`;
  //console.log(this.selectedAdminAltCountryCode)
  this.cards[2].details.adminAltCountryCode=this.selectedAdminAltCountryCode
  if (this.selectedAdminAltCountryCode) {
    this.fullForm.patchValue({ adminAltCountryCode: this.selectedAdminAltCountryCode });
  }
}
selectedTechCountryCode: string = '';  // For billPhone
selectedTechAltCountryCode: string = ''; 
updateTechCountryCode(event) {
  this.selectedTechCountryCode = `${event.target.value}`;
  if (this.selectedTechCountryCode) {
    this.fullForm.patchValue({ techCountryCode: this.selectedTechCountryCode });
  }

}
updateTechAltCountryCode(event) {
  this.selectedTechAltCountryCode = `${event.target.value}`;
  //console.log(this.selectedTechAltCountryCode)
  this.cards[3].details.techAltCountryCode=this.selectedTechAltCountryCode
  if (this.selectedTechAltCountryCode) {
    this.fullForm.patchValue({ techAltCountryCode: this.selectedTechAltCountryCode });
  }
}
selectedBillCountryCode: string = '';  // For billPhone
selectedBillAltCountryCode: string = ''; 
updateBillCountryCode(event) {
  this.selectedBillCountryCode = `${event.target.value}`;
  if (this.selectedBillCountryCode) {
    this.fullForm.patchValue({ billCountryCode: this.selectedBillCountryCode });
  }
}
updateBillAltCountryCode(event) {
  this.selectedBillAltCountryCode = `${event.target.value}`;
  //console.log(this.selectedBillAltCountryCode)
  this.cards[4].details.billAltCountryCode=this.selectedBillAltCountryCode
  if (this.selectedBillAltCountryCode) {
    this.fullForm.patchValue({ billAltCountryCode: this.selectedBillAltCountryCode });
  }
}
async sanitizeInput(event: Event, controlName: string) {
  const input = event.target as HTMLInputElement;
  const sanitizedValue = input.value.replace(/[^0-9]/g, ''); // Allow only numbers
  //console.log(sanitizedValue)
  // Update the specific FormControl value
  this.organisationForm.get(controlName)?.setValue(sanitizedValue, { emitEvent: false });

  if (controlName === "mobileNumber") {
    await this.validatemobileNumber(sanitizedValue, "orgMobile");
    
  }
}
StdCodes;
selectedStdCode
async getAllStdCodes(){
    this.organisationDetailsService.getAllStdCodes().subscribe({
        next:(response)=>{
            this.StdCodes=response.body;
            //console.log(this.StdCodes)
        },error:(error)=>{
            if(error.status==HttpStatusCode.Unauthorized){
               // this.navigateToSessionTimeOut();
            }
        }
    })
}

updateStdCode(event){
  this.selectedStdCode=event.target.value
  if(this.selectedStdCode){
      this.organisationForm.patchValue({ stdCode: this.selectedStdCode });
      //console.log(this.organisationForm)
      // this.organisationForm.controls['stdTelephone'].enable();
  }else{
      // this.organisationForm.controls['stdTelephone'].disable();
  }
}

selectedCountryCode
updateCountryCode(event){
  this.selectedCountryCode=event.target.value
  if(this.selectedCountryCode){
      this.organisationForm.patchValue({ countryCode: this.selectedCountryCode });
      //console.log(this.organisationForm.value)
      // this.organisationForm.controls['mobileNumber'].enable();
  }else{
      // this.organisationForm.controls['mobileNumber'].disable();
  }
}

  async updateOnboardingStatus(){
    this.user.isOnboardingCompleted = true;
    this.userService.updateUser(this.user).subscribe({
      next:(response)=>{
        if(response.status === HttpStatusCode.PartialContent){
          //console.log('Onboarding status updated successfully');
        }
      },error:(error)=>{
        if(error.status === HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
      }
    })
  }

  async updateUserOnboardingStep(){
    //console.log('user: '+this.user)
    this.user.onboardingStepIndex = 4;
    this.user.isOnboardingCompleted = true;
    await lastValueFrom(this.userService.updateUser(this.user)).then(
      response => {
        if(response.status === HttpStatusCode.Ok){
          //console.log('User updated successfully'+response.body);
        }
      },error => {
        //console.error('Error occurred while updating user', error);
      });
  }

  validFullName: boolean = true; // To track if the full name is valid (at least one alphabet)

  allowAlphabetsOnly(event: any, field: string): void {
    let inputValue = event.target.value;

    // Remove characters that are not alphabets or spaces
    let validValue = inputValue.replace(/[^a-zA-Z\s]/g, '');

    // If the first character is a space, remove it (no leading spaces allowed)
    if (validValue.charAt(0) === ' ') {
      validValue = validValue.slice(1);
    }

    // If a space is entered at the end without any alphabet after it, remove it
    if (validValue.charAt(validValue.length - 1) === ' ' && validValue.length > 1 && !/[a-zA-Z]/.test(validValue.charAt(validValue.length - 2))) {
      validValue = validValue.slice(0, -1);
    }

    // Replace multiple spaces with a single space
    validValue = validValue.replace(/\s+/g, ' ');

    // Update the input field with the valid value
    event.target.value = validValue;

    // Check if there is at least one alphabet in the input
    this.validFullName = /[a-zA-Z]/.test(validValue);

    // Update the model with the valid value for the appropriate field
    if (field === 'adminFullName') {
      this.cards[2].details.adminFullName = validValue;
    } else if (field === 'billFullName') {
      this.cards[4].details.billFullName = validValue;
    } else if (field === 'techFullName') {
      this.cards[3].details.techFullName = validValue;
    }
  }

  

  domainsList: any[] = [];
  async getAllDomainsListByOrgId(orgId: number) {
    //console.log(orgId)
    await lastValueFrom(this.domainService.getAllDomainsByOrgId(orgId)).then(
      (response) => {
        if (response.status === HttpStatusCode.Ok) {
          this.domainsList = response.body;
          //console.log(this.domainsList)
        }
      },
      (error) => {
        if (error.status === HttpStatusCode.Unauthorized) {
          this.navigateToSessionTimeout();
        }
      }
    );
  }

 
  convertToUpperCase(event: Event): void {
    const inputElement = event.target as HTMLInputElement;
    inputElement.value = inputElement.value.toUpperCase(); // Convert the input value to uppercase
  }
  restrictInvalidKeys(event: KeyboardEvent): void {
    const key = event.key;
  
    // Check if the key is not a number or backspace
    if (!/^\d$/.test(key) && key !== 'Backspace' && key !== 'ArrowLeft' && key !== 'ArrowRight' && key !== 'Delete') {
      event.preventDefault();  // Block the key press
    }
  }

   getUniqueDistricts(): string[] {
  return Array.from(new Set(this.cityOptions.map(city => city.district)));
}
async updateOnBoardingCompleted(){
  // async updateOrganisationDetails(){
    
   this.cards[1].details.onBoardingCompleted=true;
   //console.log( this.cards[1].details.onBoardingCompleted)
    await lastValueFrom(this.organisationService
      .updateOrganisationDetails(this.cards[1].details)).then(
      response => {
        if(response.status === HttpStatusCode.Created){
          //console.log('Organization detail updated'+response.body);
        }
      }
    )
  // }
}
validateHostNameFormat(value: string, index: number): any | null {
  const validCharactersRegex = /^[a-zA-Z0-9-]+$/;

  // Rule 1: Only allowed characters
  if (!validCharactersRegex.test(value)) {
    this.vailidationNameServerHostName[index]=false
    return "Invalid Characters. Only alphanumeric and hyphens are allowed.";
  }else{
    this.vailidationNameServerHostName[index]=true
  }

  // Rule 2: No leading/trailing hyphens or underscores
  if (
    value.startsWith('-') || value.endsWith('-')
  ) {
   this.vailidationNameServerHostName[index]=false
    return "Host name cannot start or end with a hyphen";
  }else{
    this.vailidationNameServerHostName[index]=true
  }

  // Rule 3: No consecutive hyphens
  const consecutiveHyphensRegex = /--+/;
  if (consecutiveHyphensRegex.test(value)) {
     this.vailidationNameServerHostName[index]=false
    return  "Host name cannot contain consecutive hyphens";
  }else{
     this.vailidationNameServerHostName[index]=true
  }

  // Rule 4: No consecutive underscores
  const consecutiveUnderscoresRegex = /__+/;
  if (consecutiveUnderscoresRegex.test(value)) {
     this.vailidationNameServerHostName[index]=false
    return "Host name cannot contain consecutive hyphens";
  }else{
     this.vailidationNameServerHostName[index]=true
  }

  // Rule 5: No '--' in 3rd/4th unless punycode
  if (value.length >= 4 && !value.startsWith('xn--')) {
    const thirdAndFourth = value.substring(2, 4);
    if (thirdAndFourth === '--') {
       this.vailidationNameServerHostName[index]=false
      return { invalidThirdFourthHyphen: { value: value } };
    }else{
       this.vailidationNameServerHostName[index]=true
    }
  }

  return null; // ✅ Passed all validations
}

docNameForContact:string='';
docName:string=''
  setContactDocNameForModalHeading(docName){
    //console.log("hello")
      this.docNameForContact=docName
  }

    setEntityDocNameForModalHeading(docName){
      //console.log("hello")
      this.docName=docName
  }
  getYearToNumber(nummberToBeCasted):number{
    return Number(nummberToBeCasted);
  }
  priceDetails
  freeNSRecord:number=0
  maxNsRecord:number=0
 TypeScript

fetchThePriceDetails() {
  this.domainService.getAllPriceDetails().subscribe({
    next: (response) => {
      //console.log(response.body);
      this.priceDetails = response.body;

      // Ensure priceDetails is an array before using find
      if (Array.isArray(this.priceDetails)) {
        const priceDetail = this.priceDetails.find(
          (plan) => plan.typeForPrice === 'nameserver'
        );

        if (priceDetail) {
          //console.log(priceDetail + 'fetchThePriceDetails');
          // this.priceforNameServer=priceDetail.price*this.domain.numberOfYears; // Uncomment and use if domain.numberOfYears is defined
          this.freeNSRecord = priceDetail.nsRecordCount;
          this.maxNsRecord = priceDetail.maxNameServer;
        } else {
         //console.warn('Price details for "nameserver" not found.');
          // Handle the case where 'nameserver' price details are not found
        }
      } else {
        //console.error('response.body is not an array:', this.priceDetails);
        // Handle the case where response.body is not an array as expected
      }
    },
    error: (error) => {
      //console.error('Error fetching price details:', error); // Log the error for debugging
      // Handle the error appropriately, e.g., display a user-friendly message
    },
  });
}
aliasCount:number=0


regExp: string = '';
      getRegularExpressionForEmail() {
        // Assuming 'this.assetService' is where getEmailReqExp is defined
        this.registrationService.getEmailReqExp('email').subscribe({
          next: (response: string) => { // 👈 Make sure to expect a string here
            // 'response' is ALREADY the extracted 'value' string from the map operator.
            const respo = response[0] as any;
            this.regExp = respo.value.trim(); // Trim any whitespace
            //console.log('Email regex fetched and assigned:', this.regExp);
          },
          error: (error) => {
            //console.error('Error fetching email regex:', error);
            // Handle the error, e.g., set a default value or clear regExp
            this.regExp = ''; // Or null, depending on your default state
          }
        });
      }

    async getDNSSECRrcordsByDomainId(domainId: number){
  
  }

      dnsSecRecordsOfDomain: any = [];
      dnsSecRecordsCount: number = 0;
      
      async updateAllDnsSecRecords(){
        await lastValueFrom(this.dnsSecService.updateAllDnsSecRecords(this.dnsSecRecordsOfDomain)).then(
          response => {
            if(response.status === HttpStatusCode.PartialContent){
              this.toastr.success('DNS SEC records updated successfully');
            }
          },error => {
            if(error.status === HttpStatusCode.Unauthorized){
              this.navigateToSessionTimeout();
            }
          }
        )
      }
  algorithmTypeOptions = [];
  onAlgorithmChange(code: string, dns: DnssecDetails) {
 //console.log(this.algorithmTypeOptions)
  if (!code) {
    dns.algorithmTypeCode = null;
    dns.algorithmType = null;
    return;
  }

  const selected = this.algorithmTypeOptions.find(opt => opt.algorithmCode === code);
  if (selected) {
    dns.algorithmTypeCode = selected.algorithmCode;
    dns.algorithmType = selected.algorithmType;
  }
}

onDigestChange(code: string, dns: DnssecDetails) {
  if (!code) {
    dns.digestTypeCode = null;
    dns.digestType = null;
    return;
  }

  const selected = this.digestTypeOptions.find(opt => opt.digestTypeCode === code);
  if (selected) {
    dns.digestTypeCode = selected.digestTypeCode;
    dns.digestType = selected.digestType;
  }
}
  digestTypeOptions = [];
   async getDnsAlgorithmType() {
  try {
    const result = await lastValueFrom(this.dnsSecService.getDnsAlgorithmTypes());
   //console.log(result.body);
    this.algorithmTypeOptions = result.body;
    //  this.cdr.detectChanges();
  } catch (error) {
    // 
   if(error.status === HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
  }
}

async getDnsDigestType() {
  try {
    const result = await lastValueFrom(this.dnsSecService.getDnsDigestTypes());
   //console.log(result.body);
    this.digestTypeOptions = result.body;
  } catch (error) {
   //console.error('Error fetching DNS digest types:', error);
    if(error.status === HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
  }
}
isDigestDuplicate(currentIndex: number): boolean {
  const currentValue = this.dnsSecRecordsOfDomain[currentIndex].digest?.trim();
  if (!currentValue) return false;

  // Check if any other record has the same digest
  return this.dnsSecRecordsOfDomain.some((item, idx) => 
    idx !== currentIndex && item.digest?.trim() === currentValue
  );
}
async updateDomainDetailsWithDoc() {
  try {
    
  } catch (error) {
    
  }
}
boardImageUrl: string | null = null;
boardPdfUrl: SafeUrl | null = null;


onFileSelected(event: any) {
  const file: File = event.target.files[0];
 //console.log(file);
  const MAX_FILE_SIZE_MB = environment.maxFileSizeMB; // Maximum file size in MB
  const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024; // Convert MB to bytes

  if (file) {
    // Reset any previous errors
   

    // 1. Check file size
    if (file.size > MAX_FILE_SIZE_BYTES) {
      this.boardApprovalDocErrors = `File size exceeds the maximum limit of ${MAX_FILE_SIZE_MB} MB.`;
      // Clear file input to prevent it from being submitted
      event.target.value = null; 
      // Reset the card details
      this.cards[0].details.twoLetterDomainDocumentProof = null;
      this.cards[0].details.twoLetterDomainDocumentFileName = null;
     //console.error(this.boardApprovalDocErrors);
      return; // Stop further execution
    }

    // 2. Check file type
    const allowedFileTypes = ['application/pdf', 'image/jpeg', 'image/jpg'];
    if (!allowedFileTypes.includes(file.type)) {
      this.boardApprovalDocErrors = 'Invalid file type. Only PDF, JPG and JPEG files are allowed.';
      // Clear file input
      event.target.value = null;
      // Reset the card details
      this.cards[0].details.twoLetterDomainDocumentProof = null;
      this.cards[0].details.twoLetterDomainDocumentFileName = null;
     //console.error(this.boardApprovalDocErrors);
      return; // Stop further execution
    }

    // If file size and type are valid, proceed with the original logic
    // 3. Get the file name and assign it directly.
    this.cards[0].details.twoLetterDomainDocumentFileName = file.name;

    // 4. Read the file's content and convert it to a Base64 string.
    const reader = new FileReader();

    reader.onload = (e: any) => {
      const base64StringWithPrefix = e.target.result as string;
      const base64String = base64StringWithPrefix.split(',')[1];
      
      this.cards[0].details.twoLetterDomainDocumentProof = base64String;
       this.boardApprovalDocErrors = '';
     //console.log('File successfully converted to Base64.');
    };
    
    reader.readAsDataURL(file);
    
  } else {
    // Handle the case where the user deselects the file.
    this.boardApprovalDocErrors = ''; // Clear errors if file is deselected
    this.cards[0].details.twoLetterDomainDocumentProof = null;
    this.cards[0].details.twoLetterDomainDocumentFileName = null;
   //console.log('File deselected.');
  }

}
 @ViewChild('boardDocTrigger') boardDocTrigger!: ElementRef;


async viewDocument() {
  const fileProof = this.cards[0]?.details?.twoLetterDomainDocumentProof;
  const fileName = this.cards[0]?.details?.twoLetterDomainDocumentFileName;

  if (!fileProof || !fileName) {
    return;
  }

  // Determine the MIME type based on the file extension
  const fileExtension = fileName.split('.').pop().toLowerCase();
  
  // Reset previous URLs
  this.boardImageUrl = null;
  this.boardPdfUrl = null;
  
  if (fileExtension === 'jpg' || fileExtension === 'jpeg' || fileExtension === 'png' || fileExtension === 'gif') {
    // It's an image.
    let mimeType = '';
    if (fileExtension === 'jpg' || fileExtension === 'jpeg') {
        mimeType = 'image/jpeg';
    } else if (fileExtension === 'png') {
        mimeType = 'image/png';
    } else if (fileExtension === 'gif') {
        mimeType = 'image/gif';
    }

    // Assign the full data URL to boardImageUrl
    this.boardImageUrl = `data:${mimeType};base64,${fileProof}`;

  } else if (fileExtension === 'pdf') {
    // It's a PDF.
    const mimeType = 'application/pdf';
    const dataUrl = `data:${mimeType};base64,${fileProof}`;
    
    // Sanitize the URL for the iframe's src attribute
    this.boardPdfUrl = this.sanitizer.bypassSecurityTrustResourceUrl(dataUrl);

  } else {
    // Handle other file types or show a message
   //console.warn(`File type .${fileExtension} is not supported for preview.`);
  }
}
async openBoardDocumentModal() {
    // You must first prepare the data for the modal
    await this.viewDocument(); 

    // Then, programmatically click the hidden element to show the modal
    if (this.boardDocTrigger) {
      this.boardDocTrigger.nativeElement.click();
    }
  }

  removeDomainBoardApprovalDoc(){
   this.cards[0].details.twoLetterDomainDocumentProof = null;
   this.cards[0].details.twoLetterDomainDocumentFileName ='';

  }

downloadPreview() {

  const original = document.querySelector('.name') as HTMLElement;

  // 🔥 STEP 1: Clone the preview
  const clone = original.cloneNode(true) as HTMLElement;

  // 🔥 STEP 2: Remove ALL buttons from clone
  clone.querySelectorAll('button').forEach(btn => btn.remove());

  // (Optional) remove icons / unwanted elements
  clone.querySelectorAll('.no-print').forEach(el => el.remove());

  // 🔥 STEP 3: Place clone off-screen
  clone.style.position = 'fixed';
  clone.style.top = '-9999px';
  clone.style.left = '-9999px';
  document.body.appendChild(clone);

  // 🔥 STEP 4: Capture ONLY cleaned clone
  html2canvas(clone, {
    scale: 2,
    useCORS: true
  }).then(canvas => {

    const imgData = canvas.toDataURL('image/png');

    const pdf = new jsPDF('p', 'mm', 'a4');

    const imgWidth = 210;
    const imgHeight = (canvas.height * imgWidth) / canvas.width;

    pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
    pdf.save('Organization_Details.pdf');

    // 🔥 STEP 5: Remove clone
    document.body.removeChild(clone);
  });
}


}


