import { Component, inject, ViewChild } from '@angular/core';
import { FormGroup, NonNullableFormBuilder, Validators } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NZ_MODAL_DATA, NzModalRef } from 'ng-zorro-antd/modal';
import { verticalInOut } from '../../../../../../../../common.animation';
import { getHazardFinalStatusColor, hazardLevelColor } from '../../../../../hazard.utils';
import { CommonNzModule } from './../../../../../../../../common.nz.module';
import { ApiService } from './../../../../../../../../services/api.service';
import { CustomDrawerComponent } from './../../../../../../../../shared/custom-drawer/custom-drawer.component';
import { HazardFormComponent } from './../../../../../hazard-tracking/hazard-form/hazard-form.component';
export interface RoundFillFormData {
  action: 'create' | 'update';
  item: Hazard.InspectionPlanHandleDto;
  setSize: (size: 'large' | 'default') => void;
  updateDetail: () => void;
}

interface HandleControlParams {
  // data: Partial<Hazard.HazardDto>, situation?: string, suggestion?: string, isNew = 0
  data: Partial<Hazard.HazardDto>;
  situation?: string;
  suggestion?: string;
  hasBeenDeleted?: boolean;
  endpointId?: number;
}

interface HazardControl {
  id: number;
  hazard: Partial<Hazard.HazardDto>;
  hazardActualId: number;
  endpointId?: number;
  situation: string;
  suggestion: string;
  /** 是否更新隐患 */
  updatedSignal: boolean;
  /** 是否删除隐患 */
  deletedSignal: boolean;
  /** 是否新增隐患 */
  newSignal: boolean;
  /** 是否更新不符合状况或者治理意见 */
  modifySignal: boolean;
}

@Component({
  selector: 'round-fill-form',
  standalone: true,
  imports: [CommonNzModule, HazardFormComponent, CustomDrawerComponent],
  templateUrl: './fill-form.component.html',
  styleUrl: './fill-form.component.less',
  animations: [verticalInOut],
})
export class RoundFillFormComponent {
  readonly nzModalData: RoundFillFormData = inject(NZ_MODAL_DATA);

  @ViewChild('hazardForm') hazardForm!: HazardFormComponent;

  hazardLevelColor = hazardLevelColor;
  get riskItemIds() {
    return this.nzModalData.item.targets;
  }
  loading = false;
  step = 0;
  hazardFormConfig: {
    visible: boolean;
    data: Partial<Hazard.HazardDto>;
    isEdit: boolean;
    index: number;
  } = {
    visible: false,
    data: {} as Hazard.HazardDto,
    isEdit: false,
    index: -1,
  };
  selectedHazardIndex = -1;

  listOfHazardControl: Array<HazardControl> = [];

