import { Component, OnInit, ViewChild, inject } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { STChange, STColumn, STComponent, STData } from '@delon/abc/st';
import { SFComponent, SFSchema } from '@delon/form';
import { ModalHelper, SettingsService, _HttpClient } from '@delon/theme';
import { SHARED_IMPORTS } from '@shared';
import { NzModalService } from 'ng-zorro-antd/modal';
import { AppValidators } from 'src/app/core/utils/app-validators';
import { BaseService } from 'src/app/core/utils/base.service';
import { SharedModule } from '@shared';

export interface TreeNodeInterface {
  id: string;
  deptCodg: string;
  deptName: string;
  itro: string;
  srtNo: number;
  level?: number;
  expand?: boolean;
  children?: TreeNodeInterface[];
  parent?: TreeNodeInterface;
}

const addTitle = '新增部门信息';
const editTitle = '修改部门信息';

@Component({
  selector: 'app-sys-dept-manage',
  standalone: true,
  imports: [SharedModule, ...SHARED_IMPORTS],
  templateUrl: './dept-manage.component.html'
})
export class SysDeptManageComponent implements OnInit {
  private readonly http = inject(_HttpClient);
  private readonly modal = inject(ModalHelper);
  private readonly fb = inject(FormBuilder);
  private readonly baseService = inject(BaseService);
  private readonly modalService = inject(NzModalService);
  private readonly settings = inject(SettingsService);

  public url = `/api/main/dept-info`;
  public deptList: TreeNodeInterface[] = []; //菜单列表
  public editVisible = false;
  public detailTitle = '';
  public filter = '';
  public currentOrgan: any; //当前机构
  public organList: any; //结构列表
  public catyList: any; //科别列表
  public mapOfExpandedData: { [id: string]: TreeNodeInterface[] } = {};

  searchSchema: SFSchema = {
    properties: {
      filter: {
        type: 'string',
        title: '关键字过滤'
      }
    }
  };

  public editForm = this.fb.group({
    id: [],
    parentId: [''],
    parentName: [''],
    organId: [null, AppValidators.required('E0001', '所属机构')],
    deptCodg: [null, AppValidators.required('E0001', '部门编码')], // 部门编号
    deptName: [null, AppValidators.required('E0001', '部门名称')], // 部门名称
    deptAssocAttrs: [], // 属性
    srtNo: [0], // 序号
    begntime: [, AppValidators.required('E0001', '开始时间')], // 开始时间
    endtime: [], // 结束时间
    itro: [], // 简介
    catyCode: [, AppValidators.required('E0001', '科别')], // 科别
    catyName: [, AppValidators.required('E0001', '科别')], // 科别
    memo: [] // 备注
  });

  @ViewChild('sf') private readonly sf!: SFComponent;

  // 属性
  public propertyList: any;
  public propertyColumns: STColumn[] = [
    { title: '编号', index: 'value.id', type: 'checkbox' },
    { title: '属性代码', index: 'deptAttrCodg' },
    { title: '属性名称', index: 'deptAttrName' },
    { title: '说明', index: 'exp' }
  ];
  public propertyCheckedList!: any;

  ngOnInit(): void {
    this.getOrganList();
    this.currentOrgan = this.settings.user['currentOrgan'];
    this.getDeptmentProperty([]);
    this.getDataDictList();
    this.editForm.get('parentName')?.disable();
    this.editForm.get('organId')?.disable();
    this.getDeptList(this.filter);
  }

  /**
   * ocean 2023-10-27
   * 获取字典列表
   */
  getDataDictList() {
    var url = '/api/main/data-dict/grp-dict-list?DataDictTypeCode=caty';
    this.http.get(url).subscribe(res => {
      this.catyList = res.caty;
    });
  }

  /**
   * ocean 2024-1-14
   * 获取机构列表
   */
  getOrganList() {
    this.http.get(`/api/main/organ-info`).subscribe(res => {
      this.organList = res.items;
    });
  }

  search() {
    this.filter = this.sf.value['filter'];
    this.getDeptList(this.filter);
  }

  /**
   * ocean 2024-1-18
   * 获取科室列表
   */
  getDeptList(filter: string) {
    const req = {
      filter: filter ?? '',
      organId: this.currentOrgan.id
    };

    this.http.get(this.url, req).subscribe(res => {
      this.deptList = res;

      this.deptList.forEach(item => {
        this.mapOfExpandedData[item.id] = this.convertTreeToList(item);
      });
    });
  }

