import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { DomainService } from '../rgnt-domain/service/domain.service';
import { Router } from '@angular/router';
import { async, lastValueFrom } from 'rxjs';
import { HttpStatusCode } from '@angular/common/http';
import { UserService } from './service/user.service';
import { ToastrService } from 'ngx-toastr';
import { OrganisationDetailsService } from '../organisation-details/service/organisation-details.service';
import { ContactDetailsFormService } from '../contact-details-form/service/contact-details-form.service';
import { error } from 'jquery';
//import { MatPaginator } from '@angular/material/paginator';

@Component({
    selector: 'app-rgtr-rgnt-usr-mgmt',
    templateUrl: './rgtr-rgnt-usr-mgmt.component.html',
    styleUrls: ['./rgtr-rgnt-usr-mgmt.component.css'],
    standalone: false
})

export class RgtrRgntUserMgmtComponent implements OnInit {

  user = {
    id: 0,
    userName: '',
    userId: '',
    role: '',
    active: false,
    encryptedPassword: '',
    mobileNumber: '',
    confirmPassword: '',
    createdByEmailId:'',
    organisationId:0,
    organisationDetailsDto: {
      institutionName:''
    },
    isOnboardingCompleted: false,
    loginAttemptedClientIP:'',
    loginAttemptedDateTime:'',
   // loginAttemptCount:'',
   createdDatetime:'',
   updatedDatetime:'',
   countryCode:''
  }


  showEmailButton: boolean = false;
  showNumberButton: boolean = false;
  isPasswordVisible: boolean = false;
  isConfirmPasswordVisible: boolean = false;
  isLoadingData:boolean=false;
  //isToggleOn: boolean = false;

  displayedColumns: string[] = [];// Matches matColumnDef values

  

  usersList: any[];
  usersDataSource: MatTableDataSource<any>;
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  userId = localStorage.getItem('email');
  role = localStorage.getItem('userRole');
  organisationId = localStorage.getItem('organisationId');

  constructor(private userService: UserService, private router: Router,
    private toastr: ToastrService, private organisationService: OrganisationDetailsService,private conatctFormService: ContactDetailsFormService,
  ) {
    this.usersDataSource = new MatTableDataSource<any>();
  }
    
     

  loggedInUser: any;
  async getLoggedInUserDetails(){
   await lastValueFrom(this.userService.getRgtrUserByEmailId(this.userId)).then(
    response => {
      if(response.status === HttpStatusCode.Ok){
        this.loggedInUser = response.body;
        ////console.log(this.loggedInUser)
      }
    },error => {
      if(error.status === HttpStatusCode.Unauthorized){
        this.navigateToSessionTimeout();
      }
    }
   )
  }

  async ngOnInit(): Promise<void> {
    //set table comumns based on role
    if(this.role === 'IDRBTADMIN'){
      this.displayedColumns = [
        // 'checkbox',
        'ids',
        'userId',
        'userName',
     // 'countryCode',
        'mobileNumber',
        'institutionName',
        'role',
        'access',
        'active',
        'edit',
        'delete',
      ]; 
    }else{
      this.displayedColumns = [
        'checkbox',
        'ids',
        'userId',
        'userName',
     // 'countryCode',
        'mobileNumber',
        'institutionName',
        'role',
        'active',
        'edit',
        'delete',
      ]; 
    }

    this.getLoggedInUserDetails();
    
    if(this.role === 'IDRBTADMIN'){
      await this.getUsersList(0);
    }else if(this.role != 'IDRBTADMIN' && parseInt(this.organisationId) > 0){
      await this.getUsersList(parseInt(this.organisationId));
    }
    // this.usersList.forEach(user => {
    //   if(user.organisationId > 0){
    //      this.getOrganisationDetailsOfUser(user.organisationId);
    //   }else{
    //      user.organisation.institutionName = 'Onboarding Pending';
    //   }
    // });
    //if(parseInt(this.organisationId) > 0){
      
    //}

  }

