import { Component, inject } from '@angular/core';
import { AbstractControl, NonNullableFormBuilder, Validators } from '@angular/forms';
import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal';
import { REGEXP_PHONE } from '../../../../app.util';
import { CommonNzModule } from '../../../../common.nz.module';

export interface UserModifyRolesModalData {
  data?: Auth.User;

  roleOptions: Option<string>[];
}

@Component({
  selector: 'user-modify-roles',
  standalone: true,
  imports: [CommonNzModule],
  templateUrl: './user-roles-form.component.html',
  styleUrl: './user-roles-form.component.less',
})
export class UserModifyRolesComponent {
  readonly nzModalData: UserModifyRolesModalData = inject(NZ_MODAL_DATA);
  validateForm = this.fb.group({
    roles: this.fb.control<string[]>([], {
      validators: [Validators.required],
      // updateOn: 'blur',
    }),
  });
  loading = false;
  get roleOptions() {
    return this.nzModalData.roleOptions;
  }
  constructor(private fb: NonNullableFormBuilder) {}
  patchValue() {
    const { data } = this.nzModalData;
    if (!data) return;
    this.validateForm.patchValue({
      roles: data?.roles,
    });
  }
  validate() {
    return new Promise<
      Partial<{
        roles: string[];
        username: string;
      }>
    >((resolve, reject) => {
      if (!this.validateForm.valid) {
        Object.values(this.validateForm.controls).forEach(control => {
          if (control.invalid) {
            control.markAsDirty();
            control.updateValueAndValidity({ onlySelf: true });
          }
        });
        return reject();
      }
      return resolve({
        ...this.validateForm.value,
        roles: this.validateForm.value.roles || [],
        username: this.nzModalData.data?.id,
      });
    });
  }
  resetForm() {
    this.validateForm.reset();
    this.patchValue();
  }
  ngOnInit() {
    this.patchValue();
  }
  phoneValidator(control: AbstractControl) {
    if (!control.value) {
      return { error: true, required: true };
    } else if (!REGEXP_PHONE.test(control.value)) {
      return { phone: true, error: true };
    }
    return {};
  }
  async submit(): Promise<Partial<Auth.User>> {
    if (this.loading) return {};
    this.loading = true;
    const result = await this.validate();
    if (!result) {
      this.loading = false;
      return Promise.reject();
    }
    return Promise.resolve(result);
  }
}