  /**
   * ocean 2023-4-17
   * 新建
   */
  add() {
    if (this.currentOrgan != null) {
      this.editForm.reset({
        organId: this.currentOrgan.id
      });
      this.editVisible = true;
      this.detailTitle = addTitle;
    }
  }

  addChild(item: { id: any; deptName: any }) {
    this.add();
    this.editForm.patchValue({
      parentId: item.id,
      parentName: item.deptName
    });
  }

  /**
   * ocean 2023-4-17
   * 修改
   */
  edit(data: any) {
    this.http.get(`${this.url}/${data.id}`).subscribe(res => {
      this.editForm.patchValue(res);
      this.editVisible = true;
      this.detailTitle = editTitle;
      this.getDeptmentProperty(res.deptAssocAttrs);
    });
  }

  /**
   * ocean 2023-4-17
   * 保存
   */
  save() {
    if (this.baseService.hasError(this.editForm)) {
      return;
    }
    const request = this.editForm.getRawValue();
    request.deptAssocAttrs = this.propertyCheckedList?.map((e: { id: any }) => {
      return { deptAttrId: e.id };
    });

    if (request.id) {
      this.http.put(`${this.url}/${request.id}`, request).subscribe(async res => {
        this.getDeptList(this.filter);
        this.getDeptmentProperty([]);
        this.close();
      });
    } else {
      this.http.post(this.url, request).subscribe(async res => {
        this.getDeptList(this.filter);
        this.getDeptmentProperty([]);
        this.close();
      });
    }
  }

  del(item: { id: any }) {
    this.http.delete(`${this.url}/${item.id}`).subscribe(async res => {
      this.getDeptList(this.filter);
    });
  }

  close() {
    this.editVisible = false;
  }

  convertTreeToList(root: TreeNodeInterface): TreeNodeInterface[] {
    const stack: TreeNodeInterface[] = [];
    const array: TreeNodeInterface[] = [];
    const hashMap = {};
    stack.push({ ...root, level: 0, expand: false });

    while (stack.length !== 0) {
      const node = stack.pop()!;
      this.visitNode(node, hashMap, array);
      if (node.children) {
        for (let i = node.children.length - 1; i >= 0; i--) {
          stack.push({ ...node.children[i], level: node.level! + 1, expand: false, parent: node });
        }
      }
    }

    return array;
  }

  visitNode(node: TreeNodeInterface, hashMap: { [id: string]: boolean }, array: TreeNodeInterface[]): void {
    if (!hashMap[node.id]) {
      hashMap[node.id] = true;
      array.push(node);
    }
  }

  collapse(array: TreeNodeInterface[], data: TreeNodeInterface, $event: boolean): void {
    if (!$event) {
      if (data.children) {
        data.children.forEach(d => {
          const target = array.find(a => a.id === d.id)!;
          target.expand = false;
          this.collapse(array, target, false);
        });
      } else {
        return;
      }
    }
  }

  /**
   * 下拉列表选择变化处理
   */
  selecteOptionChange(val: any, type: number) {
    switch (type) {
      case 0: //项目分类
        if (this.catyList) {
          const data = this.catyList.find((m: { dataDictCode: any }) => m.dataDictCode == val);
          if (data) {
            this.editForm.patchValue({
              catyName: data.dataDictName
            });
          }
        }
        break;
    }
  }

  /**
   * ocean 2023-7-20
   * 获取属性列表
   */
  getDeptmentProperty(deptmentAsProperties: any) {
    // this.http.get('/api/main/dept-attr').subscribe(res => {
    //   this.propertyList = res.items.map((r: { id: any; deptAttrCodg: any; deptAttrName: any; exp: any }) => {
    //     const isChecked = deptmentAsProperties
    //       .map((d: { deptAttrId: any }) => {
    //         return d.deptAttrId;
    //       })
    //       .includes(r.id);

    //     return {
    //       id: r.id,
    //       deptAttrCodg: r.deptAttrCodg,
    //       deptAttrName: r.deptAttrName,
    //       exp: r.exp,
    //       isChecked: isChecked
    //     };
    //   });
    // });
  }

  /**
   * ocean 2023-9-2
   * 属性结果
   */
  dataProcess(data: STData[]): STData[] {
    return data.map((i, index) => {
      i.checked = i['isChecked'];
      return i;
    });
  }

  /**
   * ocean 2023-9-3
   * 属性变化
   */
  propertyChange(e: STChange): void {
    if (e.type == 'checkbox') {
      this.propertyCheckedList = e.checkbox;
    }
  }
}
