import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { CommonModule } from '@angular/common'; import { State } from '../../core/models/state'; import { Region } from '../../core/models/region'; import { NotificationService } from '../../core/services/common/notification.service'; import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { ZipCodeValidator } from '../../shared/validators/zipcode-validator'; import { CommonService } from '../../core/services/common/common.service'; import { finalize, Subject, takeUntil } from 'rxjs'; import { Country } from '../../core/models/country'; import { BasicDetailService } from '../../core/services/holder/basic-detail.service'; import { BasicDetail } from '../../core/models/holder/basic-detail'; import { StorageService } from '../../core/services/common/storage.service'; import { NavigationService } from '../../core/services/common/navigation.service'; import { environment } from '../../../environments/environment'; @Component({ selector: 'app-basic-detail', imports: [AngularMaterialModule, ReactiveFormsModule, CommonModule], templateUrl: './basic-details.component.html', styleUrl: './basic-details.component.scss' }) export class BasicDetailComponent implements OnInit, OnDestroy { @Input() isEditMode = false; @Input() holderid: number = 0; @Output() holderIdCreated = new EventEmitter(); basicDetailsForm: FormGroup; countries: Country[] = []; regions: Region[] = []; states: State[] = []; currentApplicationDetails: { headerid: number, applicationName: string } | null = null; isLoading = false; changeInProgress = false; countriesHasStates = ['US', 'CA', 'MX']; returnTo: string = environment.appType === 'client' ? 'edit-carnet' : 'process-carnet'; private destroy$ = new Subject(); private fb = inject(FormBuilder); private basicDetailService = inject(BasicDetailService); private notificationService = inject(NotificationService); private commonService = inject(CommonService); private errorHandler = inject(ApiErrorHandlerService); private storageService = inject(StorageService); private navigationService = inject(NavigationService); constructor() { this.basicDetailsForm = this.createForm(); this.currentApplicationDetails = this.storageService.get<{ headerid: number, applicationName: string }>('currentapplication') } createForm(): FormGroup { return this.fb.group({ holderName: ['', [Validators.required, Validators.maxLength(100)]], dbaName: ['', [Validators.maxLength(20)]], holderNumber: ['', [Validators.required, Validators.maxLength(20)]], holderType: ['', [Validators.required, Validators.maxLength(20)]], uscibMember: [false, [Validators.required]], // govAgency: [false, [Validators.required]], address1: ['', [Validators.required, Validators.maxLength(100)]], address2: ['', Validators.maxLength(100)], city: ['', [Validators.required, Validators.maxLength(50)]], state: ['', Validators.required], country: ['US', Validators.required], zip: ['', [Validators.required, ZipCodeValidator('country')]] }); } ngOnInit(): void { this.loadLookupData(); if (this.holderid > 0) { this.isLoading = true; this.basicDetailService.getBasicDetailByHolderId(this.holderid).pipe(finalize(() => { this.isLoading = false; })).subscribe({ next: (basicDetail: BasicDetail) => { this.patchFormData(basicDetail); // this.holderName.emit(basicDetail.holderName); }, error: (error: any) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load basic details'); this.notificationService.showError(errorMessage); console.error('Error loading basic details:', error); } }); } else { this.loadStates('US'); // Load states for default country } } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } onCountryChange(country: string): void { this.basicDetailsForm.get('state')?.reset(); if (country) { this.loadStates(country); } this.basicDetailsForm.get('zip')?.updateValueAndValidity(); } saveBasicDetails() { if (this.basicDetailsForm.invalid) { this.basicDetailsForm.markAllAsTouched(); return; } const basicDetailData: BasicDetail = this.basicDetailsForm.value; const saveObservable = this.isEditMode && this.holderid > 0 ? this.basicDetailService.updateBasicDetails(this.holderid, basicDetailData) : this.basicDetailService.createBasicDetail(basicDetailData); this.changeInProgress = true; saveObservable.pipe(finalize(() => { this.changeInProgress = false; })).subscribe({ next: (basicData: any) => { this.notificationService.showSuccess(`Basic details ${this.isEditMode ? 'updated' : 'added'} successfully`); if (!this.isEditMode) { this.holderIdCreated.emit(basicData.HOLDERID); // change to edit mode after creation this.isEditMode = true; this.holderid = basicData.HOLDERID; } // if (this.isEditMode) { // this.holderName.emit(basicDetailData.holderName); // } }, error: (error: any) => { let errorMessage = this.errorHandler.handleApiError(error, `Failed to ${this.isEditMode ? 'update' : 'add'} basic details`); this.notificationService.showError(errorMessage); console.error('Error saving basic details:', error); } }); } updateStateControl(controlName: string, country: string): void { const stateControl = this.basicDetailsForm.get(controlName); if (this.countriesHasStates.includes(country)) { stateControl?.enable(); } else { stateControl?.disable(); stateControl?.setValue('FN'); } } patchFormData(data: BasicDetail): void { this.basicDetailsForm.patchValue({ holderName: data.holderName, dbaName: data.dbaName, holderNumber: data.holderNumber, holderType: data.holderType, uscibMember: data.uscibMember, // govAgency: data.govAgency, address1: data.address1, address2: data.address2, city: data.city, state: data.state, country: data.country, zip: data.zip }) if (data.country) { this.loadStates(data.country); } } get f() { return this.basicDetailsForm.controls; } loadLookupData(): void { this.commonService.getCountries() .pipe(takeUntil(this.destroy$)) .subscribe({ next: (countries) => { this.countries = countries; }, error: (error) => { console.error('Failed to load countries', error); } }); } loadStates(country: string): void { country = this.countriesHasStates.includes(country) ? country : 'FN'; this.commonService.getStates(country) .pipe(takeUntil(this.destroy$)) .subscribe({ next: (states) => { this.states = states; this.updateStateControl('state', country); }, error: (error) => { console.error('Failed to load states', error); } }); } goBackToCarnetApplication(): void { this.storageService.removeItem('currentapplication') this.navigationService.navigate([this.returnTo, this.currentApplicationDetails?.headerid], { state: { isEditMode: true }, queryParams: { applicationname: this.currentApplicationDetails?.applicationName, return: 'holder' } }) } }