import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';<% if (hasCompanyIdField || hasOrganizationIdField || optionResourceList.length > 0) { %>
import { NcOptionResource, NgCortexService } from '@ng-cortex/core';<% } %>
import { getEntityUpdate, getErrorMessage, isValid, validateForm<% if (formValidatorFieldList.length > 0) { %>, Validators<% } %> } from '@ng-cortex/utils';<% if (formDatePickerFieldList.length > 0) { %>
import { format, parseISO, startOfDay } from 'date-fns';<% } %>
import { NzNotificationService } from 'ng-zorro-antd/notification';
import { Observable, of } from 'rxjs';
import { catchError, map, mergeMap, tap } from 'rxjs/operators';

/** <%= description %>编辑器组件 */
@Component({
  selector: '<%= getSeparatorCase(prefix) %>-<%= getSeparatorCase(name) %>-editor',
  templateUrl: './<%= getSeparatorCase(name) %>-editor.component.html',
  styleUrls: ['./<%= getSeparatorCase(name) %>-editor.component.less']
})
export class <%= getPascalCase(name) %>EditorComponent implements OnInit, OnDestroy {

  /** <%= description %> */
  @Input() <%= getCamelCase(name) %>: any = null;

  /** <%= description %>表单 */
  _<%= getCamelCase(name) %>Form!: FormGroup;<% optionResourceList.forEach(function(optionResource) { %>
  /** <%= optionResource.name %>选项资源 */
  _<%= optionResource.name %>OptionResource!: NcOptionResource;<% }) %>

  /** 取消提交 */
  private _cancelSubmitFn = () => { };

  constructor(
    private _formBuilder: FormBuilder,
    private _httpClient: HttpClient<% if (hasCompanyIdField || hasOrganizationIdField || optionResourceList.length > 0) { %>,
    private _ngCortexService: NgCortexService<% } %>,
    private _nzNotificationService: NzNotificationService) { }

  /** 初始化后 */
  ngOnInit(): void {

    // 构建<%= description %>表单
    this._<%= getCamelCase(name) %>Form = this._formBuilder.group({<% formFieldList.forEach(function(field, index) { %>
      <%= getCamelCase(field.key) %>: [null<% if (field.controlValidators.length > 0) { %>, [<%= field.controlValidators.join(', ') %>]<% } %>]<% if (index < formFieldList.length - 1) { %>,<% } %><% }) %>
    });

    // 生成<%= description %>表单补丁<% if (hasCompanyIdField || hasOrganizationIdField) { %>
    const { <% if (hasCompanyIdField) { %>companyId<% } %><% if (hasCompanyIdField && hasOrganizationIdField) { %>, <% } %><% if (hasOrganizationIdField) { %>organizationId<% } %> } = this._ngCortexService.data.passport!;<% } %>
    const <%= getCamelCase(name) %>FormPatch = {<% if (hasCompanyIdField) { %>
      companyId: companyId,<% } %><% if (hasOrganizationIdField) { %>
      organizationId: organizationId,<% } %>
      ...this.<%= getCamelCase(name) %>
    };<% formDatetimePickerFieldList.forEach(function(field) { %>
    if (<%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %>) {
      <%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %> = new Date(<%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %>);
    }<% }) %><% formDatePickerFieldList.forEach(function(field) { %>
    if (<%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %>) {
      <%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %> = startOfDay(parseISO(<%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %>));
    }<% }) %><% formSelectMultipleFieldList.forEach(function(field) { %>
    if (<%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %>) {
      <%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %> = JSON.parse(<%= getCamelCase(name) %>FormPatch.<%= getCamelCase(field.key) %>) || [];
    }<% }) %><% optionResourceList.forEach(function(optionResource) { %>

    // 获取<%= optionResource.name %>选项资源
    const <%= optionResource.name %>OptionUrl = '<%= optionResource.url %>';
    this._<%= optionResource.name %>OptionResource = this._ngCortexService.getOptionResource(<%= optionResource.name %>OptionUrl, {
      error: error => this._nzNotificationService.error('获取<%= optionResource.name %>列表失败', getErrorMessage(error))
    });<% }) %>

