import { computed, nextTick, ref, unref, watch } from 'vue';
import { propTypes } from '/@/utils/propTypes';
import { useDesign } from '/@/hooks/web/useDesign';
import { getEnhanced, replaceProps } from '../utils/enhancedUtils';
import { vModel } from '/@/components/jeecg/JVxeTable/utils';
import { JVxeRenderType } from '../types/JVxeTypes';
import { isBoolean, isFunction, isObject, isPromise } from '/@/utils/is';
import { JVxeComponent } from '../types/JVxeComponent';
import { filterDictText } from '/@/utils/dict/JDictSelectUtil';
import { getAreaTextByCode } from "@/components/Form/src/utils/Area";

export function useJVxeCompProps() {
  return {
    // 组件类型
    type: propTypes.string,
    // 渲染类型
    renderType: propTypes.string.def('default'),
    // 渲染参数
    params: propTypes.object,
    // 渲染自定义选项
    renderOptions: propTypes.object,
  };
}

export function useJVxeComponent(props: JVxeComponent.Props) {
  const value = computed(() => {
    // 代码逻辑说明: 【QQYUN-9125】oracle数据库日期类型字段会默认带上时分秒
    const val = props.params.row[props.params.column.property];
    if (props.type === 'date' && typeof val === 'string') {
      return val.split(' ').shift();
    } else {
      return val;
    }
  });
  const innerValue = ref(value.value);
  const row = computed(() => props.params.row);
  const rows = computed(() => props.params.data);
  const column = computed(() => props.params.column);
  // 用户配置的原始 column
  const originColumn = computed(() => column.value.params);
  const rowIndex = computed(() => props.params._rowIndex);
  const columnIndex = computed(() => props.params._columnIndex);
  // 表格数据长度
  const fullDataLength = computed(() => props.params.$table.internalData.tableFullData.length);
  // 是否正在滚动中
  const scrolling = computed(() => !!props.renderOptions.scrolling);
  // 当有formatter时，优先使用formatter
  const innerLabel = computed(() => {
    if(typeof column.value?.formatter === 'function'){
      return column.value.formatter({
        cellValue: innerValue.value,
        row: row.value,
        column: column.value,
      });
    }
    return innerValue.value
  });
  const cellProps = computed(() => {
    let renderOptions = props.renderOptions;
    let col = originColumn.value;

    let cellProps = {};

    // 输入占位符
    cellProps['placeholder'] = replaceProps(col, col.placeholder);

    // 解析props
    if (isObject(col.props)) {
      Object.keys(col.props).forEach((key) => {
        cellProps[key] = replaceProps(col, col.props[key]);
      });
    }

    // 判断是否是禁用的列
    cellProps['disabled'] = isBoolean(col['disabled']) ? col['disabled'] : cellProps['disabled'];
    // 判断是否禁用行
    if (renderOptions.isDisabledRow(row.value, rowIndex.value)) {
      cellProps['disabled'] = true;
    }
    // 代码逻辑说明: 【TV360X-291】没勾选同步数据库禁用排序功能
    if (col.props && col.props.isDisabledCell) {
      if (col.props.isDisabledCell({ row: row.value, rowIndex: rowIndex.value, column: col, columnIndex: columnIndex.value })) {
        cellProps['disabled'] = true;
      }
    }
    // 判断是否禁用所有组件
    if (renderOptions.disabled === true) {
      cellProps['disabled'] = true;
      // 代码逻辑说明: 【TV360X-1068】行编辑整体禁用时上传按钮不显示
      cellProps['disabledTable'] = true;
    }
    // 代码逻辑说明: VUEN-1111 一对多子表 部门选择 不应该级联
    if (col.checkStrictly === true) {
      cellProps['checkStrictly'] = true;
    }

    // 代码逻辑说明: 用户组件 控制单选多选新的参数配置
    if (col.isRadioSelection === true) {
      cellProps['isRadioSelection'] = true;
    } else if (col.isRadioSelection === false) {
      cellProps['isRadioSelection'] = false;
    }

    return cellProps;
  });

  const listeners = computed(() => {
    let listeners = Object.assign({}, props.renderOptions.listeners || {});
    // 默认change事件
    if (!listeners.change) {
      listeners.change = async (event) => {
        vModel(event.value, row, column);
        await nextTick();
        // 处理 change 事件相关逻辑（例如校验）
        props.params.$table.updateStatus(props.params);
      };
    }
    return listeners;
  });
  const context = {
    innerLabel,
    innerValue,
    row,
    rows,
    rowIndex,
    column,
    columnIndex,
    originColumn,
    fullDataLength,
    cellProps,
    scrolling,
    handleChangeCommon,
    handleBlurCommon,
  };
  const ctx = { props, context };

  // 获取组件增强
  let enhanced = getEnhanced(props.type);

  watch(
    value,
    (newValue) => {
      // -update-begin--author:liaozhiyang---date:20241210---for：【issues/7497】隐藏某一列后，字典没翻译，恢复后正常
      // TODO 先这样修复解决问题，根因后期再看看
      enhanced = getEnhanced(props.type);
      // -update-end--author:liaozhiyang---date:20241210---for：【issues/7497】隐藏某一列后，字典没翻译，恢复后
      // 验证值格式
      let getValue = enhanced.getValue(newValue, ctx);
      if (newValue !== getValue) {
        // 值格式不正确，重新赋值
        newValue = getValue;
        vModel(newValue, row, column);
      }
      innerValue.value = enhanced.setValue(newValue, ctx);
      // 代码逻辑说明: 【QQYUN-9205】一对多(jVxetable组件date)支持年，年月，年度度，年周
      if (props.type === 'date' && props.renderType === JVxeRenderType.spaner && enhanced.translate.enabled === true) {
        if (isFunction(enhanced.translate.handler)) {
          innerValue.value = enhanced.translate.handler(newValue, ctx);
        }
        return;
      }

      // 代码逻辑说明: 【issues/7203】自动生成一对多表单代码中，省市区回显问题---
      if (props.type === 'pca' && props.renderType === JVxeRenderType.spaner) {
        innerValue.value = getAreaTextByCode(newValue);
        return;
      }

      // 判断是否启用翻译
      if (props.renderType === JVxeRenderType.spaner && enhanced.translate.enabled === true) {
        if (isFunction(enhanced.translate.handler)) {
          let res = enhanced.translate.handler(newValue, ctx);
          // 异步翻译，可解决字典查询慢的问题
          if (isPromise(res)) {
            res.then((v) => (innerValue.value = v));
          } else {
            innerValue.value = res;
          }
        }
      }
    },
    { immediate: true }
  );

  /** 通用处理 change 事件 */
  function handleChangeCommon($value, force = false) {
    const newValue = enhanced.getValue($value, ctx);
    const oldValue = value.value;
    // 代码逻辑说明: 【issues-5025】JVueTable的事件 @valueChange重复触发问题
    const execute = force ? true : newValue !== oldValue;
    if (execute) {
      trigger('change', { value: newValue });
      // 触发valueChange事件
      parentTrigger('valueChange', {
        type: props.type,
        value: newValue,
        oldValue: oldValue,
        col: originColumn.value,
        rowIndex: rowIndex.value,
        columnIndex: columnIndex.value,
      });
    }
  }

  /** 通用处理 blur 事件 */
  function handleBlurCommon($value) {
    // 代码逻辑说明: 【issues/636】JVxeTable加上blur事件
    const newValue = enhanced.getValue($value, ctx);
    const oldValue = value.value;
    //trigger('blur', { value });
    // 触发blur事件
    parentTrigger('blur', {
      type: props.type,
      value: newValue,
      oldValue: oldValue,
      col: originColumn.value,
      rowIndex: rowIndex.value,
      columnIndex: columnIndex.value,
    });
  }

  /**
   * 如果事件存在的话，就触发
   * @param name 事件名
   * @param event 事件参数
   * @param args 其他附带参数
   */
  function trigger(name, event?, args: any[] = []) {
    let listener = listeners.value[name];
    if (isFunction(listener)) {
      if (isObject(event)) {
        event = packageEvent(name, event);
      }
      listener(event, ...args);
    }
  }

  function parentTrigger(name, event, args: any[] = []) {
    args.unshift(packageEvent(name, event));
    trigger('trigger', name, args);
  }

  function packageEvent(name, event: any = {}) {
    event.row = row.value;
    event.column = column.value;
    // online增强参数兼容
    event.column['key'] = column.value['property'];
    // event.cellTarget = this
    if (!event.type) {
      event.type = name;
    }
    if (!event.cellType) {
      event.cellType = props.type;
    }
    // 是否校验表单，默认为true
    if (isBoolean(event.validate)) {
      event.validate = true;
    }
    return event;
  }

  /**
   * 防样式冲突类名生成器
   * @param scope
   */
  function useCellDesign(scope: string) {
    return useDesign(`vxe-cell-${scope}`);
  }

  return {
    ...context,
    enhanced,
    trigger,
    useCellDesign,
  };
}

/**
 * 获取组件默认增强
 */
export function useDefaultEnhanced(): JVxeComponent.EnhancedPartial {
  return {
    installOptions: {
      autofocus: '',
    },
    interceptor: {
      'event.clearActived': () => true,
      'event.clearActived.className': () => true,
    },
    switches: {
      editRender: true,
      visible: false,
    },
    aopEvents: {
      editActived() {},
      editClosed() {},
      activeMethod: () => true,
    },
    translate: {
      enabled: false,
      handler(value, ctx) {
        // 默认翻译方法
        if (ctx) {
          return filterDictText(unref(ctx.context.column).params.options, value);
        } else {
          return value;
        }
      },
    },
    getValue: (value) => value,
    setValue: (value) => value,
    createValue: (defaultValue) => defaultValue,
  } as JVxeComponent.Enhanced;
}
