/**
 * 质量组件属性校验与默认值收敛
 * <p>
 * 只在保存 / 发布前调用；设计过程中的中间态（比如刚拖到画布、还没填值）不触发校验。
 */
import type {
  QualityComponentDefinition,
  QualityFieldSchema,
  QualityProps,
} from './types';

/** 把任意来源的原始值收敛成字段声明的类型 */
export function coerceFieldValue(
  field: QualityFieldSchema,
  raw: boolean | number | string,
): boolean | number | string {
  switch (field.type) {
    case 'boolean': {
      if (typeof raw === 'boolean') {
        return raw;
      }
      return raw === 'true' || raw === '1';
    }
    case 'number': {
      const parsed = Number(raw);
      if (Number.isFinite(parsed)) {
        return parsed;
      }
      return typeof field.defaultValue === 'number' ? field.defaultValue : 0;
    }
    default: {
      return String(raw);
    }
  }
}

/** 以 defaults 打底，用传入值覆盖其中的合法项，得到完整可用的属性集 */
export function resolveQualityProps(
  definition: QualityComponentDefinition,
  props?: QualityProps,
): QualityProps {
  const resolved: QualityProps = { ...definition.defaults };
  if (!props) {
    return resolved;
  }
  definition.propertySchema.forEach((field) => {
    const raw = props[field.key];
    if (raw === undefined) {
      return;
    }
    resolved[field.key] = coerceFieldValue(field, raw);
  });
  return resolved;
}

/**
 * 校验业务属性，返回错误信息数组；空数组表示通过。
 * <p>
 * 提示要能让用户直接定位，所以带上字段显示名与实际值。
 */
export function validateQualityProps(
  definition: QualityComponentDefinition,
  props?: QualityProps,
): string[] {
  const errors: string[] = [];
  const resolved = resolveQualityProps(definition, props);
  definition.propertySchema.forEach((field) => {
    const value = resolved[field.key];
    const isEmpty = value === undefined || value === '';
    if (isEmpty) {
      if (field.required) {
        errors.push(`${definition.label}的「${field.label}」不能为空`);
      }
      return;
    }
    if (field.type === 'enum' && field.options) {
      const matched = field.options.some((option) => String(option.value) === String(value));
      if (!matched) {
        errors.push(
          `${definition.label}的「${field.label}」值「${value}」不在可选项内，请重新选择`,
        );
      }
      return;
    }
    if (field.type === 'number' && typeof value === 'number' && !Number.isFinite(value)) {
      errors.push(`${definition.label}的「${field.label}」必须是数字，当前为「${value}」`);
    }
  });
  // 逐个字段的规则上面已经查完，剩下的是「字段都在、但组合起来不成立」的规则
  // （列定义串的语法、表头跨列数合计等），只有组件自己知道，必须在这里接上。
  // 不接的话 definition.validate 就是个没人调用的死方法，写了也不会拦住任何人。
  errors.push(...(definition.validate?.(resolved) ?? []));
  return errors;
}