import { CommonModule } from '@angular/common';
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FindAccountResDto } from '@api/models';
import { TableColumn } from '@core/models';
import { RxState } from '@rx-angular/state';
import dayjs from 'dayjs';
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 { DynamicDialogData } from '../../shared/utils/dynamic-dialog-utils';
import {
  ManagestipulatoriDialogComponent,
  ManagestipulatoriDialogComponentState,
} from './manage-stipulatori-dialog /manage-stipulatori-dialog.component';
import {
  ManageUsersDialogComponent,
  ManageUsersDialogComponentState,
} from './manage-users-dialog/manage-users-dialog.component';
import { UtentiService } from './utenti.service';

export interface ManageUserComponentState {
  users: FindAccountResDto[];
  usersAreLoading: boolean;
  usersTotalCount: number;
  currentFilter?: TableLazyLoadEvent;
  selectedUser: FindAccountResDto | undefined;
  userIsLoading: boolean;
  cdIsLoading: boolean;
  messages?: {
    severity: string;
    summary: string;
    life: number;
    detail: string;
  }[];
  isLoading?: boolean;
}
type State = ManageUserComponentState;

@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: './utenti.component.html',
  styleUrl: './utenti.component.scss',
})
export class UtentiComponent implements OnInit {
  //private state = inject(RxState<State>);

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

  model$: Observable<ManageUserComponentState>;

  showTransitionOptions = '500ms';

  private childDialogRef: DynamicDialogRef | undefined;

  defaultUsers: FindAccountResDto[] = [
    {
      creationDate: '',
      expireDate: '',
      id: 0,
      profiles: [],
      username: '',
      firstName: '',
      lastName: '',
      status: {
        description: null,
        id: 0,
        standardCode: null,
        standardName: null,
      },
    },
    {
      creationDate: '',
      expireDate: '',
      id: 0,
      profiles: [],
      username: '',
      firstName: '',
      lastName: '',
      status: {
        description: null,
        id: 0,
        standardCode: null,
        standardName: null,
      },
    },
  ];

  cols: TableColumn[] = [
    {
      header: 'Nome',
      field: 'firstName',
      sortField: 'firstName',
    },
    {
      header: 'Cognome',
      field: 'lastName',
      sortField: 'lastName',
    },

    {
      header: 'Email',
      field: 'username',
      sortField: 'username',
    },
    {
      header: 'Ruolo',
      field: 'ruolo',
      sortField: 'ruolo',
    },
    {
      header: 'Data creazione',
      field: 'creationDate',
      sortField: 'creationDate',
    },
    {
      header: 'Data fine validità',
      field: 'expireDate',
      sortField: 'expireDate',
    },
    {
      header: 'Status',
      field: 'status.standardName',
      sortField: 'status.id',
    },
    {
      header: 'Azioni',
      field: 'azioni',
    },
  ];

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

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

  messages: ToastMessageOptions[] = [];

  constructor(
    private utentiService: UtentiService,
    private readonly dialogService: DialogService,
    private confirmationService: ConfirmationService,
    private state: RxState<State>,
  ) {
    this.model$ = this.state.select();

    this.state.set({
      users: [],
      usersAreLoading: false,
      usersTotalCount: 0,
      selectedUser: undefined,
      userIsLoading: false,
      cdIsLoading: false,
    });
  }

  ngOnInit() {
    this.getUsers();
  }

  getUsers() {
    const Users$ = this.utentiService.getUsers().pipe(
      map((res) => ({ users: res.accounts, usersTotalCount: res.count })),
      catchError((err) => {
        this.messages = [
          {
            severity: 'error',
            life: 5000,
            summary: 'Attenzione!',
            detail:
              'Impossibile recuperare la lista utenti al momento, riprova più tardi',
          },
        ];
        return of({});
      }),
      startWith({ usersAreLoading: true }),
      endWith({ usersAreLoading: false }),
    );
    this.state.connect(Users$);
  }

  createUser() {
    this.childDialogRef = this.dialogService.open(ManageUsersDialogComponent, {
      header: 'Crea utente',
      modal: true,
      style: { width: '120vw', maxWidth: '800px', minWidth: '400px' },
      data: {
        isLoading: false,
        dialogComponentName: ManageUsersDialogComponent.name,
      } satisfies DynamicDialogData<ManageUsersDialogComponentState>,
    });

    this.childDialogRef?.onClose.subscribe((result: string) => {
      if (!result) return;
      this.messages = [
        {
          severity: 'success',
          life: 5000,
          summary: 'Operazione completata',
          detail: 'Account creato con successo',
        },
      ];
      this.getUsers();
    });
  }

