import { FormPropData,EXTENSIONS_IDENTIFIER ,generateFormFromProps, ExtensibleModule} from '@abp/ng.components/extensible';
import { PageModule } from '@abp/ng.components/page';
import { CoreModule, ListResultDto, ListService, LocalizationModule, PagedResultDto } from '@abp/ng.core';
import { eIdentityComponents } from '@abp/ng.identity';
import { GetIdentityUsersInput, IdentityRoleDto, IdentityUserDto, IdentityUserService } from '@abp/ng.identity/proxy';
import { CommonModule } from '@angular/common';
import { Component, inject, Injector, OnInit, TemplateRef, TrackByFunction, ViewChild } from '@angular/core';
import { AbstractControl, FormsModule, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { ButtonModule } from 'primeng/button';
import { TableModule } from 'primeng/table';
import { Confirmation, eFormComponets, ThemeSharedModule,ToasterService ,ConfirmationService} from '@abp/ng.theme.shared';
import { finalize, switchMap, tap } from 'rxjs';
import { ePermissionManagementComponents, PermissionManagementModule } from '@abp/ng.permission-management';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import {  NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
import { PaginatorModule } from 'primeng/paginator';
import { TagModule } from 'primeng/tag'; // For active/inactive status

@Component({
  selector: 'app-custom-users',
  standalone: true,
  imports: [CommonModule,FormsModule,TableModule,ButtonModule,PageModule,LocalizationModule,ThemeSharedModule,NgxDatatableModule,ExtensibleModule,
      PermissionManagementModule,
        CoreModule,
        NgbNavModule,
        PaginatorModule,TagModule
  ],
  templateUrl: './custom-users.component.html',
  providers: [
    ListService,
    {
      provide: EXTENSIONS_IDENTIFIER,
      useValue: eIdentityComponents.Users,
    },
  ],
  styleUrl: './custom-users.component.scss'
})
export class CustomUsersComponent implements OnInit{
  protected readonly list = inject(ListService<GetIdentityUsersInput>);
  protected readonly confirmationService = inject(ConfirmationService);
  protected readonly service = inject(IdentityUserService);
  protected readonly toasterService = inject(ToasterService);
  private readonly fb = inject(UntypedFormBuilder);
  private readonly injector = inject(Injector);

  data: PagedResultDto<IdentityUserDto> = { items: [], totalCount: 0 };

  @ViewChild('modalContent', { static: false })
  modalContent!: TemplateRef<any>;

  form!: UntypedFormGroup;

  selected?: IdentityUserDto;

  selectedUserRoles?: IdentityRoleDto[];

  roles?: IdentityRoleDto[];

  visiblePermissions = false;

  providerKey?: string;

  isModalVisible?: boolean;

  modalBusy = false;

  permissionManagementKey = ePermissionManagementComponents.PermissionManagement;

  entityDisplayName: string;

  inputKey = eFormComponets.FormCheckboxComponent;

  trackByFn: TrackByFunction<AbstractControl> = (index, item) => Object.keys(item)[0] || index;

  onVisiblePermissionChange = (event: boolean) => {
    this.visiblePermissions = event;
  };

  get roleGroups(): UntypedFormGroup[] {
    return ((this.form.get('roleNames') as UntypedFormArray)?.controls as UntypedFormGroup[]) || [];
  }

  ngOnInit() {
    this.hookToQuery();
  }

  buildForm() {
    debugger
    const data = new FormPropData(this.injector, this.selected);
    this.form = generateFormFromProps(data);

    this.service.getAssignableRoles().subscribe(({ items }) => {
      this.roles = items;
      if (this.roles) {
        this.form.addControl(
          'roleNames',
          this.fb.array(
            this.roles.map(role =>
              this.fb.group({
                [role.name as string]: [
                  this.selected?.id
                    ? !!this.selectedUserRoles?.find(userRole => userRole.id === role.id)
                    : role.isDefault,
                ],
              }),
            ),
          ),
        );
      }
    });
  }

  openModal() {
    this.buildForm();
    this.isModalVisible = true;
  }

  add() {
    debugger
    this.selected = {} as IdentityUserDto;
    this.selectedUserRoles = [] as IdentityRoleDto[];
    this.openModal();
  }

  edit(id: string) {
    debugger
    this.service
      .get(id)
      .pipe(
        tap(user => (this.selected = user)),
        switchMap(() => this.service.getRoles(id)),
      )
      .subscribe(userRole => {
    debugger

        this.selectedUserRoles = userRole.items || [];
        this.openModal();
      });
  }

  save() {
    if (!this.form.valid || this.modalBusy) return;
    this.modalBusy = true;

    const { roleNames = [] } = this.form.value;
    const mappedRoleNames =
      roleNames
        .filter((role: { [key: string]: any }) => !!role[Object.keys(role)[0]])
        .map((role: { [key: string]: any }) => Object.keys(role)[0]) || [];

    const { id } = this.selected || {};

    (id
      ? this.service.update(id, {
          ...this.selected,
          ...this.form.value,
          roleNames: mappedRoleNames,
        })
      : this.service.create({ ...this.form.value, roleNames: mappedRoleNames })
    )
      .pipe(finalize(() => (this.modalBusy = false)))
      .subscribe(() => {
        this.isModalVisible = false;
        this.toasterService.success('AbpUi::SavedSuccessfully');
        this.list.get();
      });
  }

  delete(id: string, userName: string) {
    this.confirmationService
      .warn('AbpIdentity::UserDeletionConfirmationMessage', 'AbpIdentity::AreYouSure', {
        messageLocalizationParams: [userName],
      })
      .subscribe((status: Confirmation.Status) => {
        if (status === Confirmation.Status.confirm) {
          this.service.delete(id).subscribe(() => {
            this.toasterService.success('AbpUi::DeletedSuccessfully');
            this.list.get();
          });
        }
      });
  }

  sort(data: any) {
    const { prop, dir } = data.sorts[0];
    this.list.sortKey = prop;
    this.list.sortOrder = dir;
  }

  // private hookToQuery() {
  //   this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => (this.data = res));
  // }
  private hookToQuery() {
    this.list.hookToQuery(query => {
      console.log('Query:', query); // Log the query
      return this.service.getList(query);
    }).subscribe(res => {
debugger
      this.data = res;
    });
  }

  openPermissionsModal(providerKey: string, entityDisplayName?: string) {
    debugger
    this.providerKey = providerKey;
    this.entityDisplayName = entityDisplayName;
    setTimeout(() => {
      this.visiblePermissions = true;
    }, 0);
  }
}
