import { Component, inject } from '@angular/core';
import { AbstractControl, NonNullableFormBuilder, Validators } from '@angular/forms';
import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal';
import { Md5 } from 'ts-md5';
import { getRealPostNameFormLineString, REGEXP_PHONE } from '../../../../app.util';
import { CommonNzModule } from '../../../../common.nz.module';
import { ApiService } from '../../../../services/api.service';
import { SettingService } from '../../../../services/setting.service';

export interface UserFormModalData {
  data?: Auth.User;
  type: 'add' | 'edit';
  statusOptions: Option<number>[];
  lines: BasicData.Predefine[];
  roleOptions: Option<string>[];
  jobs: BasicData.Job[];
  jobGroups: Option<string>[];
  departments: BasicData.Department[];
}

@Component({
  selector: 'app-user-form',
  standalone: true,
  imports: [CommonNzModule],
  templateUrl: './user-form.component.html',
  styleUrl: './user-form.component.less',
})
export class UserFormComponent {
  readonly nzModalData: UserFormModalData = inject(NZ_MODAL_DATA);
  validateForm = this.fb.group({
    username: this.fb.control<string>('', {
      validators: [Validators.required],
      updateOn: 'blur',
    }),
    company: this.fb.control<string>('', {
      validators: [],
    }),
    department: this.fb.control<number | undefined>(undefined, {
      validators: [],
    }),
    gender: this.fb.control<string>('', {
      validators: [Validators.required],
    }),
    empno: this.fb.control<string>('', {
      validators: [Validators.required, this.empnoValidator],
    }),
    job: this.fb.control<number | undefined>(undefined, {
      validators: [],
    }),
    jobGroup: this.fb.control<string>('', {
      validators: [],
    }),
    line: this.fb.control<string>('', {
      validators: [],
    }),
    startingDate: this.fb.control<string>('', {
      validators: [],
    }),
    roles: this.fb.control<string[]>([], {
      validators: [Validators.required],
    }),
    phone: this.fb.control<string>('', {
      validators: [this.phoneValidator],
      updateOn: 'blur',
    }),
    email: this.fb.control<string>('', {
      validators: [Validators.email],
      updateOn: 'blur',
    }),
    status: this.fb.control<number>(0, {
      updateOn: 'blur',
    }),
  });
  loading = false;
  get jobOptions() {
    return this.nzModalData.jobs.filter(item => item.name !== '全体员工');
  }
  getJobOptions() {
    const line = this.validateForm.get('line')?.value;
    const department = this.validateForm.get('department')?.value;
    if (!department) return [];
    return this.jobOptions
      .filter(j => j.department === department)
      .map(item => ({
        label: line ? getRealPostNameFormLineString(line, item.name) : item.name,
        value: item.id,
      }));
  }

  get statusOptions() {
    return this.nzModalData.statusOptions;
  }

  constructor(
    private fb: NonNullableFormBuilder,
    private setting: SettingService,
    private api: ApiService
  ) {}

  patchValue() {
    const { data } = this.nzModalData;
    if (!data) return;
    this.validateForm.patchValue({
      company: data?.company,
      username: data?.name,
      line: data?.line,
      job: data?.job,
      jobGroup: data?.jobGroup,
      gender: data?.gender,
      empno: data?.empno,
      startingDate: data?.startingDate,
      roles: data?.roles,
      department: data?.department,
      phone: data?.phone,
      email: data?.email,
    });
  }
  validate() {
    return new Promise<
      Partial<{
        username: string;
        phone: string;
        email: string;
        name: string;
        password: string;
        roles: string[];
        status: number;
        id: string;
        department: number;
        line: string;
        job: number;
        jobGroup: string;
        gender: string;
        empno: string;
        startingDate: string;
        company: 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({
        company: this.setting.userCompany,
        ...this.validateForm.value,
      });
    });
  }
  onDepartmentChange() {
    this.validateForm.get('job')?.reset();
  }
  resetForm() {
    this.validateForm.reset();
    this.patchValue();
  }
  ngOnInit() {
    this.patchValue();
  }
  phoneValidator(control: AbstractControl) {
    if (!control.value) {
      return {};
    } else if (!REGEXP_PHONE.test(control.value)) {
      return { phone: true, error: true };
    }
    return {};
  }
  empnoValidator(control: AbstractControl) {
    if (!control.value) {
      return { error: true, required: true };
    }
    if (control.value.length < 4) {
      return { error: true, msg: '工号长度不能小于4位' };
    }
    // 工号只能包含大小写字母和数字
    if (!/^[a-zA-Z0-9]+$/.test(control.value)) {
      return { error: true, msg: '工号只能包含大小写字母和数字' };
    }
    return {};
  }
  async submit(): Promise<any> {
    if (this.loading) return;
    this.loading = true;
    const result = await this.validate().finally(() => (this.loading = false));
    if (!result) {
      return Promise.reject();
    }
    if (this.nzModalData.type === 'edit') {
      result.id = this.nzModalData.data?.id;
    }
    if (result.password) {
      result.password = Md5.hashStr(result.password);
    }
    return Promise.resolve(result);
  }
  get departments() {
    return this.nzModalData.departments;
  }
  get roleOptions() {
    return this.nzModalData.roleOptions;
  }
  get jobGroupOptions() {
    return this.nzModalData.jobGroups;
  }
  get lineOptions() {
    return this.nzModalData.lines;
  }
  get isEditMode() {
    return this.nzModalData.type === 'edit';
  }
}
