import { Component, Input, ViewContainerRef } from '@angular/core';
import { NonNullableFormBuilder, Validators } from '@angular/forms';
import { NzModalService } from 'ng-zorro-antd/modal';
import { NzSelectItemInterface, NzSelectOptionInterface } from 'ng-zorro-antd/select';
import {
  ComposePositionPickModalData,
  getPositionLikeDtoText,
  PositionLike,
} from '../../../../../../../../shared/compose-position-pick-modal/compose-position-pick-modal.component';
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 { ComposePositionPickModalComponent } from './../../../../../../../../shared/compose-position-pick-modal/compose-position-pick-modal.component';
import { RiskItemPickerComponent } from './../../../../../../../../shared/risk-item-picker/risk-item-picker.component';
import { RiskItemsVisualClassifyComponent } from './../../../../../../../../shared/risk-item-picker/risk-items-visual-classify/risk-items-visual-classify.component';

@Component({
  selector: 'task-form',
  standalone: true,
  imports: [CommonNzModule, RiskItemPickerComponent, RiskItemsVisualClassifyComponent],
  templateUrl: './task-form.component.html',
  styleUrl: './task-form.component.less',
})
export class TaskFormComponent {
  @Input() index!: number;
  @Input() plan!: Hazard.InspectionPlan;
  @Input() data?: Hazard.InspectionPlanHandleDto;
  @Input() times: number = -1;
  @Input() departmentId?: number;
  @Input() readonly = false;
  @Input() firstRow = false;

  riskItemPickerVisible = false;

  constructor(
    private viewContainerRef: ViewContainerRef,
    private fb: NonNullableFormBuilder,
    private setting: SettingService,
    private basic: BasicDataService,
    private api: ApiService,
    private knowledge: KnowledgeService,
    private modal: NzModalService
  ) {}
  positionText = '';
  taskForm = this.fb.group({
    position: this.fb.control<number | undefined>(undefined),
    line: this.fb.control<number | undefined>(undefined),
    positionNext: this.fb.control<number | undefined>(undefined),
    positionOther: this.fb.control<string | undefined>(undefined),
    positionType: this.fb.control<string | undefined>(undefined),
    leaderUserId: this.fb.control<string | undefined>(undefined, [Validators.required]),
    times: this.fb.control<number | undefined>(undefined, [Validators.required]),
    troubleshootPlan: this.fb.control<number | undefined>(undefined, [Validators.required]),
    targets: this.fb.control<number[] | undefined>(undefined, [Validators.required]),
    teams: this.fb.control<number[]>([], []),
    peopleNumber: this.fb.control<number | undefined>(undefined, [Validators.required]),
  });
  focus() {
    const dom = this.viewContainerRef.element.nativeElement as HTMLDivElement;
    dom.scrollIntoView({ behavior: 'smooth', block: 'center' });
    dom.focus();
  }
  responsibleOptions: NzSelectOptionInterface[] = [];
  teamOptions: NzSelectOptionInterface[] = [];
  ngOnInit(): void {
    this.responsibleOptions = this.getResponsibleOptions();
    this.teamOptions = this.getTeamOptions();
    this.patchValues();
    this.setPositionText();
  }
  setPositionText() {
    this.positionText = getPositionLikeDtoText(
      this.taskForm.value as PositionLike,
      this.basic.lines,
      this.basic.positions,
      this.basic.positionCategories
    );
  }
  revert() {
    this.taskForm.reset();
    this.patchValues();
  }
  async add() {
    return new Promise<Hazard.InspectionPlanHandleDto>(async (resolve, reject) => {
      if (!this.taskForm.valid) {
        Object.values(this.taskForm.controls).forEach(control => {
          if (control.invalid) {
            control.markAsDirty();
            control.updateValueAndValidity({ onlySelf: true });
          }
        });
        return reject();
      }
      await this.api.hazard
        .createPlanHandle({
          ...this.taskForm.value,
        })
        .then(res => {
          resolve(res);
        })
        .catch(err => {
          return reject(err);
        });
    });
  }
  async save() {
    return new Promise<Hazard.InspectionPlanHandleDto>(async (resolve, reject) => {
      this.taskForm.markAllAsTouched();
      if (this.taskForm.invalid) {
        return reject();
      }
      await this.api.hazard
        .updatePlanHandle({
          ...this.taskForm.value,
          id: this.data?.id,
        })
        .then(res => {
          resolve(res);
        })
        .catch(err => {
          return reject(err);
        });
    });
  }
  patchValues() {
    this.taskForm.patchValue({
      targets: this.data?.targets,
      position: this.data?.position,
      positionNext: this.data?.positionNext,
      positionOther: this.data?.positionOther,
      positionType: this.data?.positionType,
      leaderUserId: this.data?.leaderUserId,
      times: this.data?.times ?? this.times,
      troubleshootPlan: this.data?.troubleshootPlan,
      teams: this.data?.teams,
      peopleNumber: this.data?.peopleNumber,
      line: this.data?.line,
    });
  }
  closeRiskItemPicker() {
    this.riskItemPickerVisible = false;
  }

  handleSelectPoints(ev: Event) {
    ev.preventDefault();
    this.riskItemPickerVisible = true;
  }

  relatedFilter = (input?: string, option?: NzSelectItemInterface) => {
    if (!input) return true;
    return (option?.nzLabel as string).includes(input);
  };
  get riskItemList(): Knowledge.RiskItem[] {
    return (this.taskForm.get('targets')?.value || [])
      .map(id => this.knowledge.riskItems().find(item => item.id === id))
      .filter(Boolean) as Knowledge.RiskItem[];
  }
  get riskItemsSelectedByPlan(): Knowledge.RiskItem[] {
    return this.plan.targets
      .map(id => this.knowledge.riskItems().find(item => item.id === id))
      .filter(Boolean) as Knowledge.RiskItem[];
  }
  getResponsibleOptions(): NzSelectOptionInterface[] {
    if (!this.departmentId) return [];
    return this.setting.usersOfCurrentCompany
      .filter(item => {
        if (item.department === this.departmentId) return true;
        return false;
      })
      .map(item => ({
        label: item.name,
        value: item.id,
      }));
  }
  getTeamOptions(): NzSelectOptionInterface[] {
    if (!this.departmentId) return [];
    return this.basic.teams
      .filter(item => {
        if (item.department === this.departmentId) return true;
        return false;
      })
      .map(item => ({
        label: item.name,
        value: item.id,
      }));
  }
  createPositionModal(data?: ComposePositionPickModalData) {
    this.modal.create<ComposePositionPickModalComponent, ComposePositionPickModalData>({
      nzTitle: '选择地点',
      nzClassName: 'precaution-modal',
      nzContent: ComposePositionPickModalComponent,
      nzMaskClosable: false,
      nzData: {
        position: data?.position,
        positionNext: data?.positionNext,
        positionOther: data?.positionOther,
        positionType: data?.positionType,
        line: data?.line,
      },
      nzOnOk: async instance => {
        const data = await instance.validate();
        this.taskForm.patchValue({
          position: data.position,
          positionNext: data.positionNext,
          positionOther: data.positionOther,
          positionType: data.positionType,
          line: data.line,
        });
        this.setPositionText();
      },
    });
  }
  editPosition() {
    if (this.readonly) return;
    this.createPositionModal(this.taskForm.value);
  }
}
