import { Router } from '@angular/router';
import { NgClass } from '@angular/common';
import { State } from '@progress/kendo-data-query';
import { Component, OnInit, ViewEncapsulation, inject } from '@angular/core';
import { FormGroup, FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { plusIcon, pencilIcon, trashIcon, infoCircleIcon } from "@progress/kendo-svg-icons";
import { GridDataResult, DataStateChangeEvent, KENDO_GRID, RowClassArgs } from '@progress/kendo-angular-grid';
import { DialogService, DialogRef, DialogCloseResult, DialogContainerDirective } from '@progress/kendo-angular-dialog';

import { Api } from '../../providers/api/api';
import { AlertService } from '../components/alert';
import { BreadcrumbService } from '../breadcrumb.service';
import { UserService } from '../../providers/user/user.service.';
import { FunctionService } from '../components/models/function.service';
import { SettingsModuleEnum } from '../components/models/named-parameters.model';

@Component({
  standalone: true,
  selector: 'users',
  encapsulation: ViewEncapsulation.None,
  templateUrl: './users.component.html',
  styles: ['#grdUsers tr.inactive{color:#f00;}'],
  imports: [FormsModule, ReactiveFormsModule, DialogContainerDirective, NgClass, KENDO_GRID]
})
export class UsersComponent 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 dialogService = inject(DialogService);

  public setting: any;
  public usersForm: FormGroup;
  public colWidth: number = 0;
  public canAdd: boolean = false;
  public loading: boolean = false;
  public canEdit: boolean = false;
  public gridView: GridDataResult;
  public viewMode: boolean = false;
  public canDelete: boolean = false
  public submitted: boolean = false;
  public canResetPwd: boolean = false;
  public type: 'numeric' | 'input' = 'input';
  public pageSizes = [5, 10, 15, 20, 25, 30, 50];
  public state: State = { skip: 0, take: 10, sort: [{ field: undefined, dir: undefined }] };
  public icons = { add: plusIcon, edit: pencilIcon, delete: trashIcon, info: infoCircleIcon };

  private items: any[] = [];
  private totalRows: number = 0;
  private settingApplied: boolean = false;

  constructor()
  {
    const bcService = inject(BreadcrumbService);

    this.alertService.clear();
    bcService.setItems([{ label: 'System Setup' }, { label: 'User Management' }, { label: 'Users', routerLink: ['/users'] }]);
    if (!this.service.currentUserValue)
    {
      this.router.navigate(['/login']);
      return;
    }

    this.canAdd = this.service.currentUserValue?.moduleIds?.includes('ELIT.1.2.2_1');
    this.canEdit = this.service.currentUserValue?.moduleIds?.includes('ELIT.1.2.2_2');
    this.canDelete = this.service.currentUserValue?.moduleIds?.includes('ELIT.1.2.2_3');
    this.canResetPwd = this.service.currentUserValue?.moduleIds?.includes('ELIT.1.2.3');

    this.viewMode = !this.canEdit;

    this.loadSetting();
  }

  private loadSetting(): void
  {
    this.loading = true;
    this.service.getLabelSetting(SettingsModuleEnum.User).subscribe(
      {
        next: (resp: any) =>
        {
          this.loading = false;
          if (resp.returnStatus === 200)
          {
            this.setting = resp;
            this.setValidatorsToControls();
          }
        },
        error: (errorMessage: string) =>
        {
          this.loading = false;
          this.alertService.error(errorMessage);
        }
      });
  }

  ngOnInit(): void
  {
    let criteria: string = '';
    let hasValue: boolean = false
    if (Api.TmpValue1?.startsWith('2:'))
    {
      hasValue = true;
      criteria = Api.TmpValue1.substring(2);
    }
    if (Api.TmpValue2?.startsWith('2:'))
    {
      hasValue = true;
      this.state = JSON.parse(Api.TmpValue2.substring(2));
    }

    this.usersForm = this.formBuilder.group({ criteria: criteria });

    this.settingApplied = false;
    this.setValidatorsToControls();

    if (hasValue)
    {
      this.loadData();
    }
  }

  private setValidatorsToControls(): void
  {
    if (!this.settingApplied && this.setting && this.usersForm?.controls)
    {
      this.settingApplied = true;
      this.fnSvc.setValidatorsToToControl({ control: this.f.criteria, required: this.setting.label15Req, regExp: this.setting.label15RegExp, minLen: 0, maxLen: 50 });
    }
  }

  public addHandler(): void
  {
    this.router.navigateByUrl('/newuser', { state: { setting: this.setting } });
  }

  public editHandler({ dataItem }): void
  {
    this.router.navigateByUrl('/edituser', { state: { id: dataItem.userId, setting: this.setting } });
  }

  public removeHandler({ dataItem }): void
  {
    const dialog: DialogRef = this.dialogService.open(
      {
        title: 'Confirmation', content: `Are you sure to delete ${this.setting?.label17 || 'User'}: '` + dataItem.userName + "'?",
        actions: [{ text: 'No', themeColor: 'primary' }, { text: 'Yes', themeColor: 'secondary' }],
        width: 400,
        height: 150,
        minWidth: 250
      });

    dialog.result.subscribe((result) =>
    {
      if (result instanceof DialogCloseResult)
      {
        //Nothing to do
      }
      else if (result.text === 'Yes')
      {
        this.loading = true;
        this.alertService.clear();
        this.service.deleteUser(dataItem.userId).subscribe(
          {
            next: (resp: any) =>
            {
              this.loading = false;
              if (resp.returnStatus === 200)
              {
                this.loadData();
                this.alertService.success(resp.returnMessage);
              }
              else
              {
                this.alertService.error(resp.returnMessage);
              }
            },
            error: (errorMessage: string) =>
            {
              this.loading = false;
              this.alertService.error(errorMessage);
            }
          });
      }
    });
  }

  public dataStateChange(state: DataStateChangeEvent): void
  {
    this.state = state;
    Api.TmpValue2 = '2:' + JSON.stringify(this.state);

    this.loadData();
  }

  public resetPwd(dataItem: any): void
  {
    this.router.navigateByUrl('/resetPwd', { state: { id: dataItem.userId } });
  }

  public viewAuthCode(dataItem: any): void
  {
    const dialog: DialogRef = this.dialogService.open(
      {
        title: 'Authentication ID', content: "Authentication ID for '" + dataItem.loginId + "': " + dataItem.authId, actions: [{ text: 'Okay', themeColor: 'primary' }],
        width: 550,
        height: 160,
        minWidth: 300
      });

    dialog.result.subscribe((result) =>
    {
      if (result instanceof DialogCloseResult)
      {
        //Nothing to do
      }
      else if (result.text === 'Okay')
      {
        this.alertService.clear();
      }
    });
  }

  public unlockUser(dataItem: any): void
  {
    const dialog: DialogRef = this.dialogService.open(
      {
        title: 'Confirmation', content: "Are you sure to Unlock user: '" + dataItem.userName + "'?",
        actions: [{ text: 'No' }, { text: 'Yes', themeColor: 'primary' }],
        width: 450,
        height: 150,
        minWidth: 250
      });

    dialog.result.subscribe((result) =>
    {
      if (result instanceof DialogCloseResult)
      {
        //Nothing to do
      }
      else if (result.text === 'Yes')
      {
        this.loading = true;
        this.alertService.clear();
        this.service.unlockUser(dataItem.userId, dataItem.loginId).subscribe(
          {
            next: (resp: any) =>
            {
              this.loading = false;
              if (resp.returnStatus === 200)
              {
                this.loadData();
                this.alertService.success(resp.returnMessage);
              }
              else
              {
                this.alertService.error(resp.returnMessage);
              }
            },
            error: (errorMessage: string) =>
            {
              this.loading = false;
              this.alertService.error(errorMessage);
            }
          });
      }
    });
  }

  private reloadPage(): void
  {
    this.gridView = { data: this.items, total: this.totalRows };
  }

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

    this.reloadPage();
  }

  public rowCallback(context: RowClassArgs)
  {
    if (context.dataItem.status === 16)
      return { inactive: true };
  }

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

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

    if (this.usersForm.invalid)
      return;

    Api.clearTmpValue();
    Api.TmpValue1 = '2:' + this.f.criteria.value || '';
    Api.TmpValue2 = '2:' + JSON.stringify(this.state);

    const params =
    {
      status: 0,
      skip: this.state.skip,
      pageSize: this.state.take,
      sortOrder: this.state.sort[0]?.dir,
      sortField: this.state.sort[0]?.field,
      criteria: (this.f.criteria.value || ''),
    };

    this.loading = true;
    this.service.getUsers(params).subscribe(
      {
        next: (resp: any) =>
        {
          this.loading = false;
          if (resp.returnStatus === 200)
          {
            this.items = resp.value || [];
            this.totalRows = resp.totalRows;
            if (this.items?.length)
              this.colWidth = (this.canEdit ? 80 : 40) + (this.canDelete ? 40 : 0) + (this.canResetPwd ? 40 : 0);
            else
              this.colWidth = 0;

            this.reloadPage();
          }
          else
          {
            this.alertService.error(resp.returnMessage);
          }
        },
        error: (errorMessage: string) =>
        {
          this.loading = false;
          this.alertService.error(errorMessage);
        }
      });
  }
}

