import { RejectModel } from '../components/cards/services/RejectDialog.vue';
import { MetaClassSchemaRaw } from '@devsun/eva-models/dist/models/Schema';
import intersectionWith from 'lodash/intersectionWith';
import cloneDeep from 'lodash/cloneDeep';
import isEqual from 'lodash/isEqual';
import get from 'lodash/get';
import { FormApi } from '@openapi/registry-service';

const formApi = new FormApi();

export async function updateRejects(cardModel: any) {
  const oldForms = cloneDeep(
    cardModel?.documents?.flatMap((d: any) => d.form || []) || []
  );
  cardModel?.rejects?.forEach((reject: any) =>
    updateDocumentViews(cardModel, reject)
  );
  const modifiedForms = cardModel?.documents
    ?.flatMap((d: any) => d.form || [])
    .filter((form: any) => !oldForms.find((f: any) => isEqual(form, f)));

  if (modifiedForms?.length) {
    await formApi.updateForm(modifiedForms);
  }
}

function updateDocumentViews(card: any, model: RejectModel): void {
  const docsFromStagesObj =
    card?.stages
      ?.flatMap((s: any) => s.documents?.reject || [])
      .filter(
        (d: any) =>
          intersectionWith(
            (d.goal || []).map((g: number) => '' + g),
            model.goal as [string]
          ).length !== 0
      ) || [];

  const docsFromStagesStr =
    card?.stages
      ?.flatMap((s: any) => s.documents?.reject || [])
      .filter((d: any) => typeof d === 'string') || [];

  if (model.type) {
    card?.documents
      ?.filter(
        (item: { source: string; resultType: string }) =>
          item.source === 'result' &&
          ((model.type === 'service' && item.resultType === 'rejectService') ||
            (model.type === 'document' && item.resultType === 'rejectDoc'))
      )
      .forEach((document: any) => {
        const forms = document.form || [];
        forms.forEach((form: MetaClassSchemaRaw) => {
          const needToAdd =
            docsFromStagesObj.find((d: any) => d.form === form.name) ||
            docsFromStagesStr.includes(form.name);

          if (needToAdd) {
            addRejectToForm(form, model);
          } else {
            removeRejectFromForm(form, model);
          }
        });
      });
  }
}

function removeRejectFromForm(form: MetaClassSchemaRaw, reject: RejectModel) {
  if (Array.isArray(get(form, 'attrList'))) {
    const existedAttr = form.attrList.find((item) => item.name === reject.code);
    if (existedAttr) {
      form.attrList = form.attrList.filter((attr) => attr.name !== reject.code);
      const rejectGroup = form.groupList?.find(
        (item) => item.name === 'rejects'
      );
      if (rejectGroup) {
        if (!rejectGroup.hasOwnProperty('attrList')) {
          rejectGroup.attrList = [];
        }
        rejectGroup.attrList = rejectGroup.attrList.filter(
          (attr) => attr !== reject.code
        );
      }
    }
  }
}

function addRejectToForm(form: MetaClassSchemaRaw, model: RejectModel) {
  if (!form.hasOwnProperty('attrList')) {
    form.attrList = [];
  }
  if (Array.isArray(get(form, 'attrList'))) {
    const existedAttr = form.attrList.find((item) => item.name === model.code);
    if (existedAttr) {
      existedAttr.label = model.name || '';
    } else {
      const maxNum = form.attrList.reduce(
        (accumulator, currentValue) =>
          Math.max(accumulator, currentValue.num || 0),
        0
      );
      const attr = {
        name: model.code || '',
        num: maxNum + 10,
        label: model.name || '',
        type: 'boolean',
        props: {
          type: 'bool',
          rightLabel: true,
        },
        view: 'boolean',
        cols: 12,
        previewHidden: false,
        editHidden: false,
        editReadOnly: false,
        createHidden: false,
        createReadOnly: false,
        editRequired: false,
        createRequired: false,
      };
      // @ts-ignore
      form.attrList.push(attr);
      const rejectGroup = form.groupList?.find(
        (item) => item.name === 'rejects'
      );
      if (rejectGroup) {
        if (!rejectGroup.hasOwnProperty('attrList')) {
          rejectGroup.attrList = [];
        }
        rejectGroup.attrList.push(attr.name);
      }
    }
  }
}
