import { Component, EventEmitter, Input, Output, SimpleChanges, ViewContainerRef } from '@angular/core';
import { AbstractControl, NonNullableFormBuilder, Validators } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal';
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 { UserRole } from '../../../user/user.const';
import {
  cycleOptions,
  hazardPlanTypeOptions,
  PlanCycle,
  PlanLevel,
  planLevelOptions,
  PlanType,
} from '../inspection-plan.utils';
import { CommonNzModule } from './../../../../../common.nz.module';
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';

export interface PlanFormComponentProps {
  data?: Hazard.InspectionPlan;
  visible: boolean;
  isEdit: boolean;
}

@Component({
  selector: 'plan-form',
  standalone: true,
  imports: [CommonNzModule, RiskItemPickerComponent, RiskItemsVisualClassifyComponent],
  templateUrl: './plan-form.component.html',
  styleUrl: './plan-form.component.less',
  host: {
    class: 'custom-scroll-bar',
  },
})
export class PlanFormComponent {
  @Input() data?: Hazard.InspectionPlan;
  @Input() isEdit = false;
  @Output() onClose = new EventEmitter<void>();
  @Output() refreshList = new EventEmitter<void>();
  @Output() fetchDetail = new EventEmitter<number>();

  validateForm = this.fb.group({
    title: this.fb.control<string>('', [Validators.required, Validators.maxLength(100)]),
    level: this.fb.control<string | undefined>(undefined, [Validators.required]),
    type: this.fb.control<string | undefined>(undefined, [Validators.required]),
    cycle: this.fb.control<string | undefined>(undefined, [Validators.required]),
    frequency: this.fb.control<number | undefined>(undefined, [this.frequencyValidator.bind(this)]),
    frequencyTimes: this.fb.control<number | undefined>(undefined, [Validators.required]),
    time: this.fb.control<string[]>([], [this.timeValidator.bind(this)]),
    targets: this.fb.control<number[]>([], [Validators.required]),
    content: this.fb.control<string>('', [Validators.required, Validators.maxLength(2000)]),
    // isUnited: this.fb.control<boolean>(false),
  });

  types: Option<string>[] = [];
  levels: Option<string>[] = [];
  cycleOptions = cycleOptions;
  frequencyOptions: Option<number>[] = [];

  riskItemPickerVisible = false;