  editUser(user: FindAccountResDto) {
    const fetchUserById$ = of(EMPTY).pipe(
      switchMap(() =>
        this.utentiService.getUserById(user.id).pipe(
          catchError(() => of(null)),
          tap((res) => {
            if (!res) return;
            this.childDialogRef = this.dialogService.open(
              ManageUsersDialogComponent,
              {
                header: 'Modifica utente',
                modal: true,
                style: { width: '90vw', maxWidth: '800px', minWidth: '400px' },
                data: {
                  selectedUser: res,
                  dialogComponentName: ManageUsersDialogComponent.name,
                } satisfies DynamicDialogData<ManageUsersDialogComponentState>,
              },
            );

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

  editStipulatori(user: FindAccountResDto) {
    const fetchUserById$ = of(EMPTY).pipe(
      switchMap(() =>
        this.utentiService.getUserById(user.id).pipe(
          catchError(() => of(null)),
          tap((res) => {
            if (!res) return;
            this.childDialogRef = this.dialogService.open(
              ManagestipulatoriDialogComponent,
              {
                header: 'Modifica utente',
                modal: true,
                style: { width: '90vw', maxWidth: '800px', minWidth: '400px' },
                data: {
                  selectedUser: res,
                  dialogComponentName: ManagestipulatoriDialogComponent.name,
                } satisfies DynamicDialogData<ManagestipulatoriDialogComponentState>,
              },
            );

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

  showDeleteDialog(event: Event, user: FindAccountResDto): void {
    this.confirmationService.confirm({
      target: event.target as EventTarget,
      key: 'cd',
      header: 'Elimina utente',
      icon: 'pi pi-exclamation-triangle',
      message: 'Sei sicuro di voler eliminare questo utente?',
      acceptLabel: 'Sì, elimina',
      acceptButtonStyleClass: 'p-button-rounded',
      rejectButtonStyleClass: 'p-button-rounded p-button-outlined',
      acceptIcon: 'pi pi-trash',
      rejectLabel: 'Annulla',
      accept: () => {
        const saveDeleteChannel$ = this.utentiService.deleteUser(user.id).pipe(
          catchError((err) => of(null)),
          tap((res) => {
            if (!res) return;
            this.messages = [
              {
                severity: 'success',
                summary: 'Operazione completata!',
                life: 5000,
                detail: 'Account eliminato con successo',
              },
            ];
            this.getUsers();
          }),
          map(() => ({})),
          startWith({ cdIsLoading: true }),
          endWith({ cdIsLoading: false }),
        );
        this.state.connect(saveDeleteChannel$);
      },
    });
  }

  getSeverity(statusCode: 'Disabled' | 'Enabled') {
    switch (statusCode) {
      case 'Disabled':
        return 'danger';

      case 'Enabled':
        return 'success';

      default:
        return 'danger';
    }
  }

  // sendFirstAccessMail(event: Event, id: number) {
  //   this.confirmationService.confirm({
  //     target: event.target as EventTarget,
  //     header: 'Invio mail prima attivazione',
  //     message: 'Sei sicuro di voler inviare la mail?',
  //     icon: 'pi pi-exclamation-triangle',
  //     acceptLabel: 'Invia',
  //     acceptButtonStyleClass: 'p-button-success',
  //     acceptIcon: 'pi pi-send',
  //     rejectLabel: 'Annulla',
  //     key: 'cd',
  //     accept: () => {
  //       const sendActivationMail$ = this.utentiService
  //         .sendActivationMail(id)
  //         .pipe(
  //           tap(() => {
  //             this.messages = [
  //               {
  //                 severity: 'success',
  //                 summary: 'Operazione completata!',
  //                 life: 5000,
  //                 detail: 'Email inviata con successo',
  //               },
  //             ];
  //           }),
  //           catchError((err) => {
  //             this.messages = [
  //               {
  //                 severity: 'error',
  //                 summary: 'Attenzione!',
  //                 life: 5000,
  //                 detail:
  //                   'Impossibile mandare la email in questo momento, riprova più tardi',
  //               },
  //             ];
  //             return throwError(() => new Error(err));
  //           }),
  //         );
  //       this.state.connect(sendActivationMail$);
  //     },
  //   });
  // }

  sendFirstAccessMail(event: Event, id: number) {
    this.confirmationService.confirm({
      target: event.target as EventTarget,
      header: 'Invio mail prima attivazione',
      message: 'Sei sicuro di voler inviare la mail?',
      icon: 'pi pi-exclamation-triangle',
      acceptLabel: 'Invia',
      acceptButtonStyleClass: 'p-button-rounded',
      rejectButtonStyleClass: 'p-button-rounded p-button-outlined',
      acceptIcon: 'pi pi-send',
      rejectLabel: 'Annulla',
      key: 'cd',
      accept: () => {
        const sendActivationMail$ = this.utentiService
          .sendActivationMail(id)
          .pipe(
            map((res) => ({
              messages: [
                {
                  severity: 'success',
                  summary: 'Operazione completata!',
                  life: 5000,
                  detail: 'Email inviata con successo',
                },
              ],
            })),
            catchError((err) => {
              return of({
                messages: [
                  {
                    severity: 'error',
                    summary: 'Attenzione!',
                    life: 5000,
                    detail:
                      'Impossibile mandare la email in questo momento, riprova più tardi',
                  },
                ],
              });
            }),
          );
        this.state.connect(sendActivationMail$);
      },
    });
  }
  isFinalDate(date: string) {
    return dayjs(date)
      .startOf('day')
      .isBefore(dayjs('9998-12-31').startOf('day'));
  }
}
