import { ChangeDetectionStrategy, Component } from '@angular/core';
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
import { EmployeeInviteResponse } from '@msfa-models/api/employee-invite.response.model';
import { EmployeeService } from '@msfa-services/api/employee.service';
import { CommaSeparatedEmailValidator } from '@msfa-utils/validators/email.validator';
import { RequiredValidator } from '@msfa-utils/validators/required.validator';
import { BehaviorSubject, Observable } from 'rxjs';

@Component({
  selector: 'msfa-employee-invite',
  templateUrl: './employee-invite.component.html',
  styleUrls: ['./employee-invite.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class EmployeeInviteComponent {
  formGroup: FormGroup = new FormGroup({
    emails: new FormControl('', [RequiredValidator('E-postadresser'), CommaSeparatedEmailValidator()]),
  });
  private _lastInvites$ = new BehaviorSubject<EmployeeInviteResponse>(null);
  lastInvites$: Observable<EmployeeInviteResponse> = this._lastInvites$.asObservable();

  constructor(private employeeService: EmployeeService) {}

  get emailsControl(): AbstractControl {
    return this.formGroup.get('emails');
  }

  get lastInvites(): EmployeeInviteResponse {
    return this._lastInvites$.getValue();
  }

  get emailsControlValueAsArray(): string[] {
    return (this.emailsControl.value as string)
      .replaceAll(/\n|\t|\r|\s/g, '')
      .split(',')
      .filter(email => !!email);
  }

  get lastInvitedNewUsers(): string[] {
    return this.lastInvites?.invitedUsers || [];
  }
  get lastInvitedAssignedUsers(): string[] {
    const assignedUsers = this.lastInvites?.assignedUsers || [];
    return assignedUsers.map(user => user.email);
  }
  get lastInvitedExistingUsers(): string[] {
    const existingUsersInCurrentOrg = this.lastInvites?.existingUsersInCurrentOrg || [];
    return existingUsersInCurrentOrg.map(user => user.email);
  }
  get lastInvitedFailedInvites(): string[] {
    const failedInvites = this.lastInvites?.failedInvite || [];
    return failedInvites;
  }
  get lastInvitedAlreadyInvitedUsers(): string[] {
    const alreadyInvitedUsers = this.lastInvites?.alreadyInvitedUsers || [];
    return alreadyInvitedUsers.map(user => user.email);
  }

  get alertTexts(): { variation: string; heading: string } {
    if (this.lastInvitedFailedInvites.length) {
      if (
        this.lastInvitedNewUsers.length ||
        this.lastInvitedExistingUsers.length ||
        this.lastInvitedAlreadyInvitedUsers.length
      ) {
        return {
          variation: 'warning',
          heading: 'Något gick fel',
        };
      }

      return {
        variation: 'danger',
        heading: 'Inbjudningar har inte skickats!',
      };
    }

    return {
      variation: 'success',
      heading: 'Allt gick bra',
    };
  }

  submitForm(): void {
    this._lastInvites$.next(null);
    if (this.formGroup.invalid) {
      this.emailsControl.markAsDirty();
      this.emailsControl.markAsTouched();
      return;
    }

    const post = this.employeeService.postEmployeeInvitation(this.emailsControlValueAsArray).subscribe({
      next: data => {
        this._lastInvites$.next(data);
        this.formGroup.reset();
      },
      complete: () => {
        post.unsubscribe();
      },
    });
  }

  onCloseAlert(): void {
    this._lastInvites$.next(null);
  }
}
