import { IParam } from "@core";
import { IActionParam } from "@core/interface";
import { Ref } from "vue";
import { ControlStateBase } from "../control-base";
import { MDControl } from "../md-control";
import { DataViewControlProps } from "./dataview-control-prop";
import { DataViewControlState } from "./dataview-control-state";

/**
 * 实体卡片视图部件
 *
 * @export
 * @class DataViewControl
 * @extends {MDControl}
 */
export class DataViewControl extends MDControl {

  /**
   * 实体卡片视图部件状态
   *
   * @type {DataViewControlState}
   * @memberof DataViewControl
   */
  public declare state: DataViewControlState;

  /**
   * 实体卡片视图部件输入参数
   *
   * @type {DataViewControlProps}
   * @memberof DataViewControl
   */
  public declare props: DataViewControlProps;

  /**
   * @description 处理状态变化
   * @memberof DataViewControl
   */
  public handleStateChange() {
    // 计算列表数据界面行为权限
    const { items, uIActions } = toRefs(this.state);
    if (items.value.length > 0 && uIActions.value && Object.keys(uIActions.value).length > 0) {
      Object.keys(uIActions.value).forEach((key: string) => {
        const tempActionModel = uIActions.value[key];
        items.value.forEach((item: any) => {
          Object.assign(item, { [key]: this.getActionAuthState(item, [tempActionModel]) });
        });
      })
    }
    //  清空选中数据，避免多次加载选中效果异常
    this.state.selections = [];
    // 处理分组
    this.handleDataGroup();
    // 处理默认选中
    this.handleDefaultSelect();
  }

  /**
   * @description 默认选中
   * @private
   * @memberof DataViewControl
   */
  private handleDefaultSelect() {
    const { selectFirstDefault, controlName } = this.state;
    const { selections, items } = toRefs(this.state);
    if (selectFirstDefault) {
      if (items.value && items.value.length > 0) {
        selections.value.push(items.value[0]);
        this.emit("ctrlEvent", {
          tag: controlName,
          action: "selectionChange",
          data: [items.value[0]],
        });
      }
    }
  }

  /**
   * @description 触发界面行为
   * @protected
   * @param {IParam} item 列表数据
   * @param {IParam} action 界面行为
   * @param {MouseEvent} event 鼠标源事件
   * @memberof DataViewControl
   */
  protected onUIAction(item: IParam, action: IParam, event: MouseEvent) {
    if (!item || !action) {
      console.warn("行为执行参数不足");
      return;
    }
    const inputParam = {
      context: this.state.context,
      viewParams: this.state.viewParams,
      data: [item],
      event: event,
      actionEnvironment: this
    };
    // 执行行为
    App.getAppActionService().execute(action, inputParam);
  }

  /**
   * 使用自定义模块
   *
   * @protected
   * @return {*} 
   * @memberof DataViewControl
   */
  protected useCustom() {
    const { controlName } = this.state;
    
    /**
     * 数据项选中
     *
     * @param {IParam} item 数据项
     * @param {MouseEvent} event 鼠标源事件
     */
    const onDataViewItemSelected = (item: IParam, event: MouseEvent) => {
      const { isMultiple } = this.state;
      const { selections } = toRefs(this.state);
      const index = selections.value.findIndex((selection: any) => selection.srfkey === item.srfkey);
      //  存在选中则删除
      if (index !== -1) {
        selections.value.splice(index, 1);
      } else {
        //  单选清空已选中
        if (!isMultiple) {
          selections.value.splice(index, selections.value.length);
        }
        selections.value.push(item);
      }
      this.emit('ctrlEvent', { tag: controlName, action: 'selectionChange', data: selections.value });
    }

    /**
     * 是否选中
     * 
     * @param item 列表项
     * @returns 
     */
    const isSelected = (item: IParam): boolean => {
      const { selections } = toRefs(this.state);
      return selections.value.findIndex((selection: any) => selection.srfkey === item.srfkey) !== -1;
    }

    return {
      onDataViewItemSelected: onDataViewItemSelected.bind(this),
      isSelected: isSelected.bind(this)
    }
  }

  /**
   * 安装部件功能模块
   *
   * @return {*} 
   * @memberof DataViewControl
   */
  public moduleInstall() {
    const superParams = super.moduleInstall();
    return {
      ...superParams,
      onUIAction: this.onUIAction.bind(this),
      useCustom: this.useCustom.bind(this)
    }
  }
}