import { getMonitorInfoTree } from '@/api/ems/base/baseMonitorInfo';
import type { DisplacementBoardQuery } from '@/api/ems/types';
import { createDefaultTimeRange } from './displacementBoardShared';

type DisplacementBoardQueryForm = {
  compareScope: string;
  monitorId: string;
  monitorIds: string[];
  selectionLabel: string;
  samplingInterval: number;
  vibrationParam: string;
  highThreshold: number | undefined;
  warningThreshold: number | undefined;
  minContinuousSamples: number | undefined;
  rapidRiseThreshold: number | undefined;
  stddevThreshold: number | undefined;
};

type BuildQueryOptions = {
  includeVibrationParam?: boolean;
};

const createDefaultQueryForm = (defaultMetric = 'vibrationDisplacement'): VibrationBoardQueryForm => ({
  compareScope: 'all',
  monitorId: '',
  monitorIds: [],
  selectionLabel: '全部振动设备',
  samplingInterval: 5,
  vibrationParam: defaultMetric,
  highThreshold: undefined,
  warningThreshold: undefined,
  minContinuousSamples: undefined,
  rapidRiseThreshold: undefined,
  stddevThreshold: undefined
});

// 模块级缓存：同一浏览器会话内 7 个页面共享设备树与查询状态，避免重复请求和切页丢筛选。
const sharedState = reactive({
  treeLoaded: false,
  monitorTreeOptions: [] as any[],
  deviceDisplayMap: {} as Record<string, string>,
  daterangeRecordTime: createDefaultTimeRange() as string[],
  queryForm: createDefaultQueryForm()
});

export function useVibrationBoardQueryState(defaultMetric = 'vibrationDisplacement') {
  const localState = reactive({
    loading: false,
    treeLoading: false,
    treeProps: { label: 'label', children: 'children' }
  });

  // 仅在首次进入页面时应用默认主看指标，后续页面切换沿用用户最新选择。
  if (!sharedState.queryForm.vibrationParam) {
    sharedState.queryForm.vibrationParam = defaultMetric;
  }

  const { loading, treeLoading, treeProps } = toRefs(localState);
  const { monitorTreeOptions, deviceDisplayMap, daterangeRecordTime, queryForm } = toRefs(sharedState);
  const deviceCount = computed(() => queryForm.value.monitorIds?.length || (queryForm.value.monitorId ? 1 : 0));
  const hasMultiDevice = computed(() => deviceCount.value > 1 || ['group', 'all'].includes(queryForm.value.compareScope));

  const buildDeviceDisplayMap = (nodes: any[]): Record<string, string> =>
    (nodes || []).reduce(
      (acc, item) => {
        if (item.code && !item.children?.length) acc[item.code] = item.label;
        if (item.children?.length) Object.assign(acc, buildDeviceDisplayMap(item.children));
        return acc;
      },
      {} as Record<string, string>
    );

  const getLeafNodes = (nodes: any[]): any[] =>
    (nodes || []).flatMap((item) => (item.children?.length ? getLeafNodes(item.children) : item.code ? [item] : []));

  const buildSelection = (nodes: any[], selectionLabel: string, compareScope?: string) => {
    const monitorIds = nodes.map((item) => item.code);
    return {
      compareScope: compareScope || (monitorIds.length > 1 ? 'group' : 'single'),
      monitorId: monitorIds.length === 1 ? monitorIds[0] : '',
      monitorIds,
      selectionLabel
    };
  };

  const applySelection = (selection: any) => {
    Object.assign(queryForm.value, selection);
  };

  const setTimeRange = (value: string[]) => {
    daterangeRecordTime.value = value;
  };

  const setSamplingInterval = (value: number) => {
    queryForm.value.samplingInterval = value;
  };

  const setVibrationParam = (value: string) => {
    // 位移专属看板不再允许切换指标，这里强制收敛为位移，避免旧页面残留调用把状态带偏。
    queryForm.value.vibrationParam = 'vibrationDisplacement';
  };

  const resetAnomalyThresholds = () => {
    // 主看指标切换后必须回到“未覆盖”状态，让后端按新指标重新下发默认阈值，
    // 否则会把上一指标的阈值误当成当前指标的用户自定义值。
    queryForm.value.highThreshold = undefined;
    queryForm.value.warningThreshold = undefined;
    queryForm.value.minContinuousSamples = undefined;
    queryForm.value.rapidRiseThreshold = undefined;
    queryForm.value.stddevThreshold = undefined;
  };

  const loadTree = async () => {
    // 已加载且有缓存时直接复用，避免 7 个页面重复打同一个树接口。
    if (sharedState.treeLoaded) {
      return;
    }
    treeLoading.value = true;
    try {
      const response = await getMonitorInfoTree({ monitorType: 10 });
      monitorTreeOptions.value = response.data || [];
      deviceDisplayMap.value = buildDeviceDisplayMap(monitorTreeOptions.value);
      sharedState.treeLoaded = true;
      if (!queryForm.value.monitorIds.length && !queryForm.value.monitorId) {
        applySelection(buildSelection(getLeafNodes(monitorTreeOptions.value), '全部振动设备', 'all'));
      }
    } finally {
      treeLoading.value = false;
    }
  };

  const handleTreeNodeClick = (data: any) => {
    if (!data) return;
    if (data.children?.length) {
      applySelection(buildSelection(getLeafNodes(data.children), `${data.label}设备组`, 'group'));
      return;
    }
    applySelection(buildSelection([data], data.label, 'single'));
  };

  const buildQuery = (options?: BuildQueryOptions): VibrationBoardQuery => ({
    samplingInterval: queryForm.value.samplingInterval,
    // 位移专属看板统一固定为 vibrationDisplacement，前端不再暴露可切换口径。
    vibrationParam: 'vibrationDisplacement',
    beginRecordTime: daterangeRecordTime.value[0],
    endRecordTime: daterangeRecordTime.value[1],
    highThreshold: queryForm.value.highThreshold,
    warningThreshold: queryForm.value.warningThreshold,
    minContinuousSamples: queryForm.value.minContinuousSamples,
    rapidRiseThreshold: queryForm.value.rapidRiseThreshold,
    stddevThreshold: queryForm.value.stddevThreshold,
    monitorId: queryForm.value.monitorIds?.length > 1 ? undefined : queryForm.value.monitorIds?.[0] || queryForm.value.monitorId,
    monitorIds: queryForm.value.monitorIds?.length > 1 ? queryForm.value.monitorIds : undefined,
    params: {
      beginRecordTime: daterangeRecordTime.value[0],
      endRecordTime: daterangeRecordTime.value[1]
    }
  });

  const getMonitorDisplayName = (monitorId?: string) => (monitorId ? deviceDisplayMap.value[monitorId] || monitorId : '--');

  return {
    loading,
    treeLoading,
    monitorTreeOptions,
    treeProps,
    daterangeRecordTime,
    queryForm,
    deviceCount,
    hasMultiDevice,
    loadTree,
    handleTreeNodeClick,
    setTimeRange,
    setSamplingInterval,
    setVibrationParam,
    resetAnomalyThresholds,
    buildQuery,
    getMonitorDisplayName
  };
}