    // 更新<%= description %>表单值
    this._<%= getCamelCase(name) %>Form.patchValue(<%= getCamelCase(name) %>FormPatch);
  }

  /** 注销后 */
  ngOnDestroy(): void {
    this._cancelSubmitFn();
  }

  /** 提交 */
  submit(): Observable<{ success: boolean; updated: any; }> {
    return new Observable(subscriber => {
      const submitResult = {
        success: false,
        updated: null
      };
      const <%= getCamelCase(name) %>Update = this._get<%= getPascalCase(name) %>Update();
      const submitSubscription = validateForm(this._<%= getCamelCase(name) %>Form)
        .pipe(mergeMap(valid => {
          if (valid) {
            if (<%= getCamelCase(name) %>Update) {
              return this._submit<%= getPascalCase(name) %>(<%= getCamelCase(name) %>Update)
                .pipe(tap(<%= getCamelCase(name) %>Updated => {
                  submitResult.success = true;
                  submitResult.updated = <%= getCamelCase(name) %>Updated;
                }));
            } else {
              submitResult.success = true;
            }
          }
          return of(undefined);
        }))
        .pipe(catchError(() => of(undefined)))
        .pipe(map(() => submitResult))
        .subscribe(subscriber);
      this._cancelSubmitFn = () => {
        submitSubscription.unsubscribe();
      };
    });
  }<% if (formInputNumberFieldList.length > 0) { %>

  /**
   * 格式化数字
   * @param numberValue 数值
   */
  _formatterNumber(numberValue: number): string {
    if (typeof numberValue === 'number') {
      return numberValue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }
    return '';
  }<% } %>

  /** 获取<%= description %>更新 */
  private _get<%= getPascalCase(name) %>Update(): any {
    const <%= getCamelCase(name) %>FormValue = { ...this._<%= getCamelCase(name) %>Form.getRawValue() };
    for (const key in <%= getCamelCase(name) %>FormValue) {
      if (!isValid(<%= getCamelCase(name) %>FormValue[key])) {
        <%= getCamelCase(name) %>FormValue[key] = null;
      }
    }<% formDatePickerFieldList.forEach(function(field) { %>
    if (<%= getCamelCase(name) %>FormValue.<%= getCamelCase(field.key) %>) {
      <%= getCamelCase(name) %>FormValue.<%= getCamelCase(field.key) %> = format(<%= getCamelCase(name) %>FormValue.<%= getCamelCase(field.key) %>, 'yyyy-MM-dd');
    }<% }) %><% formSelectMultipleFieldList.forEach(function(field) { %>
    if (<%= getCamelCase(name) %>FormValue.<%= getCamelCase(field.key) %>) {
      <%= getCamelCase(name) %>FormValue.<%= getCamelCase(field.key) %> = JSON.stringify(<%= getCamelCase(name) %>FormValue.<%= getCamelCase(field.key) %>);
    }<% }) %>
    const <%= getCamelCase(name) %>Update = getEntityUpdate(<%= getCamelCase(name) %>FormValue, this.<%= getCamelCase(name) %>);
    return <%= getCamelCase(name) %>Update;
  }

  /**
   * 提交<%= description %>
   * @param update 更新
   */
  private _submit<%= getPascalCase(name) %>(update: any): Observable<any> {
    const url = '@<%= serviceName %>/api/<%= getPluralForm(getSeparatorCase(name)) %>';
    const body = update;
    if (body.id) {
      return this._httpClient.patch(url, body).pipe(tap(
        () => {
          this._nzNotificationService.success('更新<%= description %>成功', null!);
        },
        (httpErrorResponse: HttpErrorResponse) => {
          this._nzNotificationService.error('更新<%= description %>失败', getErrorMessage(httpErrorResponse));
        }));
    } else {
      return this._httpClient.post(url, body).pipe(tap(
        () => {
          this._nzNotificationService.success('新增<%= description %>成功', null!);
        },
        (httpErrorResponse: HttpErrorResponse) => {
          this._nzNotificationService.error('新增<%= description %>失败', getErrorMessage(httpErrorResponse));
        }));
    }
  }

}
