<script setup lang="ts">
import { nextTick } from 'vue';
import { VxeUI, type VxeFormProps, type VxeFormListeners } from 'vxe-pc-ui';
import type { SupplierModel } from '@/model/care.model';
import { useRequest } from 'alova/client';
import { supplierMethod, supplierEditMethod } from '@/request/api/care.api';
import { getDictionaryMethod } from '@/request/api/dictionary.api';
import { branchMethod } from '@/request/api/system.api';
import { notification } from 'ant-design-vue';
import { TreeSelect } from 'ant-design-vue';
const SHOW_ALL = TreeSelect.SHOW_ALL;

type FormModel = Partial<SupplierModel>;

const defaultModel = {};

const props = defineProps<{ data: FormModel }>();
const emits = defineEmits<{
  submit: [data?: SupplierModel];
}>();

const model = ref<Record<string, any>>({});
watchEffect(() => {
  const data = props.data;
  const collaborateDepts = data?.collaborateDepts?.map((item: any) => ({ value: String(item.deptId), label: item.deptName })) ?? [];
  model.value = {
    collaborateDepts
  }
});

const branch = ref<any[]>([]);
const { loading: branchLoading } = useRequest(branchMethod).onSuccess(({ data }) => {
  const to = (data?: any[]): any[] => {
    return Array.isArray(data)
      ? data.map(item => ({
          ...item,
          value: String(item.id),
          key: String(item.id),
          label: item.label,
          title: item.label,
          children: to(item.children)
        }))
      : [];
  }
  branch.value = to(data);
});

// 安全挂载弹层，避免 document 不可用时报错
function getSafePopupContainer(triggerNode?: HTMLElement) {
  try {
    // @ts-ignore
    if (typeof document !== 'undefined' && document?.body) return document.body;
  } catch (e) {}
  return triggerNode?.parentNode as HTMLElement | undefined;
}

// 查找节点/子孙/标签
function findNode(nodes: any[], id: string | number): any | undefined {
  for (const n of nodes) {
    if (String(n.value) === String(id)) return n;
    const x = n.children && findNode(n.children, id);
    if (x) return x;
  }
}
function collectChildren(node?: any): string[] {
  const res: string[] = [];
  if (!node?.children) return res;
  const dfs = (n: any) => {
    if (!n?.children) return;
    for (const c of n.children) {
      res.push(String(c.value));
      dfs(c);
    }
  };
  dfs(node);
  return res;
}
function findLabel(nodes: any[], id: string | number): string {
  const stack = [...nodes];
  while (stack.length) {
    const n = stack.pop();
    if (String(n.value) === String(id)) return n.label;
    if (n.children) stack.push(...n.children);
  }
  return '';
}

// 收集整棵树的所有节点 key，用于一次性展开整个下拉树
function collectAllKeys(nodes: any[]): string[] {
  const keys: string[] = [];
  const stack = [...nodes];
  while (stack.length) {
    const n = stack.pop();
    if (!n) continue;
    keys.push(String(n.value));
    if (n.children) stack.push(...n.children);
  }
  return keys;
}
const expandedKeys = ref<string[]>([]);
function onVisibleChange(visible: boolean) {
  if (visible) {
    expandedKeys.value = collectAllKeys(branch.value);
  }
}
const { loading, send: load } = useRequest((params) => supplierMethod(1, 10, params), {
  immediate: false,
  initialData: props.data ?? defaultModel,
});
const { loading: submitting, send: submit } = useRequest(supplierEditMethod, { immediate: false }).onSuccess(({ data }) => {
  emits('submit');
});

const projectList = ref<Array<{ label: string; value: string }>>([]);

const formProps = reactive<VxeFormProps<FormModel>>({
  titleWidth: 100,
  titleAlign: 'right',
  titleColon: true,
  data: { ...props.data },
  items: [
    {
      field: 'name',
      title: '供应商',
      span: 24,
      itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
    },
    {
      field: 'detailAddress',
      title: '地址',
      span: 24,
      itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
    },
    {
      field: 'kahuna',
      title: '负责人',
      span: 24,
      itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
    },
    {
      field: 'phone',
      title: '联系电话',
      span: 24,
      itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
    },
    {
      field: 'collaborateDepts',
      title: '合作机构',
      span: 24,
      slots: {
        default: 'initiate',
      },
    },
    {
      field: 'onlineCPTypes',
      title: '居家项目',
      span: 24,
      itemRender: {
        name: 'VxeSelect',
        props: {
          placeholder: '请选择',
          options: computed(() => projectList.value),
          optionProps: {
            value: 'value',
            label: 'label',
          },
          multiple: true,
          collapseTags: true,
          clearable: true,
        },
      },
    },
    {
      field: 'offlineCPTypes',
      title: '线下项目',
      span: 24,
      itemRender: {
        name: 'VxeSelect',
        props: {
          placeholder: '请选择',
          options: computed(() => projectList.value),
          optionProps: {
            value: 'value',
            label: 'label',
          },
          multiple: true,
          collapseTags: true,
          clearable: true,
        },
      },
    },
    { align: 'center', span: 24, slots: { default: 'active' } },
  ],
  rules: {
    name: [{ required: true, message: '请输入供应商名称' }],
    phone: [{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }],
  },
});