  async getUsersList(organisationId: number) {
    //console.log('Organisation ID:', organisationId);
    if (isNaN(organisationId) || organisationId <= 1) {
      //console.error('Invalid organisationId:', organisationId);
      organisationId=0
      //return;
    }
    this.isLoadingData=true;
    await lastValueFrom(this.userService.getAllUsers(organisationId)).then(
      (response) => {
        if (response.status === HttpStatusCode.Ok) {
          //console.log(response.body);
          this.usersList = response.body;
          this.usersDataSource.data = this.usersList;
          this.usersList.forEach((item, index) => {
            item.ids= index+1; // Add originalIndex property to your data
          });
          this.usersDataSource.paginator = this.paginator;
                     //console.log(this.sort)
                     setTimeout(() => {
                       this.usersDataSource.sort = this.sort;
                       this.usersDataSource.sortingDataAccessor = (data: any, sortHeaderId: string) => {
                         if (sortHeaderId === 'institutionName') {
                           const organisationName = data.organisationDetailsDto.institutionName; // Use optional chaining
                           return organisationName || ''; // Handle null/undefined or empty userRoles
                         } else {
                           return data[sortHeaderId]; // Default sorting for other columns
                         }
                       };
                     }, 0);
          this.isLoadingData=false;
        }
      },
      (error) => {
        this.isLoadingData=false;
        if (error.status === HttpStatusCode.Unauthorized) {
          this.navigateToSessionTimeout();
        }
      }
    );
  }

  navigateToDomainDetails(domainId: number){
    this.router.navigate(['/domain-details'],{queryParams:{domainId:domainId}});
  }

  navigateToSessionTimeout() {
    this.router.navigateByUrl('/session-timeout');
  }

  toggleState: boolean = false;
  async onAccessToggle(event: any, user: any): Promise<void> {
    //console.log(user)
    this.toggleState = event.checked;
    console.log(this.toggleState);
    user.active = this.toggleState;
    if(user.active == true){
       user.isDeleted = false;
    }
    console.log(user.id)
    await this.fetchContactDetails(user.userRoles,user.userId)
    await this.updateUser(user);
  }
  adminContactDetails:any
  technicalContactDetails:any
  billingContactDetails:any
  async fetchContactDetails(userRoles,email){
    //console.log(userRoles[0].roleName)
    if(userRoles[0].roleName == "Administrative Officer"){
      this.conatctFormService.getAdministrativeOfficersByEmail(email).subscribe({
       next:(response)=>{
        this.adminContactDetails=response.body
        this.adminContactDetails.isActive=this.toggleState;
        this.updateAdministrativeContact(this.adminContactDetails);
        //console.log(this.adminContactDetails)
       }
      })
    }else if(userRoles[0].roleName == "Technical Officer"){
      this.conatctFormService.getTechnicalOfficersByEmail(email).subscribe({
        next:(response)=>{
          this.technicalContactDetails=response.body
          this.technicalContactDetails.isActive=this.toggleState;
          this.updateTechnicalContact(this.technicalContactDetails);
          //console.log(this.technicalContactDetails)
        }
      })
    }else if(userRoles[0].roleName == "Billing Officer"){
      this.conatctFormService.getBillingOfficersByEmail(email).subscribe({
        next:(response)=>{
          this.billingContactDetails=response.body
          this.billingContactDetails.isActive=this.toggleState;
        this.updateBillingContact(this.billingContactDetails);
          //console.log(this.billingContactDetails)
        }
      })
    }
  }

