import { CommonModule } from '@angular/common';
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RxState } from '@rx-angular/state';
import { ConfirmationService, ToastMessageOptions } from 'primeng/api';
import { ButtonModule } from 'primeng/button';
import { ConfirmDialogModule } from 'primeng/confirmdialog';
import { ConfirmPopupModule } from 'primeng/confirmpopup';
import { DialogService, DynamicDialogRef } from 'primeng/dynamicdialog';
import { IconFieldModule } from 'primeng/iconfield';
import { InputIconModule } from 'primeng/inputicon';
import { InputTextModule } from 'primeng/inputtext';
import { MessagesModule } from 'primeng/messages';
import { MultiSelectModule } from 'primeng/multiselect';
import { SkeletonModule } from 'primeng/skeleton';
import { Table, TableLazyLoadEvent, TableModule } from 'primeng/table';
import { TagModule } from 'primeng/tag';
import { ToastModule } from 'primeng/toast';
import { TooltipModule } from 'primeng/tooltip';
import {
  catchError,
  EMPTY,
  endWith,
  map,
  Observable,
  of,
  startWith,
  switchMap,
  tap,
} from 'rxjs';
import { FindPrivilegeResDto, FindRoleResDto } from '../../../../api/models';
import { TableColumn } from '../../shared/interfaces';
import { DynamicDialogData } from '../../shared/utils/dynamic-dialog-utils';
import {
  ManageRolesDialogComponent,
  ManageRolesDialogComponentState,
} from './manage-roles-dialog/manage-roles-dialog.component';
import { RuoliService } from './ruoli.service';

export interface ManageRoleComponentState {
  roles: FindRoleResDto[];
  rolesAreLoading: boolean;
  rolesTotalCount: number;
  currentFilter?: TableLazyLoadEvent;
  selectedRole: FindRoleResDto | undefined;
  privileges: FindPrivilegeResDto[];
  roleIsLoading: boolean;
  cdIsLoading: boolean;
  privilegesAreLoading: boolean;
}
type State = ManageRoleComponentState;

@Component({
  selector: 'app-utenti',
  imports: [
    CommonModule,
    TableModule,
    InputTextModule,
    SkeletonModule,
    ButtonModule,
    TooltipModule,
    FormsModule,
    ReactiveFormsModule,
    MultiSelectModule,
    ConfirmDialogModule,
    IconFieldModule,
    InputIconModule,
    MessagesModule,
    TagModule,
    ConfirmPopupModule,
    ToastModule,
  ],
  providers: [RxState, DialogService, ConfirmationService],
  templateUrl: './ruoli.component.html',
  styleUrl: './ruoli.component.scss',
})
export class RuoliComponent implements OnInit {
  //private state = inject(RxState<State>);

  //model$ = this.state.select();

  model$: Observable<ManageRoleComponentState>;

  showTransitionOptions = '500ms';

  private childDialogRef: DynamicDialogRef | undefined;

  defaultRoles: FindRoleResDto[] = [
    { description: '', id: 0, standardCode: '', standardName: '' },
    { description: '', id: 0, standardCode: '', standardName: '' },
    { description: '', id: 0, standardCode: '', standardName: '' },
    { description: '', id: 0, standardCode: '', standardName: '' },
    { description: '', id: 0, standardCode: '', standardName: '' },
  ];

  cols: TableColumn[] = [
    {
      header: 'Codice',
      field: 'standardCode',
      sortField: 'standardCode',
    },
    {
      header: 'Nome',
      field: 'standardName',
      sortField: 'standardName',
    },
    {
      header: 'Descrizione',
      field: 'description',
      sortField: 'description',
    },

    {
      header: 'Azioni',
      field: 'azioni',
    },
  ];

  defaultSort = [{ field: 'standardCode', order: 1 }];

  @ViewChild('rolesTable') rolesTable!: Table;

  messages: ToastMessageOptions[] = [];

  constructor(
    private ruoliService: RuoliService,
    private readonly dialogService: DialogService,
    private confirmationService: ConfirmationService,
    private state: RxState<State>,
  ) {
    this.model$ = this.state.select();
    this.state.set({
      roles: [],
      rolesAreLoading: false,
      rolesTotalCount: 0,
      selectedRole: undefined,
      roleIsLoading: false,
      cdIsLoading: false,
      privilegesAreLoading: false,
    });
  }

  ngOnInit() {
    this.getRoles();
  }

  getRoles() {
    const roles$ = this.ruoliService.getRoles().pipe(
      map((res) => ({ roles: res, rolesTotalCount: res.length })),
      catchError(() => {
        this.messages = [
          {
            severity: 'error',
            life: 5000,
            summary: 'Attenzione!',
            detail:
              'Impossibile recuperare la lista di ruoli al momento, riprova più tardi',
          },
        ];
        return of({});
      }),
      startWith({ rolesAreLoading: true }),
      endWith({ rolesAreLoading: false }),
    );
    this.state.connect(roles$);
  }

  openPrivilegiDialog(idRuolo: number) {
    const fetchPrivilegiById$ = of(EMPTY).pipe(
      switchMap(() =>
        this.ruoliService.getPrivilegesById(idRuolo).pipe(
          catchError(() => of(null)),
          tap((res) => {
            if (!res) return;
            this.childDialogRef = this.dialogService.open(
              ManageRolesDialogComponent,
              {
                header: 'Modifica privilegi del ruolo',
                modal: true,
                closable: true,
                focusOnShow: false,
                style: { width: '90vw', maxWidth: '1500px', minWidth: '400px' },
                data: {
                  privileges: res,
                  roleId: idRuolo,
                  dialogComponentName: ManageRolesDialogComponent.name,
                } satisfies DynamicDialogData<ManageRolesDialogComponentState>,
              },
            );

            this.childDialogRef?.onClose.subscribe((result: string) => {
              if (!result) return;
              this.messages = [
                {
                  severity: 'success',
                  summary: 'Operazione completata',
                  life: 5000,
                  detail: 'Privilegi del ruolo modificato con successo',
                },
              ];
              this.getRoles();
            });
          }),
          map(() => ({})),
          startWith({ privilegesAreLoading: true }),
          endWith({ privilegesAreLoading: false }),
        ),
      ),
    );
    this.state.connect(fetchPrivilegiById$);
  }
}