function handleSelect(value: string, node: any, extra: any) {
  const get = (children?: any[]) => {
    if (!Array.isArray(children)) return;
    children.forEach(child => {
      if (!model.value.collaborateDepts.find((item: any) => item.value === child.value)) {
        model.value.collaborateDepts.push(child)
      }
      get(child.children)
    })
  }
  get(node.children)
}

const formEmits: VxeFormListeners<FormModel> = {
  submit({ data }) {
    data.collaborateDepts = model.value.collaborateDepts.map((item: any) =>{
      return {
        deptId: item.value,
        deptName: item.label
      }
    })
    submit(data).then(() => {
      notification.success({
        message: '操作成功',
      });
      VxeUI.modal.close('supplier-modal');
    });
  },
};

// 统一用 change 事件集中处理（父选子，取消独立），避免在 select 阶段改值导致弹层关闭
function onDeptChange(
  newVal: Array<{ value: string | number; label: string }>,
  _labels: Array<string>,
  extra: any
) {
  const current = new Set(newVal?.map((n) => String(n.value)) ?? []);
  const prev = new Set(
    (model.value.collaborateDepts as Array<{ value: string | number }> | undefined)?.map((n) => String(n.value)) ?? []
  );

  const final = new Set(current);

  // 优先使用组件提供的 triggerValue 判定是否为新增（选中）以及哪一个父节点被点击
  const triggerValue = String(extra?.triggerValue ?? '');
  const isChecked = !!extra?.checked; // true: 勾选, false: 取消

  if (triggerValue && isChecked) {
    // 勾选：为该节点补齐所有子孙节点
    const node = findNode(branch.value, triggerValue);
    if (node) {
      for (const cid of collectChildren(node)) final.add(cid);
    }
  } else if (!isChecked) {
    // 取消：独立行为，保持 current 即可（不联动移除子）
    // 无其他处理
  } else {
    // 回退策略：没有 extra（某些版本或场景），使用 diff 判定新增的父节点并补齐
    const added = [...current].filter((v) => !prev.has(v));
    for (const v of added) {
      const node = findNode(branch.value, v);
      if (node) {
        for (const cid of collectChildren(node)) final.add(cid);
      }
    }
  }

  const finalIds = [...final];
  const nextList = finalIds.map((id) => ({ value: String(id), label: findLabel(branch.value, id) }));
  // 延后设置，避免同一事件循环重绘导致“没反应”
  nextTick(() => {
    model.value.collaborateDepts = nextList;
  });
}
function cancel() {
  VxeUI.modal.close('supplier-modal');
}
onBeforeMount(async () => {
  if (props.data?.id) load(props.data);
  try {
    const res = await getDictionaryMethod('condition_type');
    if (res?.length > 0) {
      projectList.value = res; // 直接使用返回的数据
    }
  } catch (error) {
    console.error('获取项目列表失败:', error);
  }
});
</script>

<template>
  <div class="form-container">
    <vxe-form v-bind="formProps" v-on="formEmits" :loading="submitting">
      <template #initiate>
        <a-tree-select
          style="width: 100%"
          :show-checked-strategy="SHOW_ALL"
          tree-check-strictly
          :tree-data="branch"
          tree-checkable
          allow-clear
          :labelInValue="true"
          v-model:value="model.collaborateDepts"
          v-model:treeExpandedKeys="expandedKeys"
          :getPopupContainer="getSafePopupContainer"
          :dropdownMatchSelectWidth="false"
          :dropdownStyle="{ zIndex: 4000 }"
          placeholder="请选择"
          @change="onDeptChange"
          @dropdownVisibleChange="onVisibleChange"
        />
      </template>
      <template #active>
        <vxe-button type="reset" content="取消" :disabled="submitting" @click="cancel"></vxe-button>
        <vxe-button type="submit" status="primary" content="确定" :loading="submitting"></vxe-button>
      </template>
    </vxe-form>

  </div>
</template>

<style scoped lang="scss">
.form-container {
  padding: 20px;
}
</style>
