import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { PermissionNode } from '../utils/app.interfaces';
import { CredentialService } from '../services/credential.service';
import { I18NService } from '../services/i18n.service';
import { HttpURIService } from '../app.http.uri.service';
import { TranslateModule } from '@ngx-translate/core';
import { URIKey } from '../utils/uri-enums';
import { HttpErrorResponse, HttpParams } from '@angular/common/http';
import { CommonModule } from '@angular/common';
import { NgSelectModule } from '@ng-select/ng-select';
import { filter, Observable, take } from 'rxjs';
import { SuccessMessages } from '../utils/enums';
import { URIService } from '../app.uri';

@Component({
  selector: 'app-menu',
  imports: [TranslateModule, ReactiveFormsModule, ReactiveFormsModule, CommonModule, TranslateModule, NgSelectModule, FormsModule],
  templateUrl: './menu.component.html',
  styleUrl: './menu.component.scss'
})
export class MenuComponent {
  users: any[] = [];
  thirdPartyForm!: FormGroup;
  permission: FormGroup;
  showPermissions = false;
  permissions: PermissionNode[] = [];
  saving = false;
  menuItems: { endpoint: string; checked: boolean }[] = [];

  constructor(
    private credentialService: CredentialService,
    private fb: FormBuilder,
    private httpService: HttpURIService,
    private i18nService: I18NService,
    private uriService: URIService
  ) {
    this.permission = this.fb.group({ userCode: [null] });
  this.defaultPermissions().subscribe((data: PermissionNode[]) => {
    this.permissions = data;
  });


  }

  ngOnInit() {
    this.getAllUsers();
    this.loadTransactionEndpoints();
    this.createThirdPartyUserForm();
  }

  createThirdPartyUserForm(): void{
    this.thirdPartyForm = this.fb.group({
      SUS_USERCODE: ["", [Validators.required]],
      SUS_EMPCODE: ["", [Validators.required]],
      SUS_NAME: ["", [Validators.required]],
      SUS_PASSWORD:  ['', [
        Validators.required,
        Validators.minLength(8),  
        Validators.maxLength(20),
        Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/)
      ]],
      SUS_EMAIL: ["", [Validators.required, Validators.email]],
      SUS_USERCELLNO: ["", [Validators.required]],
      POR_ORGACODE: [this.credentialService.getPorOrgacode()],
      SUS_ACTIVE: [true],
      SUS_THIRDPARTY: [true],
      
    })
  }

  submitForm() {
  if (this.thirdPartyForm.invalid) {
    this.thirdPartyForm.markAllAsTouched();
    return;
  }

  const f = this.thirdPartyForm.value;
  const payload = {
    formId: "SH_SM_US_USER",
    postProcessFormId: "SH_SM_US_USER",
    workFlowId: null,
    operation: "nonwizard",
    porOrgacode: this.credentialService.getPorOrgacode(),
    usercode: this.credentialService.getUserId(),
    uniqueConstraints: [["SUS_USERCODE", "POR_ORGACODE"]],
    formCounters: [],
    susUsercode: f.SUS_USERCODE,
    susName: f.SUS_NAME,
    susEmpcode: f.SUS_EMPCODE,
    susPassword: f.SUS_PASSWORD,
    susEmail: f.SUS_EMAIL,
    susUsercellno: f.SUS_USERCELLNO,
    susActive: f.SUS_ACTIVE,
    susThirdparty: f.SUS_THIRDPARTY,
  }
  
  console.log("payload",payload )
  this.httpService.requestPOST(URIKey.CREATE_THIRD_PARTY_USER, payload)
    .subscribe({
      next: (response: any) => {
        if (!(response instanceof HttpErrorResponse)) {
          this.i18nService.success(SuccessMessages.SAVED_SUCCESSFULLY, []);
          this.createThirdPartyUserForm();
        }
      }
      
      // handle error codes e.g. ERR_TRX_0006
      // Once backend is ready, check response for errorCode field
      // e.g. if (response?.errorCode === 'ERR_TRX_0006') { show error }
    });
}

  loadTransactionEndpoints() {
  this.httpService.requestGET<string[]>(URIKey.TRANSACTION_ENDPOINTS).subscribe((response) => {
    if (!(response instanceof HttpErrorResponse)) {
      this.menuItems = response.map(endpoint => ({
        endpoint,
        checked: false
      }));
    }
  });
}


  defaultPermissions(): Observable<PermissionNode[]> {
      return this.httpService.requestGET<PermissionNode[]>('assets/data/sideMenu.json');
    }

  getAllUsers() {
    this.httpService.requestGET<any[]>(URIKey.GET_ALL_USER_URI).subscribe((response) => {
      if (!(response instanceof HttpErrorResponse)) {
        this.users = response.map(item => ({
          userName: item.userFullname,
          userId: item.userId,
        }));
      }
    });
  }

onUserChange() {
  this.showPermissions = true;
  const userId = this.permission.get('userCode')?.value;
  const params = new HttpParams().set('userId', userId);

  this.httpService.requestGET(URIKey.TRANSACTION_PERMISSIONS, params)
    .subscribe((response: any) => {
      if (!(response instanceof HttpErrorResponse)) {

        const allowedEndpoints: string[] = (response as any[])
          .filter(p => p.allowed)
          .map(p => this.normalizeUrl(p.transactionEndpoint)); // ← normalize

          this.menuItems.forEach(item => {
            item.checked = allowedEndpoints.some(allowed =>
          allowed.endsWith(this.normalizeUrl(item.endpoint))
            );
            
          });
          
      } else {
        this.menuItems.forEach(item => item.checked = false);
      }
    });
}

private normalizeUrl(url: string): string {
  return url?.trim().toLowerCase().replace(/\/+$/, ''); // trim, lowercase, remove trailing slash
}

savePermissions() {
  if (this.saving) return; 
  this.saving = true;

  const selectedUser = this.permission.get('userCode')?.value;

  this.uriService.canSubscribe.pipe(
    filter(ready => ready === true),
    take(1)
  ).subscribe(() => {
    const transactionEndpoints: string[] = this.menuItems
      .filter(item => item.checked)
      .map(item => item.endpoint);

    const payload = { 
      porOrgacode: this.credentialService.getPorOrgacode(), 
      userId: selectedUser,
      transactionEndpoints
    };

    this.httpService.requestPOST(URIKey.TRANSACTION_PERMISSIONS_ASSIGN, payload)
      .subscribe({
        next: (response: any) => {
          if (!(response instanceof HttpErrorResponse)) {
            this.i18nService.success(SuccessMessages.SAVED_SUCCESSFULLY, []);
            this.permission.reset();
            this.showPermissions = false;
            this.menuItems.forEach(item => item.checked = false); 
          }
        },
        complete: () => {
          this.saving = false; // ← reset after done
        },
        error: () => {
          this.saving = false;
        }
      });
  });
}
  updatePermissions(savedPermissions: PermissionNode[], existingPermissions: PermissionNode[]): void {
    for (const existingNode of existingPermissions) {
      const savedNode = savedPermissions.find(node => node.name === existingNode.name);

      if (savedNode) {
        // Update state from saved node
        existingNode.checked = savedNode.checked;
       
        if (existingNode.children) {
          this.updatePermissions(savedNode.children || [], existingNode.children);
        }
        if (existingNode.buttons) {
          this.updatePermissions(savedNode.buttons || [], existingNode.buttons);
        }
      }
    }
  }
}