import { Router } from '@angular/router';
import { NgClass, DatePipe } from '@angular/common';
import { orderBy, process, State } from '@progress/kendo-data-query';
import { NgxSpinnerService, NgxSpinnerComponent } from 'ngx-spinner';
import { DatePickerComponent } from '@progress/kendo-angular-dateinputs';
import { DropDownListComponent } from '@progress/kendo-angular-dropdowns';
import { Component, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { DataStateChangeEvent, GridDataResult, KENDO_GRID } from '@progress/kendo-angular-grid';
import { FormBuilder, FormGroup, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';

import { AlertService } from '../components/alert';
import { BreadcrumbService } from '../breadcrumb.service';
import { UserService } from '../../providers/user/user.service.';
import { FunctionService } from '../components/models/function.service';

@Component({
  standalone: true,
  selector: 'access-log',
  encapsulation: ViewEncapsulation.None,
  templateUrl: './accesslog.component.html',
  imports: [FormsModule, ReactiveFormsModule, NgxSpinnerComponent, DropDownListComponent, NgClass, DatePickerComponent, KENDO_GRID, DatePipe]
})
export class AccessLogComponent implements OnInit
{
  private readonly router = inject(Router);
  private readonly service = inject(UserService);
  private readonly fnSvc = inject(FunctionService);
  private readonly formBuilder = inject(FormBuilder);
  private readonly alertService = inject(AlertService);
  private readonly bcService = inject(BreadcrumbService);
  private readonly spinnerService = inject(NgxSpinnerService);

  private items: any[] = [];

  public setting: any;
  public accessLogForm: FormGroup;
  public canEdit: boolean = false;
  public submitted: boolean = false;
  public remainingWidth: number = undefined;
  public type: 'numeric' | 'input' = 'input';
  public pageSizes = [10, 15, 20, 25, 30, 50];
  public state: State = { skip: 0, take: 10, sort: [{ field: 'loginId', dir: undefined }] };
  public gridView: GridDataResult = process(this.items, this.state);
  public accessTypes: Array<{ id: number, value: string }> = [{ id: 0, value: 'No Filter' }, { id: 1, value: 'Successful' }, { id: 2, value: 'Unauthorized' }];

  constructor()
  {
    this.alertService.clear();
    this.bcService.setItems([{ label: 'User Profile' }, { label: 'Access Log', routerLink: ['/accesslog'] }]);
    if (!this.service.currentUserValue)
    {
      this.router.navigate(['/login']);
    }
  }

  ngOnInit()
  {
    this.spinnerService.hide();
    const loginId = (this.service.currentUserValue?.loginId || '');
    this.canEdit = this.service.currentUserValue?.moduleIds?.includes('ELIT.1.2.5_2') || loginId.toLowerCase() === 'superuser';
    this.accessLogForm = this.formBuilder.group(
      {
        loginId: [{ value: loginId, disabled: !this.canEdit }],
        accessType: [0, [Validators.required, Validators.min(0), Validators.max(2)]],
        endDate: [new Date(), Validators.required],
        startDate: [new Date(), Validators.required],
      });

    this.remainingWidth = window.innerWidth <= 900 ? 250 : undefined;
  }

  get f() { return this.accessLogForm.controls; }

  public dataStateChange(state: DataStateChangeEvent): void
  {
    this.state = state;
    this.loadData();
  }

  private reloadPage(): void
  {
    this.gridView = process(this.items, this.state);
  }

  public clearData(): void
  {
    this.items = [];
    this.state.skip = 0;

    this.reloadPage();
  }

  public loadData(): void
  {
    this.submitted = true;
    this.alertService.clear();
    if (!this.service.currentUserValue)
    {
      this.router.navigate(['/login']);
      return;
    }

    if (this.accessLogForm.invalid)
      return;

    const params =
    {
      loginId: (this.f.loginId.value || ''),
      accessType: this.f.accessType.value,
      endDate: this.f.endDate.value ? this.fnSvc.getDate(new Date(this.f.endDate.value)) : null,
      startDate: this.f.startDate.value ? this.fnSvc.getDate(new Date(this.f.startDate.value)) : null
    };

    this.spinnerService.show();
    this.service.getAccessLog(params).subscribe(
      {
        next: (resp: any) =>
        {
          this.spinnerService.hide();
          if (resp.returnStatus === 200)
          {
            this.items = resp.value || [];
            this.reloadPage();
          }
          else
          {
            this.alertService.error(resp.returnMessage);
          }
        },
        error: (errorMessage: string) =>
        {
          this.spinnerService.hide();
          this.alertService.error(errorMessage);
        }
      });
  }
}