  constructor(
    private fb: NonNullableFormBuilder,
    private api: ApiService,
    private message: NzMessageService,
    private modalRef: NzModalRef
  ) {}
  ngOnInit() {
    if (this.nzModalData.action === 'update') {
      this.fillForm.patchValue({
        checkAbnormal: this.nzModalData.item.checkAbnormal,
        checkWorkSituation: this.nzModalData.item.checkWorkSituation,
      });
      (this.nzModalData.item.checkOpinions || []).forEach(item => {
        this.addHazardControl({
          data: item.trouble,
          situation: item.situation,
          suggestion: item.suggestion,
          hasBeenDeleted: !!item.isDelete,
          endpointId: item.id,
        });
      });
      if (this.nzModalData.item.checkAbnormal) {
        this.onAction();
      }
    }
  }
  fillForm: FormGroup = this.fb.group({
    checkAbnormal: this.fb.control<number>(0),
    checkWorkSituation: this.fb.control<string>('', [Validators.required]),
  });
  getIndexFormControlName(name: string) {
    return /.+-(\d+)/.exec(name)?.[1];
  }
  addHazardControl(handleControl: HandleControlParams) {
    const { data, situation, suggestion, hasBeenDeleted = false, endpointId = 0 } = handleControl;
    const id =
      this.listOfHazardControl.length > 0 ? this.listOfHazardControl[this.listOfHazardControl.length - 1].id + 1 : 0;
    const control: HazardControl = {
      id,
      hazard: {
        ...data,
        id: endpointId ? data.id : 0,
      },
      hazardActualId: endpointId,
      endpointId,
      situation: `situation-${id}`,
      suggestion: `suggestion-${id}`,
      updatedSignal: false,
      deletedSignal: hasBeenDeleted,
      newSignal: !endpointId,
      modifySignal: false,
    };
    const index = this.listOfHazardControl.push(control);
    this.fillForm.addControl(
      this.listOfHazardControl[index - 1].situation,
      this.fb.control(situation || '', {
        validators: [Validators.required],
      })
    );
    this.fillForm.addControl(
      this.listOfHazardControl[index - 1].suggestion,
      this.fb.control(suggestion || '', {
        validators: [Validators.required],
      })
    );

    this.selectedHazardIndex = id;
  }
  selectHazard(control: HazardControl) {
    this.selectedHazardIndex = control.id;
  }
  handleEditHazard(control: HazardControl) {
    // this.selectedHazardIndex = control.id;
    this.hazardFormConfig = {
      visible: true,
      data: control.hazard,
      isEdit: true,
      index: control.id,
    };
  }
  handleDeleteHazard(control: HazardControl) {
    if (this.selectedHazardIndex === control.id) {
      this.selectedHazardIndex = -1;
    }
    this.fillForm.removeControl(control.situation);
    this.fillForm.removeControl(control.suggestion);
    if (control.newSignal) {
      this.listOfHazardControl = this.listOfHazardControl.filter(item => item.id !== control.id);
    } else {
      control.deletedSignal = true;
      control.updatedSignal = false;
      // 不直接移除, 仅是标记为删除
      // this.listOfHazardControl = this.listOfHazardControl.filter(item => item.id !== control.id);
    }
  }
  onAction() {
    if (this.isNormal) {
      this.submitNormal();
    } else {
      this.onNext();
    }
  }
  afterGettingHazard(value: Partial<Hazard.HazardDto>) {
    if (this.hazardFormConfig.index === -1) {
      this.addHazardControl({ data: value, endpointId: 0 });
    } else {
      this.listOfHazardControl[this.hazardFormConfig.index].hazard = {
        ...this.listOfHazardControl[this.hazardFormConfig.index].hazard,
        ...value,
      };
      // 编辑操作时，需要把隐患标记为已更新
      if (this.nzModalData.action === 'update') {
        this.listOfHazardControl[this.hazardFormConfig.index].updatedSignal = true;
      }
    }
  }
  closeFormDrawer() {
    this.hazardForm.reset();
    this.hazardFormConfig.visible = false;
  }
  handleAddHazard() {
    this.hazardFormConfig = {
      visible: true,
      data: {
        // position like dto
        position: this.nzModalData.item.position,
        positionNext: this.nzModalData.item.positionNext,
        positionOther: this.nzModalData.item.positionOther,
        positionType: this.nzModalData.item.positionType,
        line: this.nzModalData.item.line,
      } as Hazard.HazardDto,
      isEdit: false,
      index: -1,
    };
  }
  validate(step = 1) {
    return new Promise<Hazard.ReportTaskParams>((resolve, reject) => {
      if (!this.fillForm.valid) {
        Object.entries(this.fillForm.controls).forEach(([name, control]) => {
          if (control.invalid) {
            control.markAsDirty();
            control.updateValueAndValidity({ onlySelf: true });
            const index = this.getIndexFormControlName(name);
            if (index) {
              this.selectedHazardIndex = this.listOfHazardControl[Number(index)].id;
            }
          }
        });
        return reject();
      }
      if (step === 1) {
        const { checkAbnormal } = this.fillForm.value;
        if (checkAbnormal && this.listOfHazardControl.length === 0) {
          this.message.error('请添加隐患');
          return reject();
        }
      }
      return resolve(this.nzModalData.action === 'create' ? this.getCreateParams() : this.getUpdateParams());
    });
  }
  getCreateParams(): Hazard.ReportTaskParams {
    const { checkAbnormal, checkWorkSituation } = this.fillForm.value;
    return {
      id: this.nzModalData.item.id,
      checkAbnormal: checkAbnormal ? 1 : 0,
      checkWorkSituation: checkWorkSituation,
      checkOpinions: !checkAbnormal
        ? []
        : this.listOfHazardControl.map(item => ({
            trouble: item.hazard,
            situation: this.fillForm.get(item.situation)?.value,
            suggestion: this.fillForm.get(item.suggestion)?.value,
            troubleshootPlanHandleId: this.nzModalData.item.id, // taskId
            troubleIsUpdate: 0,
            isUpdate: 0,
            isDelete: 0,
          })),
    };
  }
  getUpdateParams(): Hazard.ReportTaskParams {
    const { checkAbnormal, checkWorkSituation } = this.fillForm.value;
    return {
      id: this.nzModalData.item.id,
      checkAbnormal: checkAbnormal ? 1 : 0,
      checkWorkSituation: checkWorkSituation,
      checkOpinions: !checkAbnormal
        ? this.listOfHazardControl.map(item => ({
            trouble: item.hazard,
            situation: this.fillForm.get(item.situation)?.value,
            suggestion: this.fillForm.get(item.suggestion)?.value,
            troubleshootPlanHandleId: this.nzModalData.item.id, // taskId
            id: item.endpointId,
            troubleIsUpdate: 0, // 编辑操作时，需要把隐患标记为已更新
            isUpdate: 0,
            isDelete: 1,
          }))
        : this.listOfHazardControl.map(item => ({
            trouble: item.hazard,
            situation: this.fillForm.get(item.situation)?.value,
            suggestion: this.fillForm.get(item.suggestion)?.value,
            troubleshootPlanHandleId: this.nzModalData.item.id, // taskId
            troubleIsUpdate: item.updatedSignal ? 1 : 0, // 编辑操作时，需要把隐患标记为已更新
            id: item.endpointId,
            isUpdate: item.modifySignal ? 1 : 0,
            isDelete: item.deletedSignal ? 1 : 0,
          })),
    };
  }
  onBack() {
    this.step = 0;
    this.nzModalData.setSize('default');
  }
  async onNext() {
    if (this.step === 0) {
      await this.validate(this.step);
      this.step = 1;
      this.nzModalData.setSize('large');
    } else {
      this.submit();
    }
  }
  async submitNormal() {
    for (const item of this.listOfHazardControl) {
      this.fillForm.removeControl(item.situation);
      this.fillForm.removeControl(item.suggestion);
    }
    this.listOfHazardControl = [];
    return this.submit();
  }

  async submit() {
    if (this.loading) return Promise.reject();
    this.loading = true;
    const result = await this.validate(this.step).catch(() => {
      this.loading = false;
      return Promise.reject();
    });
    if (!result) {
      return Promise.reject();
    }
    await this.api.hazard
      .reportTask(result)
      .finally(() => {
        this.loading = false;
      })
      .catch(err => {
        this.message.error(err.message);
        throw err;
      });
    this.message.success('填报成功');
    this.nzModalData.updateDetail();
    this.modalRef.destroy();
  }
  get isNormal() {
    return !this.fillForm.get('checkAbnormal')?.value;
  }
  get actionText() {
    if (this.step === 0) {
      return this.isNormal ? '提交' : '下一步，隐患填写';
    }
    return '提交';
  }
  handleModifyHazard(control: HazardControl) {
    if (!control.newSignal) {
      this.listOfHazardControl[control.id].modifySignal = true;
    }
  }
  getStateColor(status: string) {
    return getHazardFinalStatusColor(status);
  }
  get listOfHazardControlActual() {
    return this.listOfHazardControl.filter(item => !item.deletedSignal);
  }
}