  constructor(
    private viewContainerRef: ViewContainerRef,
    private modal: NzModalService,
    private fb: NonNullableFormBuilder,
    private message: NzMessageService,
    private setting: SettingService,
    private api: ApiService,
    private knowledge: KnowledgeService,
    private basic: BasicDataService
  ) {
    // setting.getUsersOfCurrentCompany();
    this.setLevelOptions();
  }
  setLevelOptions() {
    const roles = this.setting.user?.roles || [];
    if (roles.includes(UserRole.ADMIN) || roles.includes(UserRole.MANAGER)) {
      this.levels = planLevelOptions.slice();
      return;
    }
    if (roles.includes(UserRole.CHIEF)) {
      this.levels = planLevelOptions.slice(0, 1);
      return;
    }
  }
  ngOnChanges(changes: SimpleChanges) {
    if (changes['data']) {
      this.validateForm.reset();
      if (this.data) {
        this.patchValues();
      }
    }
  }
  patchValues() {
    if (!this.data) return;
    this.validateForm.patchValue({
      title: this.data.title,
      level: this.data.level,
      type: this.data.type,
      cycle: this.data.cycle,
      frequency: this.data.frequency,
      frequencyTimes: this.data.frequencyTimes,
      time: [this.data.startDate, this.data.endDate],
      targets: this.data.targets,
      content: this.data.content,
    });
  }
  disabledDate = (current: Date): boolean => {
    // if (current < new Date()) return true;
    return false;
  };
  setTypeOptions(level: string) {
    switch (level) {
      case PlanLevel.COMPANY:
        this.types = hazardPlanTypeOptions.filter(t => t.value !== PlanType.DAILY);
        break;
      case PlanLevel.DEPARTMENT:
        this.types = hazardPlanTypeOptions.slice();
        break;
      // case PlanLevel.GROUP:
      //   this.types = hazardPlanTypeOptions.filter(t => t.value === PlanType.DAILY);
      //   break;
      default:
        this.types = [];
        break;
    }
  }
  onCancel() {
    this.onClose.emit();
  }
  onLevelChange(v: string) {
    this.typeControl.setValue(undefined);
    this.cycleControl.setValue(undefined);
    this.frequencyControl.setValue(undefined);
    this.setTypeOptions(v);
  }
  onCycleChange(v: string) {
    this.frequencyControl.setValue(v === PlanCycle.SINGLE ? undefined : 1);
    this.rateControl.setValue(1);
  }
  handleSelectTargets(ev: Event) {
    ev.preventDefault();
    this.riskItemPickerVisible = true;
  }
  closeRiskItemPicker() {
    this.riskItemPickerVisible = false;
  }
  frequencyValidator(control: AbstractControl) {
    if (!this.validateForm) {
      return null;
    }
    const cycle = this.validateForm.get('cycle')?.value;
    if (cycle === PlanCycle.SINGLE) {
      return null;
    }
    if (!control.value) {
      return { frequency: true, error: true, required: true };
    }
    return null;
  }
  timeValidator(control: AbstractControl) {
    if (!control.value || control.value.length !== 2) {
      return { error: true, required: true };
    }
    const [start, end] = control.value;
    if (end - start > 365 * 24 * 60 * 60 * 1000) {
      return { error: true, message: '开始和结束时间不能大于一年' };
    }
    return null;
  }
  async submitForm() {
    if (!this.validateForm.valid) {
      Object.values(this.validateForm.controls).forEach(control => {
        if (control.invalid) {
          control.markAsDirty();
          control.updateValueAndValidity({ onlySelf: true });
        }
      });
    } else {
      if (this.isEdit) {
        this.onUpdate();
      } else {
        this.onSubmit();
      }
    }
  }
  getValues(): Partial<Hazard.InspectionPlan> {
    const { title, targets, content, time, frequency, frequencyTimes, cycle, type, level } = this.validateForm.value;
    const result: Partial<Hazard.InspectionPlan> = {
      title,
      targets: targets || [],
      content,
      startDate: time?.[0],
      endDate: time?.[1],
      frequency: frequency || undefined,
      frequencyTimes: frequencyTimes || 1,
      cycle: cycle || '',
      type: type || '',
      level: level || '',
    };

    return result;
  }
  async onSubmit() {
    await this.api.hazard.createPlan(this.getValues()).then(res => {
      if (!res.code) {
        this.message.success('创建计划成功');
        this.onClose.emit();
        this.refreshList.emit();
      } else {
        this.message.error('创建计划失败:' + res.message);
      }
    });
  }

  async onUpdate() {
    await this.api.hazard
      .updatePlan({
        ...this.getValues(),
        id: this.data?.id,
      })
      .then(res => {
        if (!res.code) {
          this.message.success('更新计划成功');
          this.onClose.emit();
          this.refreshList.emit();
          this.fetchDetail.emit(this.data?.id);
        } else {
          this.message.error('更新计划失败:' + res.message);
        }
      });
  }
  get typeControl() {
    return this.validateForm.get('type')!;
  }
  get levelControl() {
    return this.validateForm.get('level')!;
  }
  get cycleControl() {
    return this.validateForm.get('cycle')!;
  }
  get frequencyControl() {
    return this.validateForm.get('frequency')!;
  }
  get rateControl() {
    return this.validateForm.get('frequencyTimes')!;
  }
  get riskItemValue() {
    return this.validateForm.get('targets')?.value || [];
  }
  get riskItemList(): Knowledge.RiskItem[] {
    return this.riskItemValue
      .map(id => this.knowledge.riskItems().find(item => item.id === id))
      .filter(Boolean) as Knowledge.RiskItem[];
  }
  get cycleShortLabel() {
    const cycle = this.cycleControl.value;
    if (!cycle) {
      return '';
    }
    const firstWord = (cycleOptions.find(c => c.value === cycle)?.label || '').split('')[0];
    return firstWord;
  }

  get isSinglePlan() {
    return this.cycleControl.value === PlanCycle.SINGLE;
  }
}
