import { EventEmitter, Injectable, TemplateRef, Type } from '@angular/core';
import { FormArray, FormGroup } from '@angular/forms';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { ModalButtonOptions, NzModalService } from 'ng-zorro-antd/modal';
import { MESSAGE_UTIL } from '../../conf/message';
import { FormProperty, retrieveSchema } from '@delon/form';
import { NzMessageService } from 'ng-zorro-antd/message';
import { _HttpClient } from '@delon/theme';

declare var FakeServer: any;

@Injectable({
  providedIn: 'root'
})
export class BaseService {
  public drawerWidth = 550;

  deptmentServiceUrl = ''; //

  constructor(
    private http: _HttpClient,
    private modalService: NzModalService,
    private message: NzMessageService
  ) {}

  hasError(...args: (FormGroup | FormProperty | null)[]): boolean {
    const result = this.hasErrorBase(args);

    return result;
  }

  hasErrorBase(args: (FormGroup | FormProperty | null)[]): boolean {
    let result = false;
    if (!args) {
      return result;
    }
    args.forEach((val: any) => {
      if (val instanceof FormGroup) {
        for (const key in val.controls) {
          const ctl = val.controls[key];
          if (ctl instanceof FormGroup) {
            result = this.hasErrorBase([ctl]) || result;
          } else if (ctl instanceof FormArray) {
            (ctl as FormArray).controls.forEach(c => {
              c.markAsDirty();
              c.updateValueAndValidity();
              result = c.invalid || result;
            });
          } else {
            ctl.markAsDirty();
            ctl.updateValueAndValidity();
            result = ctl.invalid || result;
          }
        }
      } else if (val instanceof FormProperty) {
        const properties = val.root.properties as FormProperty[];
        if (properties) {
          for (const key in properties) {
            const ctl = properties[key];
            if (ctl instanceof FormProperty) {
              ctl.updateValueAndValidity();
              result = ctl.valid || result;
            }
          }
        }
      }
    });
    return result;
  }

  public getMessage(messageId: string, ...params: string[]): string {
    return this.getMessageBase(messageId, params);
  }

  private getMessageBase(messageId: string, params: string[]): string {
    return MESSAGE_UTIL.getMessage(messageId, params);
  }

  /**
   * ocean 2023-4-17
   * message提示框
   */
  public showMessage(state: { messageId: string }) {
    this.message.info(this.getMessage(state.messageId));
  }

  public showConfirm(state: { title?: string; message?: string; okCallback?: () => void; cancelCallback?: () => void }) {
    this.modalService.create({
      nzTitle: state.title,
      nzContent: state.message,
      nzClosable: false,
      nzBodyStyle: { 'font-size': '1.5rem' },
      nzOnOk: () => {
        if (state.okCallback) {
          state.okCallback();
        }
      },
      nzOnCancel: () => {
        if (state.cancelCallback) {
          state.cancelCallback();
        }
      }
    });
  }

  public showModal(config: AppModalConfig) {
    let width = 600;
    switch (config.widthClass) {
      case 'xxl':
        width = 1200;
        break;
      case 'xl':
        width = 1000;
        break;
      case 'lg':
        width = 800;
        break;
      case 'sm':
        width = 600;
        break;
      case 'xs':
        width = 400;
        break;
    }
    const modal = this.modalService.create({
      nzTitle: config.title,
      nzContent: config.component,
      nzData: config.componentParams,
      nzClosable: true,
      nzWidth: width,
      nzOnOk: config.okCallBack,
      nzFooter: config.footer,
      nzStyle: config.style
    });
    return modal;
  }

  public async post(url: string, method: 'put' | 'post' | 'get' | 'delete', params?: any) {
    switch (method) {
      case 'put':
        return this.http.put(url, params).subscribe(res => {});
        break;
      case 'post':
        return this.http.post(url, params).subscribe(res => {});
        break;
      case 'get':
        return this.http.get(url, params).subscribe(res => {});
        break;
      case 'delete':
        return this.http.delete(url, params).subscribe(res => {});
        break;
    }
  }
}

export class AppModalConfig {
  title?: string | TemplateRef<{}>;
  component?: string | TemplateRef<NzSafeAny> | Type<any>;
  componentParams?: any;
  okCallBack?: () => void;
  widthClass?: 'xxl' | 'xl' | 'lg' | 'sm' | 'xs';
  footer?: string | TemplateRef<{}> | Array<ModalButtonOptions<any>> | null;
  style?: Object;
}
