import { cloneDeep, pick } from 'lodash-es';

import { getDefaultValue, getSearchMultiple, getSearchType, noSearchList } from './config';

/**
 * 列表字段中由「列表设计」维护的属性，刷新时保留，其余属性一律以表单字段为准。
 * 与 ColumnDesign/src/components/Main.vue 里 setListValue 的回填清单保持一致。
 */
const COLUMN_OWN_KEYS = [
  'align',
  'biz_log_enabled',
  'contentFormat',
  'fixed',
  'headerAlign',
  'label',
  'labelI18nCode',
  'noShow',
  'sortable',
  'superQueryNoShow',
  'useContentFormat',
  'width',
];

/** 按列表字段的 prop 建立表单字段索引，子表字段的 key 为 `子表字段-子字段` */
function buildFormFieldMap(fields: any[]) {
  const map = new Map<string, any>();
  const loop = (data: any, parent?: any) => {
    if (!data) return;
    if (data.__config__ && Array.isArray(data.__config__.children)) loop(data.__config__.children, data);
    if (Array.isArray(data)) {
      for (const item of data) loop(item, parent);
      return;
    }
    const config = data.__config__;
    if (!config?.jnpfKey || config.layout !== 'colFormItem' || !data.__vModel__) return;
    const isTableChild = parent?.__config__?.jnpfKey === 'table';
    const id = isTableChild ? `${parent.__vModel__}-${data.__vModel__}` : data.__vModel__;
    map.set(id, {
      id,
      fullName: isTableChild ? `${parent.__config__.label}-${config.label}` : config.label,
      fullNameI18nCode: isTableChild ? [parent.__config__.labelI18nCode || '', config.labelI18nCode || ''] : [config.labelI18nCode || ''],
      ...data,
    });
  };
  loop(fields);
  return map;
}

/**
 * 列表和查询字段是表单字段配置的副本，只在进入「列表设计」时才会重建。
 * 保存前按最新表单字段刷新；查询字段沿用列表设计的合并规则：类型相同时保留查询设置，
 * 类型改变时使用新控件默认设置，不支持查询或在当前端不可见的字段从查询列表移除。
 */
function isFieldVisible(field: any, platform?: 'app' | 'pc') {
  if (!platform || !Array.isArray(field.__config__?.visibility)) return true;
  return field.__config__.visibility.includes(platform);
}

function buildSearchOption(field: any) {
  const jnpfKey = field.__config__.jnpfKey;
  return {
    label: field.fullName,
    labelI18nCode: field.__config__.labelI18nCode || '',
    prop: field.id,
    jnpfKey,
    sourceType: 2,
    value: getDefaultValue(field),
    searchType: getSearchType(field),
    searchMultiple: getSearchMultiple(jnpfKey),
    isKeyword: false,
    ...cloneDeep(field),
  };
}

function syncSearchListFieldConfig(columnData: any, fieldMap: Map<string, any>, platform?: 'app' | 'pc') {
  if (!Array.isArray(columnData.searchList)) return;
  columnData.searchList = columnData.searchList.flatMap((search: any) => {
    const field = fieldMap.get(search.prop);
    if (!field || !isFieldVisible(field, platform) || noSearchList.includes(field.__config__.jnpfKey)) return [];
    const nextSearch = buildSearchOption(field);
    nextSearch.label = search.label;
    nextSearch.labelI18nCode = search.labelI18nCode;
    nextSearch.isKeyword = search.isKeyword;
    if (search.jnpfKey === nextSearch.jnpfKey) {
      nextSearch.searchType = search.searchType;
      nextSearch.searchMultiple = search.searchMultiple;
      nextSearch.noShow = search.noShow;
      nextSearch.sourceType = search.sourceType;
      nextSearch.value = cloneDeep(search.value);
    }
    return [nextSearch];
  });
}

export function syncColumnListFieldConfig(columnData: any, formData: any, platform?: 'app' | 'pc') {
  const fields = formData?.fields;
  if (!columnData || !Array.isArray(fields) || !fields.length) return columnData;
  const fieldMap = buildFormFieldMap(fields);
  if (!fieldMap.size) return columnData;
  if (Array.isArray(columnData.columnList)) {
    columnData.columnList = columnData.columnList.map((column: any) => {
      const field = fieldMap.get(column.prop);
      if (!field) return column;
      return {
        labelI18nCode: field.__config__.labelI18nCode || '',
        label: field.fullName,
        prop: field.id,
        fixed: 'none',
        headerAlign: 'left',
        align: 'left',
        jnpfKey: field.__config__.jnpfKey,
        sortable: false,
        width: null,
        useContentFormat: false,
        biz_log_enabled: false,
        superQueryNoShow: false,
        ...cloneDeep(field),
        ...pick(column, COLUMN_OWN_KEYS),
      };
    });
  }
  syncSearchListFieldConfig(columnData, fieldMap, platform);
  return columnData;
}

/** 运行时兜底：列上的掩码配置可能是旧快照，按当前表单字段取正确的值 */
export function buildFormFieldMaskMap(formData: any) {
  const map = new Map<string, { maskConfig: any; useMask: boolean }>();
  const fields = formData?.fields;
  if (!Array.isArray(fields) || !fields.length) return map;
  for (const [id, field] of buildFormFieldMap(fields)) {
    map.set(id, { maskConfig: field.maskConfig, useMask: !!field.useMask });
  }
  return map;
}
