<template>
  <div class="bg-[var(--text-n10)] p-[16px]">
    <n-spin :show="updateStageLoading">
      <WorkflowStep
        v-model:status="currentStage"
        :readonly="props.readonly"
        :operation-permission="props.operationPermission"
        :stageConfig="props.stageConfig"
        :workflow-list="workflowList"
        :is-limit-back="props.isLimitBack"
        :back-stage-permission="props.backStagePermission"
        :failure-reason="getFailureReason"
        :is-no-resign-flow="props.isNoResignFlow"
        @change="handleUpdateStatus"
      >
        <template v-if="!props.readonly" #action>
          <div v-permission="props.operationPermission" class="flex items-center">
            <n-button
              v-if="props.showErrorBtn"
              type="error"
              ghost
              class="n-btn-outline-error"
              @click="handleUpdateStatus(failureStage)"
            >
              {{ t('common.followFailed') }}
            </n-button>
          </div>
        </template>
      </WorkflowStep>

      <CrmModal
        v-model:show="updateStatusModal"
        :title="t('common.complete')"
        :ok-loading="updateStageLoading"
        size="small"
        @confirm="handleConfirm"
        @cancel="handleCancel"
      >
        <n-form ref="formRef" :model="form" :rules="rules" label-placement="left" require-mark-placement="left">
          <n-form-item
            require-mark-placement="left"
            label-placement="left"
            path="failureReason"
            :label="t('opportunity.failureReason')"
            :rule="[{ required: true, message: t('common.notNull', { value: t('opportunity.failureReason') }) }]"
          >
            <n-select
              v-model:value="form.failureReason"
              :options="reasonList"
              :placeholder="t('common.pleaseSelect')"
            />
          </n-form-item>
        </n-form>
      </CrmModal>
    </n-spin>
  </div>
  <CrmStatusFlowModal
    v-if="props.formKey"
    v-model:show="flowModalShow"
    :from="{ id: currentStageConfig?.id, name: currentStageConfig?.name }"
    :to="{ id: targetStageConfig?.id, name: targetStageConfig?.name }"
    :form-key="props.formKey"
    :circulationFieldValues="circulationFieldValues"
    :source-id="props.sourceId"
    @success="handleFlowSuccess"
  />
</template>

