import { Component, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core';
import { NonNullableFormBuilder, Validators } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { Subscription } from 'rxjs';
import { CommonNzModule } from '../../../../common.nz.module';
import { ApiService } from '../../../../services/api.service';
import { BasicDataService } from '../../../../services/basic.service';
import { KnowledgeService } from '../../../../services/knowledge.service';
import { SettingService } from '../../../../services/setting.service';
import { RiskTypeCategoryNavComponent } from '../../../../shared/risk-type-category-nav/risk-type-category-nav.component';

type PoeItem = BasicData.Position | BasicData.Operation | BasicData.Equipment;

export enum PoeType {
  Position = 1,
  Operation = 2,
  Equipment = 3,
}
export const poeTabs = [
  {
    label: '场所',
    value: PoeType.Position,
  },
  {
    label: '作业',
    value: PoeType.Operation,
  },
  {
    label: '设备',
    value: PoeType.Equipment,
  },
];

/**
 * 基础数据 - 场所/作业/设备
 */
@Component({
  selector: 'basic-poe',
  standalone: true,
  imports: [CommonNzModule, RiskTypeCategoryNavComponent],
  templateUrl: './poe.component.html',
  styleUrl: './poe.component.less',
})
export class PoeComponent {
  @ViewChild('formTpl') formTpl!: TemplateRef<void>;

  subs = new Subscription();
  types: OptionWithCount<number>[] = [];
  categories: OptionWithCount<number>[] = [];
  poeTabs = poeTabs;
  activeTab = PoeType.Position;
  selectedType = -1;
  selectedCategory = -1;
  isEdit = false;

  modalInstance?: NzModalRef<TemplateRef<void>, any>;
  loading = false;
  validateForm = this.fb.group({
    name: this.fb.control<string>('', [Validators.required]),
  });
  constructor(
    private fb: NonNullableFormBuilder,
    private viewContainerRef: ViewContainerRef,
    private modal: NzModalService,
    private knowledge: KnowledgeService,
    private basic: BasicDataService,
    private setting: SettingService,
    private message: NzMessageService,
    private api: ApiService
  ) {
    const sub = this.knowledge.onTypesChange.subscribe(() => {
      this.resetSelected();
    });
    this.subs.add(sub);
  }
  ngOnInit() {
    this.resetSelected();
  }
  ngOnDestroy() {
    this.subs.unsubscribe();
  }
  resetSelected() {
    this.types = this.getTypes();
    if (this.selectedType === -1) {
      this.selectedTypeChange(this.types.find(c => c.count > 0)?.value || -1);
    } else {
      this.categories = this.getCategories(this.selectedType);
    }
    if (this.selectedCategory === -1) {
      this.selectedCategoryChange(this.categories.find(c => c.count > 0)?.value || -1);
    }
  }
  getTypes(): OptionWithCount<number>[] {
    return this.allTypes.map(type => ({
      label: type.value,
      value: type.id,
      count: this.list.filter(item => item.type === type.id).length,
    }));
  }
  activeTabChange(value: number) {
    this.activeTab = value;
    this.resetSelected();
  }
  selectedTypeChange(value: number) {
    this.selectedType = value;
    this.categories = this.getCategories(value);
    const validCategory = this.categories.find(c => c.count > 0)?.value || -1;
    if (this.selectedCategory === -1) {
      this.selectedCategory = validCategory;
    }
    if (validCategory !== -1) {
      this.selectedCategoryChange(validCategory);
    }
  }
  selectedCategoryChange(value: number) {
    this.selectedCategory = value;
  }

  getCategories(typeId: number): OptionWithCount<number>[] {
    const options = this.knowledge.getCategoryOptionsByType(typeId);
    return options.map(option => ({
      ...option,
      count: this.list.filter(item => item.category === option.value).length,
    }));
  }
  addPoe() {
    this.validateForm.reset();
    this.modalInstance = this.modal.create<TemplateRef<void>, {}>({
      nzContent: this.formTpl,
      nzViewContainerRef: this.viewContainerRef,
      nzClassName: 'precaution-modal',
      nzClosable: true,
      nzData: {},
      nzWidth: 500,
      nzTitle: '新增' + this.currentTabLabel,
      nzOnOk: async () => {
        await this.validate();
        return this.onAdd();
      },
    });
  }
  async validate() {
    return new Promise<boolean>((resolve, reject) => {
      if (!this.validateForm.valid) {
        Object.values(this.validateForm.controls).forEach(control => {
          if (control.invalid) {
            control.markAsDirty();
            control.updateValueAndValidity({ onlySelf: true });
          }
        });
        reject(false);
      }
      resolve(true);
    });
  }
  editItem(item: PoeItem) {
    this.validateForm.patchValue({
      name: item.name,
    });
    this.modal.create<TemplateRef<void>, {}>({
      nzContent: this.formTpl,
      nzViewContainerRef: this.viewContainerRef,
      nzClassName: 'precaution-modal',
      nzClosable: true,
      nzData: {},
      nzWidth: 500,
      nzTitle: '编辑' + this.currentTabLabel + '【' + item.name + '】',
      nzOnOk: async () => {
        await this.validate();
        return await this.onEdit(item);
      },
    });
  }
  deleteItem(item: PoeItem) {
    this.deleteApi(item.id).then(() => {
      this.message.success('删除成功');
      this.refreshList();
    });
  }
  async onAdd() {
    this.modalInstance?.updateConfig({ nzOkLoading: true });
    return this.addApi(this.getParams())
      .finally(() => {
        this.modalInstance?.updateConfig({ nzOkLoading: false });
      })
      .then(() => {
        this.refreshList();
      });
  }
  async onEdit(data: PoeItem) {
    this.modalInstance?.updateConfig({ nzOkLoading: true });
    return this.editApi({
      ...this.getParams(),
      id: data.id,
    })
      .finally(() => {
        this.modalInstance?.updateConfig({ nzOkLoading: false });
      })
      .then(() => {
        this.refreshList();
      });
  }
  get addApi() {
    switch (this.activeTab) {
      case PoeType.Position:
        return this.api.basic.addPosition.bind(this.api.basic);
      case PoeType.Operation:
        return this.api.basic.addOperation.bind(this.api.basic);
      case PoeType.Equipment:
        return this.api.basic.addEquipment.bind(this.api.basic);
    }
  }
  get editApi() {
    switch (this.activeTab) {
      case PoeType.Position:
        return this.api.basic.updatePosition.bind(this.api.basic);
      case PoeType.Operation:
        return this.api.basic.updateOperation.bind(this.api.basic);
      case PoeType.Equipment:
        return this.api.basic.updateEquipment.bind(this.api.basic);
    }
  }
  get deleteApi() {
    switch (this.activeTab) {
      case PoeType.Position:
        return this.api.basic.deletedPosition.bind(this.api.basic);
      case PoeType.Operation:
        return this.api.basic.deletedOperation.bind(this.api.basic);
      case PoeType.Equipment:
        return this.api.basic.deletedEquipment.bind(this.api.basic);
    }
  }
  get fetchListApi() {
    switch (this.activeTab) {
      case PoeType.Position:
        return this.basic.fetchPositions.bind(this.basic);
      case PoeType.Operation:
        return this.basic.fetchOperations.bind(this.basic);
      case PoeType.Equipment:
        return this.basic.fetchEquipments.bind(this.basic);
    }
  }
  async refreshList() {
    await this.fetchListApi();
    setTimeout(() => {
      this.resetSelected();
    }, 100);
  }

  getParams() {
    return {
      type: this.selectedType,
      category: this.selectedCategory,
      name: this.formNameValue,
      company: this.company,
    };
  }
  get allTypes() {
    return this.knowledge.types();
  }
  get positions() {
    return this.basic.positions;
  }
  get operations() {
    return this.basic.operations;
  }
  get equipments() {
    return this.basic.equipments;
  }
  get list(): Array<PoeItem> {
    switch (this.activeTab) {
      case PoeType.Position:
        return this.positions;
      case PoeType.Operation:
        return this.operations;
      case PoeType.Equipment:
        return this.equipments;
    }
  }
  get filteredList() {
    return this.list.filter(item => {
      if (this.selectedType >= 0) {
        if (item.type !== this.selectedType) {
          return false;
        }
      }
      if (this.selectedCategory >= 0) {
        if (item.category !== this.selectedCategory) {
          return false;
        }
      }
      return true;
    });
  }
  get formNameValue() {
    return this.validateForm.get('name')?.value;
  }
  get company() {
    return this.setting.userCompany;
  }
  get currentTab() {
    return this.poeTabs.find(t => t.value === this.activeTab);
  }
  get currentTabLabel() {
    return this.currentTab?.label;
  }
}
