import type { CardListApi, CardListPagination, CardListProps } from './types';

import { bindMethods, isFunction, mergeWithArrayOverride, StateHandler } from '@vben/utils';

import { Store } from '@vben-core/shared/store';

function getDefaultState(): CardListProps {
  return {
    class: '',
    gridClass: '',
    gridOptions: {
      columns: [],
      data: [],
      showTitle: true,
      gridColumns: 3,
      fieldColumns: 1,
      pagerConfig: {
        enabled: true,
        current: 1,
        pageSize: 10,
        total: 0,
        showSizeChanger: true,
        showQuickJumper: true,
        showTotal: (total: number) => `共 ${total} 条`,
      },
      cardHeight: 'auto',
      cardWidth: '100%',
      cardGap: '10px',
      loading: false,
      emptyText: '暂无数据',
    },
    gridEvents: {},
  };
}

export class CardListApiInstance<T extends Record<string, any> = any> implements CardListApi<T> {
  public state: CardListProps<T> | null = null;
  public store: Store<CardListProps<T>>;

  private isMounted = false;
  private stateHandler: StateHandler;

  constructor(options: CardListProps = {}) {
    const storeState = { ...options };

    const defaultState = getDefaultState();
    this.store = new Store<CardListProps>(mergeWithArrayOverride(storeState, defaultState), {
      onUpdate: () => {
        this.state = this.store.state;
      },
    });

    this.state = this.store.state;
    this.stateHandler = new StateHandler();
    bindMethods(this);
  }

  clear() {
    this.setData([]);
  }

  getData() {
    return (this.state?.gridOptions?.data || []).map((item) => ({ ...item })) as T[];
  }

  /** 检查组件是否已挂载 */
  getIsMounted() {
    return this.isMounted;
  }

  getState() {
    return this.state;
  }

  /** 添加项目 */
  insertAt(items: T[], index?: number) {
    const data = this.getData();
    const newData = [...data];

    if (typeof index === 'number' && index >= 0 && index <= newData.length) {
      newData.splice(index, 0, ...items);
    } else {
      // 需判断如果原数据已经存在，则不添加
      newData.push(...items);
    }

    this.setData(newData);
  }

  mount() {
    this.isMounted = true;
  }

  refresh() {
    // 触发数据刷新
    const currentData = this.state?.gridOptions?.data || [];
    this.setData([...currentData] as any);
  }

  remove(predicate: ((row: T, index: number) => boolean) | number) {
    const data = this.getData();

    const newData =
      typeof predicate === 'number'
        ? data.filter((_, index) => index !== predicate)
        : data.filter((row, index) => !predicate(row, index));

    this.setData(newData);
  }

  reset() {
    const defaultState = getDefaultState();
    this.setState({
      gridOptions: defaultState.gridOptions,
    });
  }

  setData(data: T[]) {
    this.setState({
      gridOptions: {
        ...this.state?.gridOptions,
        data: data as any,
      },
    });
  }

  setErrorItems(errorItems: any[]) {
    // 遍历data，将errorItems中的id匹配到的item添加error属性
    const newData = this.getData().map((item) => {
      const errorData = errorItems.find((error) => error.id === item.id);
      return errorData ? { ...item, error: true } : { ...item, error: false };
    });
    this.setState({
      gridOptions: {
        ...this.state?.gridOptions,
        data: newData as any,
      },
    });
  }

  setLoading(loading: boolean) {
    this.setState({
      gridOptions: {
        ...this.state?.gridOptions,
        loading,
      },
    });
  }

  setPagination(pagination: any) {
    // 确保分页对象符合CardListPagination类型要求
    const validPagination: CardListPagination = {
      current: pagination?.current || 1,
      pageSize: pagination?.pageSize || 10,
      total: pagination?.total,
      showSizeChanger: pagination?.showSizeChanger,
      showQuickJumper: pagination?.showQuickJumper,
      showTotal: pagination?.showTotal,
    };

    this.setState({
      gridOptions: {
        ...this.state?.gridOptions,
        pagerConfig: validPagination,
      },
    });
  }

  setState(
    state: ((prev: CardListProps<T>) => Partial<CardListProps<T>>) | Partial<CardListProps<T>>,
  ) {
    if (isFunction(state)) {
      const stateFn = state as (prev: CardListProps<T>) => Partial<CardListProps<T>>;
      this.store.setState((prev: any) => {
        return mergeWithArrayOverride(stateFn(prev), prev);
      });
    } else {
      this.store.setState((prev: any) => mergeWithArrayOverride(state, prev));
    }
  }

  unmount() {
    this.isMounted = false;
    this.stateHandler.reset();
  }

  updateItem(predicate: ((row: T, index: number) => boolean) | number, newItem: Partial<T>) {
    const data = this.getData();

    const newData = data.map((row, index) => {
      const matched = typeof predicate === 'number' ? index === predicate : predicate(row, index);

      return matched ? { ...row, ...newItem } : row;
    });

    this.setData(newData);
  }
}
