import { Component, inject } from '@angular/core';
import { NonNullableFormBuilder, Validators } from '@angular/forms';
import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal';
import { CommonNzModule } from './../../common.nz.module';
import { BasicDataService } from './../../services/basic.service';

export interface PositionLike {
  /** 发生地点类型 */
  positionType?: string;

  /** 线路 */
  line?: number;

  /** 站点 */
  position?: number;

  /** 站点2 */
  positionNext?: number;

  /** 站点其他 */
  positionOther?: string;
}

export interface ComposePositionPickModalData {
  positionType?: string;
  /** 线路 */
  line?: number;

  /** 站点 */
  position?: number;

  /** 站点2 */
  positionNext?: number;

  /** 站点其他 */
  positionOther?: string;
}

export const getPositionLikeDtoText = (
  d: PositionLike,
  lines: BasicData.Predefine[],
  positions: BasicData.Position[],
  positionCategories: BasicData.PositionCategory[]
): string => {
  const { position, positionNext, positionOther, positionType, line } = d;
  if (positionType === 'other') {
    return positionOther || '';
  }
  if (positionType === 'line') {
    const l = lines.find(l => l.id === line);
    const p1 = positions.find(p => p.id === position);
    const p2 = positions.find(p => p.id === positionNext);
    return `${l?.value} ( ${p1?.name} - ${p2?.name} )`;
  }
  if (positionType === 'station') {
    const p = positions.find(p => p.id === position);
    const l = lines.find(l => l.id === line);
    const pc = positionCategories.find(pc => pc.id === p?.category);
    if (pc?.name === '车站') {
      return `${l?.value} - ${p?.name}`;
    }
    return p?.name || '';
  }
  return '';
};

export const isPositionLikeValid = (d: PositionLike): boolean => {
  if (!d.positionType) {
    return false;
  }
  switch (d.positionType) {
    case 'other':
      return !!d.positionOther;
    case 'line':
      return !!d.line && !!d.position && !!d.positionNext;
    case 'station':
      return !!d.position;
    default:
      return false;
  }
};

@Component({
  selector: 'compose-position-pick-modal',
  standalone: true,
  imports: [CommonNzModule],
  templateUrl: './compose-position-pick-modal.component.html',
  styleUrl: './compose-position-pick-modal.component.less',
})
export class ComposePositionPickModalComponent {
  readonly nzModalData: ComposePositionPickModalData = inject(NZ_MODAL_DATA);
  form = this.fb.group({
    positionCategory: this.fb.control<number | undefined>(undefined),
    line: this.fb.control<number | undefined>(undefined),
    position: 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),
  });
  scenes: Option<string>[] = [
    { label: '站点', value: 'station' },
    { label: '路线区间', value: 'line' },
    { label: '其他场景', value: 'other' },
  ];
  lineOptions: Option<number>[] = [];
  stationOptions: Option<number>[] = [];
  positionCategoryOptions: Option<number>[] = [];
  constructor(
    private fb: NonNullableFormBuilder,
    private basic: BasicDataService
  ) {}

  ngOnInit() {
    this.init();
  }
  init() {
    this.positionCategoryOptions = this.basic.positionCategories.map(item => ({
      label: item.name,
      value: item.id,
    }));
    this.resetSceneValidators(this.nzModalData.positionType || 'station');
    this.setPositionCategory();
    this.nzModalData.line && this.onLineChange(this.nzModalData.line);
    this.patchValues();

    this.initLineOptions();
  }
  setPositionCategory() {
    const { position } = this.nzModalData;
    if (position) {
      const positionCategory = this.basic.positions.find(item => item.id === position);
      if (positionCategory) {
        this.positionCategory?.setValue(positionCategory.category);
        this.onPositionCategoryChange(positionCategory.category);
      }
    }
  }
  initLineOptions() {
    this.lineOptions = this.basic.lines.map(item => ({ label: item.value, value: item.id }));
  }
  patchValues() {
    const { position, positionNext, positionOther, positionType, line } = this.nzModalData;
    this.form.patchValue({
      position,
      positionNext,
      positionOther,
      positionType: positionType || 'station',
      line,
    });
  }
  onLineChange(value: number) {
    this.stationOptions = this.basic.positions
      .filter(item => item.stationLines.includes(value))
      .map(item => ({ label: item.name, value: item.id }));
    this.position?.setValue(undefined);
    this.positionNext?.setValue(undefined);
  }
  onSceneChange(value: string) {
    this.form.get('positionType')?.setValue(value);
    this.resetSceneValidators(value);
    this.resetScene();
  }
  onPositionCategoryChange(value: number) {
    this.position?.reset();
    this.positionNext?.reset();
    this.stationOptions = this.basic.positions
      .filter(item => item.category === value)
      .map(item => ({
        label: item.name,
        value: item.id,
      }));
  }
  resetSceneValidators(value: string) {
    switch (value) {
      case 'station':
        this.line?.clearValidators();
        this.position?.setValidators([Validators.required]);
        this.positionCategory?.setValidators([Validators.required]);
        this.positionNext?.clearValidators();
        this.positionOther?.clearValidators();
        break;
      case 'line':
        this.line?.setValidators([Validators.required]);
        this.position?.setValidators([Validators.required]);
        this.positionCategory?.clearValidators();
        this.positionNext?.setValidators([Validators.required]);
        this.positionOther?.clearValidators();
        break;
      case 'other':
        this.line?.clearValidators();
        this.position?.clearValidators();
        this.positionCategory?.clearValidators();
        this.positionNext?.clearValidators();
        this.positionOther?.setValidators([Validators.required]);
        break;
    }
  }
  resetScene() {
    this.line?.reset();
    this.position?.reset();
    this.positionNext?.reset();
    this.positionOther?.reset();
    this.positionCategory?.reset();
  }

  validate() {
    return new Promise<ComposePositionPickModalData>((resolve, reject) => {
      if (!this.form.valid) {
        Object.values(this.form.controls).forEach(control => {
          if (control.invalid) {
            control.markAsDirty();
            control.updateValueAndValidity({ onlySelf: true });
          }
        });
        return reject();
      }
      return resolve({
        ...this.form.value,
      });
    });
  }
  get line() {
    return this.form.get('line');
  }
  get position() {
    return this.form.get('position');
  }
  get positionNext() {
    return this.form.get('positionNext');
  }
  get positionOther() {
    return this.form.get('positionOther');
  }
  get positionCategory() {
    return this.form.get('positionCategory');
  }

  get positionTypeValue() {
    return this.form.get('positionType')?.value;
  }
  get positionCategoryValue() {
    return this.positionCategory?.value;
  }
  get isStation() {
    if (this.positionTypeValue === 'station') {
      if (this.positionCategoryValue) {
        const positionCategory = this.basic.positionCategories.find(item => item.id === this.positionCategoryValue);
        if (positionCategory && positionCategory.name === '车站') {
          return true;
        }
      }
    }
    return false;
  }
  get showLineControl() {
    if (this.positionTypeValue === 'line') {
      return true;
    }
    if (this.isStation) {
      return true;
    }
    return false;
  }
  get positionPlaceHolder() {
    if (this.isStation) {
      return '请选择场所';
    }
    if (this.positionTypeValue === 'station') {
      return '请选择站点';
    }
    return '请选择起始站点';
  }
}