<script lang="ts" setup>
  import { FormInst, FormRules, NButton, NForm, NFormItem, NSelect, NSpin, SelectOption, useMessage } from 'naive-ui';

  import type { FormDesignKeyEnum } from '@lib/shared/enums/formDesignEnum.js';
  import { ReasonTypeEnum } from '@lib/shared/enums/moduleEnum';
  import { useI18n } from '@lib/shared/hooks/useI18n';
  import type {
    CirculationFieldValueItem,
    OpportunityStageConfig,
    StageConfigItem,
    UpdateStageParams,
  } from '@lib/shared/models/opportunity';

  import CrmModal from '@/components/pure/crm-modal/index.vue';
  import type { Option } from '@/components/business/crm-select-user-drawer/type';
  import CrmStatusFlowModal from '@/components/business/crm-status-flow-modal/index.vue';
  import WorkflowStep from './workflowStep.vue';

  import { getReasonConfig } from '@/api/modules';

  const { t } = useI18n();
  const Message = useMessage();

  const props = defineProps<{
    formKey?: FormDesignKeyEnum;
    stageConfig?: OpportunityStageConfig; // 阶段配置
    sourceId: string; // 资源id
    showErrorBtn?: boolean;
    showConfirmStatus?: boolean; // 是否二次确认更新成功 | 成败
    updateApi?: (params: UpdateStageParams) => Promise<any>;
    operationPermission?: string[];
    readonly?: boolean;
    isLimitBack?: boolean; // 是否限制状态往返
    backStagePermission?: string[];
    failureReason?: string;
    afootRollBack?: boolean; // 是否允许从跟进中回退
    endRollBack?: boolean; // 是否允许从成功或失败回退
    isNoResignFlow?: boolean; // 是否是不区分成功失败、无反签逻辑的流程
    beforeChangeStage?: (stage: string) => boolean | Promise<boolean>; // 切换阶段前的拦截，返回 false 阻止默认更新
  }>();

  const emit = defineEmits<{
    (e: 'loadDetail'): void;
  }>();

  const currentStage = defineModel<string>('stage', {
    required: true,
  });

  const reasonList = ref<Option[]>([]);
  const updateStatusModal = ref<boolean>(false);

  const rules: FormRules = {
    status: [{ required: true, message: t('common.pleaseSelect') }],
  };
  const failureStage = computed(
    () => props.stageConfig?.stageConfigList.find((e) => e.type === 'END' && e.rate === '0')?.id || ''
  );

  const form = ref<UpdateStageParams>({
    id: '',
    stage: failureStage.value,
    failureReason: null,
  });

  const getFailureReason = computed(() => reasonList.value.find((e) => e.value === props.failureReason)?.label);
  const workflowList = computed<SelectOption[]>(() => {
    return (
      props.stageConfig?.stageConfigList.map((item) => ({
        label: item.name,
        value: item.id,
      })) || []
    );
  });

  function handleCancel() {
    updateStatusModal.value = false;
    form.value = { id: '', stage: failureStage.value, failureReason: null };
    form.value.stage = failureStage.value;
  }

  const formRef = ref<FormInst | null>(null);
  const updateStageLoading = ref(false);

  async function handleSave(stage: string) {
    try {
      updateStageLoading.value = true;
      if (props.updateApi) {
        await props.updateApi({
          id: props.sourceId,
          stage,
          failureReason: props.showConfirmStatus && stage === failureStage.value ? form.value.failureReason : undefined,
        });
        handleCancel();
        Message.success(t('common.updateSuccess'));
        emit('loadDetail');
      }
    } catch (error) {
      // eslint-disable-next-line no-console
      console.log(error);
    } finally {
      updateStageLoading.value = false;
    }
  }

  function handleFlowSuccess() {
    emit('loadDetail');
  }

  const flowModalShow = ref(false);
  const currentStageConfig = computed(() =>
    props.stageConfig?.stageConfigList.find((e) => e.id === currentStage.value)
  );
  const targetStageConfig = ref<StageConfigItem>();
  const circulationFieldValues = ref<CirculationFieldValueItem[]>([]);

  const enableReason = ref(false);
  // 更新状态
  async function handleUpdateStatus(stage: string) {
    const canContinue = (await props.beforeChangeStage?.(stage)) ?? true;
    if (!canContinue) {
      return;
    }

    if (
      props.showConfirmStatus &&
      stage === workflowList.value[workflowList.value.length - 1].value &&
      enableReason.value
    ) {
      updateStatusModal.value = true;
      form.value.stage = failureStage.value;
      return;
    }
    targetStageConfig.value = props.stageConfig?.stageConfigList.find((e) => e.id === stage);
    circulationFieldValues.value =
      props.stageConfig?.advancedConfigs
        ?.find((e) => e.originId === currentStage.value)
        ?.targets.find((e) => e.targetId === targetStageConfig.value?.id)?.circulationFieldValues || [];
    if (circulationFieldValues.value.length > 0) {
      flowModalShow.value = true;
    } else {
      handleSave(stage);
    }
  }

  // 确认更新
  async function handleConfirm() {
    if (enableReason.value) {
      formRef.value?.validate(async (errors) => {
        if (!errors) {
          handleSave(form.value.stage);
        }
      });
    } else {
      handleSave(form.value.stage);
    }
  }

  async function initReason() {
    try {
      const { dictList, enable } = await getReasonConfig(ReasonTypeEnum.OPPORTUNITY_FAIL_RS);
      enableReason.value = enable;
      reasonList.value = dictList.map((e) => ({ label: e.name, value: e.id }));
    } catch (e) {
      // eslint-disable-next-line no-console
      console.log(e);
    }
  }

  onBeforeMount(() => {
    if (props.showConfirmStatus) {
      initReason();
    }
  });
</script>

<style lang="less" scoped></style>
