import { Router } from '@angular/router';
import { DatePipe, NgClass } from '@angular/common';
import { KENDO_DATEINPUTS } from '@progress/kendo-angular-dateinputs';
import { Component, ElementRef, OnInit, ViewChild, inject } from '@angular/core';
import { GridComponent, ColumnComponent, CellTemplateDirective } from '@progress/kendo-angular-grid';
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { WindowCloseResult, WindowRef, WindowService, WindowSettings, WindowState, WindowContainerDirective } from '@progress/kendo-angular-dialog';

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 { ViewDocumentComponent } from '../components/viewdocument/viewdocument.component';

@Component({
  standalone: true,
  selector: 'my-profile',
  templateUrl: './myprofile.component.html',
  imports: [FormsModule, ReactiveFormsModule, NgClass, DatePipe, WindowContainerDirective, GridComponent, ColumnComponent, CellTemplateDirective, KENDO_DATEINPUTS]
})
export class MyProfileComponent 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 windowService = inject(WindowService);
  private readonly functionService = inject(FunctionService);

  public items: any;
  public loading = false;
  public userId: number = 0;
  public myProfileForm: FormGroup;
  public submitted: boolean = false;
  public hasAIApiKey: boolean = false;  
  public colWidth: number = undefined;
  public canDoTestSTT: boolean = false;
  public kWindowOpened: boolean = false;
  public hasPwdChanged: boolean = false;
  public isUserEmployee: boolean = false;
  public hasPayslipPath: boolean = false;
  public hasNextPwdDate: boolean = false
  public readonly acceptFileType: string = '.wav,.mp3';

  private formData: FormData;
  private prvHeight: number = 570;
  @ViewChild('uploadFileLabel') private readonly uploadFileLabel: ElementRef

  constructor()
  {
    const breadcrumbService = inject(BreadcrumbService);
    breadcrumbService.setItems([{ label: 'User Profile' }, { label: 'My Profile', routerLink: ['/myprofile'] }]);
    if (this.service.currentUserValue)
    {
      this.userId = this.service.currentUserValue?.id;
      this.canDoTestSTT = this.service.currentUserValue?.moduleIds?.includes('ELIT.1.2.5_1')
      this.isUserEmployee = this.service.currentUserValue?.employeeId && this.service.currentUserValue?.employeeId > 0;
    }
    else
    {
      this.router.navigate(['/login']);
    }
  }

  ngOnInit()
  {
    let payslipMonth: Date = new Date();
    payslipMonth = this.fnSvc.getFirstDayOfMonth(payslipMonth.getFullYear(), (payslipMonth.getMonth() - 1));
    this.myProfileForm = this.formBuilder.group(
      {
        loginId: '',
        address: '',
        username: '',
        fileName: '',
        contactNo: '',
        designation: '',
        nextPwdDate: '',
        uploadFile: null,
        pwdChangedTime: '',
        payslipMonth: [new Date(payslipMonth), Validators.required]
      });

    this.loading = true;
    this.colWidth = window.innerWidth <= 870 ? 150 : undefined;
    this.fnSvc.setValidatorsToToControl({ control: this.f.address, required: 1, regExp: '', minLen: 1, maxLen: 120 });
    this.fnSvc.setValidatorsToToControl({ control: this.f.contactNo, required: 1, regExp: '', minLen: 1, maxLen: 25 });

    this.service.getMyProfile().subscribe(
      {
        next: (resp: any) =>
        {
          this.loading = false;
          if (resp.returnStatus === 200)
          {
            this.items = resp.loginHistories;
            this.hasAIApiKey = resp.hasAIApiKey;            
            this.hasNextPwdDate = resp.nextPwdDate;
            this.hasPayslipPath = resp.hasPayslipPath;
            this.hasPwdChanged = resp.pwdLastChangedTime;
            this.myProfileForm.patchValue(
              {
                loginId: resp.loginId,
                address: resp.address,
                username: resp.userName,
                contactNo: resp.contactNo,
                designation: resp.designation,
                nextPwdDate: this.hasNextPwdDate ? this.functionService.toFormattedDate(resp.nextPwdDate, 'dd-MMM-yyyy') : '',
                pwdChangedTime: this.hasPwdChanged ? this.functionService.toFormattedDate(resp.pwdLastChangedTime, 'dd-MMM-yyyy H:mm:ss') : ''
              });
          }
          else
          {
            this.alertService.error(resp.returnMessage);
          }
        },
        error: (errorMessage: string) =>
        {
          this.loading = false;
          this.alertService.error(errorMessage);
        }
      });
  }

  public get f() { return this.myProfileForm.controls; }

  public keyPressEvent(event: any): boolean
  {
    return this.fnSvc.validateNumbers({ event: event, includePlus: true });
  }

  public onFileSelected(event: any): void
  {
    const sellectedFile = event.target.files[0];
    const selFileName = sellectedFile.name;
    this.uploadFileLabel.nativeElement.innerText = selFileName;
    this.myProfileForm.patchValue({ fileName: selFileName });

    this.formData = new FormData();
    this.formData.append('fileName', selFileName);
    this.formData.append('fileData', sellectedFile);
  }

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

    if (this.myProfileForm.invalid)
      return;

    const params =
    {
      yearMonth: new Date(this.fnSvc.getDate(new Date(this.f.payslipMonth.value)))
    };
    this.service.getMyPayslip(params).subscribe(
      {
        next: (resp: any) =>
        {
          this.loading = false;
          if (resp.returnStatus === 200)
          {
            const modalOptions: WindowSettings = { title: 'My Payslip', content: ViewDocumentComponent, minWidth: 500, minHeight: 370, height: 570, width: 875, state: 'default' };
            const windowRef: WindowRef = this.windowService.open(modalOptions);
            windowRef.content.instance.fromParent = { reportId: 0, txnId: 0, fileName: '', data: resp.value };

            this.kWindowOpened = true;
            const top: number = window.scrollY > 50 ? (window.scrollY + 50) : 100;
            windowRef.window.instance.setOffset("top", top);
            windowRef.window.instance.heightChange.subscribe(
              (height: number) =>
              {
                windowRef.content.instance.setHeight = this.prvHeight = height;
              });

            windowRef.window.instance.stateChange.subscribe(
              (state: WindowState) =>
              {
                if (state === 'maximized')
                {
                  windowRef.content.instance.setHeight = window.innerHeight;
                }
                else if (state === 'default')
                {
                  windowRef.content.instance.setHeight = this.prvHeight;
                }
              });

            windowRef.result.subscribe(
              (result) =>
              {
                if (result instanceof WindowCloseResult)
                {
                  this.kWindowOpened = false;
                }
              });

            windowRef.content.instance.okayClicked.subscribe(
              () => { this.kWindowOpened = false; windowRef.close(); },
              () => { this.kWindowOpened = false; windowRef.close(); }
            );
          }
          else
          {
            this.alertService.error(resp.returnMessage);
          }
        },
        error: (errorMessage: string) =>
        {
          this.loading = false;
          this.alertService.error(errorMessage);
        }
      });
  }

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

    if (!this.formData)
    {
      this.alertService.error('Select a pdf file first, then try again');
      return;
    }

    this.loading = true;
    this.formData.append('keywordsToSearch', 'My, Name');
    this.service.findKeywordsFromAudio(this.formData).subscribe(
      {
        next: (resp: any) =>
        {
          this.loading = false;
          if (resp.returnStatus === 200)
          {
            this.alertService.info(resp.returnMessage);
          }
          else
          {
            this.alertService.error(resp.returnMessage);
          }
        },
        error: (errorMessage: string) =>
        {
          this.loading = false;
          this.alertService.error(errorMessage);
        }
      });
  }

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

    this.submitted = true;
    if (this.f.address.invalid || this.f.contactNo.invalid)
    {
      return;
    }

    const params = {
      address: (this.f.address.value || ''),
      contactNo: (this.f.contactNo.value || ''),
      employeeId: this.service.currentUserValue.employeeId
    }

    this.service.updateMyInfo(params).subscribe(
      {
        next: (resp: any) =>
        {
          this.loading = false;
          if (resp.returnStatus === 200)
          {
            this.alertService.info(resp.returnMessage);
          }
          else
          {
            this.alertService.error(resp.returnMessage);
          }
        },
        error: (errorMessage: string) =>
        {
          this.loading = false;
          this.alertService.error(errorMessage);
        }
      });
  }
}