  updateBillingContact(billContact){
    this.conatctFormService.updateBillDetails(billContact).subscribe({
      next:(response)=>{
        this.billingContactDetails=[]
      },error:(error)=>{
        if(error.status==HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
      }
    })
  }
  updateAdministrativeContact(administrativeContact){
    this.conatctFormService.updateAdminDetails(administrativeContact).subscribe({
      next:(response)=>{
        this.adminContactDetails=[]
      },error:(error)=>{
        if(error.status==HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
      }
    })
  }
  updateTechnicalContact(technicalContact){
    this.conatctFormService.updateTechDetails(technicalContact).subscribe({
      next:(response)=>{
        this.technicalContactDetails=[]
      },error:(error)=>{
        if(error.status==HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
      }
    })
  }
  //user: any = null;
  async getuserById(email) {
    await lastValueFrom(this.userService.getUserByEmailId(email)).then(
      response => {
        if (response.status === HttpStatusCode.Ok) {
          this.user = response.body;
          console.log(this.user);
        }
      }, error => {
        if (error.status === HttpStatusCode.Unauthorized) {
          this.navigateToSessionTimeout();
        }
      }
    )
  }

  async updateUser(user: any) {
  if (user.active) {
    user.loginAttemptCount = 0;
  }

  // Perform validation checks before making the API call
  if (!this.nameInput || !this.emailInput || !this.numberInput) {
    this.toastr.error('Please fill in all required fields.');
    return;
  }

  try {
    console.log('Updating user:', user);
    const response = await lastValueFrom(this.userService.updateUser(user));
    if (response.status === HttpStatusCode.Ok) {
      this.toastr.success('User updated successfully.');
      document.getElementById('closeTheUpdateUser')?.click(); // Use optional chaining
      setTimeout(() => {
        window.location.reload();
      }, 1000);
      //  this.usersDataSource._updateChangeSubscription();
    } else {
      // this.toastr.error(`Failed to update user. Status: ${response.status}`);
      // Optionally handle other error status codes with specific messages
    }
  } catch (error: any) {
    if (error.status === HttpStatusCode.Unauthorized) {
      this.navigateToSessionTimeout();
    } else {
      this.toastr.error(`An unexpected error occurred: ${error.message}`);
      // Optionally log the error for further investigation
      console.error('Error updating user:', error);
    }
  }
}

  async deleteUserById(email) {
    var confirmed = window.confirm('Are you sure, you really want to delete this user ?');
    if (confirmed) {
      await lastValueFrom(this.userService.deleteUserByUserId(email)).then(
        response => {
          if (response.status === HttpStatusCode.Ok) {
            this.getUsersList(parseInt(this.organisationId));
          }
        }, error => {
          if (error.status === HttpStatusCode.Unauthorized) {
            this.navigateToSessionTimeout();
          }
        }
      )
    }else{
      this.toastr.warning('User not deleted')
    }
  }

  formValid() {
    //console.log("validation checking");
    return this.nameInput && this.emailInput && this.numberInput && this.passwordNameInput && this.confirmPasswordInput && this.isAuthorized;
  }

  nameErrorMessage: string = '';
  nameInput: boolean = true;
  nameChange() {
    if (!this.user.userName) {
      this.nameInput = false;
      this.nameErrorMessage = 'Name should not be empty.';
    } else if (this.user.userName.length > 25) {
      this.nameInput = false;
      this.nameErrorMessage = 'Name should not exceed 25 characters.';
    } else {
      this.nameInput = true;
      this.nameErrorMessage = '';
    }
  }

  emailInput: boolean = true;
  emailerrorMessage: string = '';
  emailChange() {
    const emailPattern = /^[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9.]+\.[a-zA-Z]{2,4}$/;
    if (!this.user.userId) {
      this.emailInput = false;
      this.emailerrorMessage = 'Email ID should not be empty';
    } else if (!emailPattern.test(this.user.userId)) {
      this.emailInput = false;
      this.emailerrorMessage = 'Please enter a valid email ID';
    } else {
      this.emailInput = true;
      this.emailerrorMessage = '';
    }
  }

  numberInput: boolean = true;
  numbererrorMessage: string = '';
  numberChange() {
    const numberPattern = /^\d{10}$/;
if (!this.user.mobileNumber) {
      this.numberInput = false;
      this.numbererrorMessage = 'Mobile number should not be empty';
    } else if (!numberPattern.test(this.user.mobileNumber)) {
      this.numberInput = false;
      this.numbererrorMessage = 'Please enter a valid mobile number starting with +91 and 10 digits';
    } else {
      this.numberInput = true;
      this.numbererrorMessage = ''; 
    }
  }

  passwordErrorMessage: string = '';
  passwordNameInput: boolean = true;
  passwordChange() {
    const pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@!#$%^&*])[A-Za-z\d@!#$%^&*]{8,}/;
    if (!this.user.encryptedPassword) {
      this.passwordNameInput = false;
      this.passwordErrorMessage = 'Password should not be empty';
    } else if (!pattern.test(this.user.encryptedPassword)) {
      this.passwordNameInput = false;
      this.passwordErrorMessage = 'Password must be at least 8 characters long, include at least one uppercase letter, one lowercase letter, one digit, and one special character';
    } else {
      this.passwordNameInput = true;
      this.passwordErrorMessage = '';
    }
  }

  confirmPasswordErrorMessage: string = '';
  confirmPasswordInput: boolean = true;
  confirmPasswordChange() {
    if (!this.user.confirmPassword) {
      this.confirmPasswordInput = false;
      this.confirmPasswordErrorMessage = 'Confirm password should not be empty';
    } else if (this.user.encryptedPassword !== this.user.confirmPassword) {
      this.confirmPasswordInput = false;
      this.confirmPasswordErrorMessage = 'Passwords do not match';
    } else {
      this.confirmPasswordInput = true;
      this.confirmPasswordErrorMessage = '';
    }
  }

  isAuthorized: boolean = false;
  showError: boolean = false;
  validateCheckbox() {
    if (!this.isAuthorized) {
      this.showError = true;
    } else {
      this.showError = false;
    }
  }

  toggleEmailButton() {
    this.showEmailButton = this.user.userId.length > 0;
  }

  toggleNumberButton() {
    this.showNumberButton = this.user.mobileNumber.length > 0;
  }

  togglePasswordVisibility() {
    this.isPasswordVisible = !this.isPasswordVisible;
    const passwordField = document.getElementById('password') as HTMLInputElement;
    passwordField.type = this.isPasswordVisible ? 'text' : 'password';
  }

  toggleConfirmPasswordVisibility() {
    this.isConfirmPasswordVisible = !this.isConfirmPasswordVisible;
    const confirmPasswordField = document.getElementById('confirmPassword') as HTMLInputElement;
    confirmPasswordField.type = this.isConfirmPasswordVisible ? 'text' : 'password';
  }

  async saveOrUpdateUser(){
    //console.log(this.user);
    if(this.user.id < 1){
      await this.saveUser(this.user);
    }else{
      await this.updateUser(this.user);
    }
  }


  async saveUser(user: any) {
    var id =  localStorage.getItem('email');
    //console.log(id);
    user.createdByEmailId = id;
    user.organisationId = this.organisationId;
    await lastValueFrom(this.userService.saveUser(user)).then(
      response => {
      if (response.status === HttpStatusCode.Created) {
        this.toastr.success('User added successfully.')
        this.getUsersList(parseInt(this.organisationId));
      }
    }, error => {
      if (error.status === HttpStatusCode.Unauthorized) {
        this.navigateToSessionTimeout();
      }
    }
    )
  }

  organisationDetails: any;
  async getOrganisationDetailsOfUser(organisationId: number){
    await lastValueFrom(this.organisationService
      .getOrganisationDetailsByOrganisationId(organisationId)).then(
      response => {
        if(response.status === HttpStatusCode.Ok){
          this.user.organisationDetailsDto = response.body;
          console.log(this.user.organisationDetailsDto);
        }
      },error => {
        if(error.status === HttpStatusCode.Unauthorized){
          this.navigateToSessionTimeout();
        }
      }
    )
  }

  clearData(){
    this.user.id = 0;
    this.user.userName = '';
    this.user.userId = '';
    this.user.role = '';
    this.user.encryptedPassword = '';
    this.user.mobileNumber = '';
    this.user.mobileNumber = '';
    this.user.confirmPassword = '';
    this.nameErrorMessage='';
    this.numbererrorMessage='';
    
  }


  /**
   * 
   */
  verifyOnBoardingStatus(){
    //console.log(this.loggedInUser.isOnboardingCompleted)
    if(this.loggedInUser.isOnboardingCompleted === false) {
      this.toastr.error('Please complete onbaording to add users.');
      //console.log('complete onbaording')
    }else{
      document.getElementById('addUser1').click();
    }
  }
  searchText: string = '';
 
  applyFilter(): void {
    const filterValue = (event.target as HTMLInputElement).value?.trim().toLowerCase();
  
    // Define the custom filterPredicate for MatTableDataSource
    this.usersDataSource.filterPredicate = (data: any, filter: string) => {
      return this.displayedColumns.some(column => {
        let value: any;
  
        // Special handling for 'institutionName' (Organisation Name)
        if (column === 'institutionName') {
          value = data?.organisationDetailsDto?.institutionName; // Access institutionName in the nested object
        }
        // Special handling for 'role' (User Role)
        else if (column === 'role') {
          value = data?.userRoles?.[0]?.roleName; // Access roleName from the first item in the userRoles array
        }
        // Special handling for 'active' (Status)
        else if (column === 'active') {
          value = data?.active ? 'Active' : 'Inactive'; // Convert boolean value to 'Active' or 'Inactive'
        } else {
          value = data[column]; // Normal handling for other columns
        }
  
        const valueAsString = value?.toString().toLowerCase() || '';
        return valueAsString.includes(filter); // Return true if any column matches the filter
      });
    };
  
    // Apply the filter to the dataSource
    this.usersDataSource.filter = filterValue;
  
    // If pagination is used, reset to the first page
    if (this.usersDataSource.paginator) {
      this.usersDataSource.paginator.firstPage();
    }
  }

  getRoleNames(user: any): string { // Create a method to get role names
    if (!user?.userRoles || user.userRoles.length === 0) {
      return '';
  }

  const modifiedRoles = user.userRoles.map(role => {
      if (role.roleName === "Billing Officer") {
          return { ...role, roleName: "Financial Officer" }; // Replace "Billing Officer"
      }
      return role; // Keep other roles as they are
  });

  return modifiedRoles.length > 1
      ? modifiedRoles.map(role => role.roleName).join(', ')
      : modifiedRoles[0].roleName;
  }
  
  allowAlphabetsOnly(event: any): void {
    let inputValue = event.target.value;
  
    // Remove characters that are not allowed (allow alphabets, digits, underscores, spaces)
    let validValue = inputValue.replace(/[^a-zA-Z0-9_ \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-Z0-9_]/.test(validValue.charAt(validValue.length - 2))) {
      validValue = validValue.slice(0, -1);
    }
  
    // Replace multiple spaces with a single space
    validValue = validValue.replace(/\s+/g, ' ');
  
    // Validation checks
    let nameErrorMessage = '';
    let nameInput = true;
  
    // Validate input: At least one alphanumeric or underscore character is required
    if (!validValue || validValue.length === 0) {
      nameErrorMessage = 'Name should not be empty.';
      nameInput = false;
    } else if (validValue.length > 25) {
      nameErrorMessage = 'Name should not exceed 25 characters.';
      nameInput = false;
    } else if (!/[a-zA-Z0-9]/.test(validValue)) {  // Check if there's at least one alphanumeric character (A-Z, a-z, 0-9)
      nameErrorMessage = 'Name should contain at least one alphanumeric character.';
      nameInput = false;
    }
  
    // Update the input value and error messages
    event.target.value = validValue;
  
    // Display the error message (for example, by setting a state or variable)
    this.nameErrorMessage = nameErrorMessage;  // Use this variable to bind in your template
    this.nameInput = nameInput;  // Use this flag to enable/disable the Save button
  }
  
}  


