import type { ExtendedFormApi } from '@vben-core/form-ui';

import type { ZqCursorState, ZqPaginationInfo, ZqTableProps } from './types';

import { reactive, ref } from 'vue';

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

import { Store } from './store';

function getDefaultState(): ZqTableProps {
  return {
    class: '',
    gridClass: '',
    gridOptions: {
      proxyConfig: {
        autoLoad: true,
      },
      pagerConfig: {
        enabled: true,
        pageSize: 20,
        pageSizes: [10, 20, 50, 100],
        currentPage: 1,
        total: 0,
      },
    },
    gridEvents: {},
    formOptions: undefined,
    showSearchForm: true,
  };
}

export class ZqTableApi<T extends Record<string, any> = any> {
  public formApi = {} as ExtendedFormApi;

  public loading = ref(false);
  public pagination = reactive<ZqPaginationInfo>({
    currentPage: 1,
    pageSize: 20,
    total: 0,
  });

  // 游标分页状态
  public cursorState = reactive<ZqCursorState>({
    hasMore: false,
    hasPrev: false,
    nextCursor: null,
    prevCursor: null,
  });
  public cursorVirtualPage = ref(1);
  public cursorDirection = ref<'next' | 'prev'>('next');

  public state: null | ZqTableProps<T> = null;
  // 状态存储
  public store: Store<ZqTableProps<T>>;
  // 响应式数据供组件消费
  public tableData = ref<T[]>([]);
  public total = ref(0);

  private isMounted = false;
  private stateHandler: StateHandler;

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

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

  handlePageChange(currentPage: number, pageSize: number) {
    this.pagination.currentPage = currentPage;
    this.pagination.pageSize = pageSize;
    // 更新 store 中的 pagerConfig，保持一致性
    this.setState((prev) => ({
      gridOptions: {
        ...prev.gridOptions,
        pagerConfig: {
          ...prev.gridOptions?.pagerConfig,
          currentPage,
          pageSize,
        },
      },
    }));
    this.reload();
  }

  /** 游标分页 - 下一页 */
  cursorNext() {
    this.cursorDirection.value = 'next';
    this.cursorVirtualPage.value++;
    this.reload();
  }

  /** 游标分页 - 上一页 */
  cursorPrev() {
    this.cursorDirection.value = 'prev';
    this.cursorVirtualPage.value = Math.max(1, this.cursorVirtualPage.value - 1);
    this.reload();
  }

  /** 游标分页 - 切换每页条数 */
  cursorSizeChange(size: number) {
    this.pagination.pageSize = size;
    this.resetCursorState();
    this.reload();
  }

  /** 游标分页 - 页码变化（由 ElPagination 的 current-change 触发） */
  cursorPageChange(newPage: number) {
    if (newPage > this.cursorVirtualPage.value) {
      this.cursorNext();
    } else if (newPage < this.cursorVirtualPage.value) {
      this.cursorPrev();
    }
  }

  /** 更新游标分页状态（由查询回调返回值驱动） */
  updateCursorState(state: Partial<ZqCursorState>) {
    if (state.hasMore !== undefined) this.cursorState.hasMore = state.hasMore;
    if (state.hasPrev !== undefined) this.cursorState.hasPrev = state.hasPrev;
    if (state.nextCursor !== undefined) this.cursorState.nextCursor = state.nextCursor;
    if (state.prevCursor !== undefined) this.cursorState.prevCursor = state.prevCursor;
  }

  /** 重置游标分页状态 */
  resetCursorState() {
    this.cursorState.hasMore = false;
    this.cursorState.hasPrev = false;
    this.cursorState.nextCursor = null;
    this.cursorState.prevCursor = null;
    this.cursorVirtualPage.value = 1;
    this.cursorDirection.value = 'next';
  }

  mount(formApi: ExtendedFormApi) {
    if (!this.isMounted) {
      this.formApi = formApi;
      this.stateHandler.setConditionTrue();
      this.isMounted = true;
    }
  }

  // 模拟 commitProxy('query')
  async query(params: Record<string, any> = {}) {
    await this.reload(params);
  }

  // 核心数据加载逻辑
  async reload(params: Record<string, any> = {}) {
    console.log('[ZqTable] reload called, state:', this.state?.gridOptions);
    const { proxyConfig } = this.state?.gridOptions || {};
    if (!proxyConfig?.ajax?.query) {
      console.warn(
        '[ZqTable] No ajax.query configured, proxyConfig:',
        proxyConfig,
      );
      this.setLoading(false);
      return;
    }

    console.log('[ZqTable] Starting data load...');
    this.setLoading(true);
    try {
      // 1. 获取表单数据（带超时保护）
      let formData: Record<string, any> = {};
      try {
        if (
          this.isMounted &&
          this.formApi &&
          typeof this.formApi.getValues === 'function'
        ) {
          // 添加超时保护，避免 formApi 未就绪时卡住
          const timeoutPromise = new Promise<Record<string, any>>((_, reject) =>
            setTimeout(() => reject(new Error('Form API timeout')), 100),
          );
          formData = await Promise.race([
            this.formApi.getValues() as Promise<Record<string, any>>,
            timeoutPromise,
          ]).catch(() => ({}));
        }
      } catch {
        // 表单未初始化时忽略错误
        formData = {};
      }

      const isCursorMode = this.state?.gridOptions?.pagerConfig?.cursorMode;

      // 2. 组装参数
      const queryParams: any = {
        page: {
          currentPage: this.pagination.currentPage,
          pageSize: this.pagination.pageSize,
          total: this.pagination.total,
        },
        form: { ...formData, ...params },
        sort: {}, // TODO: 实现排序
      };

      if (isCursorMode) {
        queryParams.cursor = {
          direction: this.cursorDirection.value,
          nextCursor: this.cursorState.nextCursor,
          prevCursor: this.cursorState.prevCursor,
        };
      }

      // 3. 调用用户传入的 ajax 方法
      const queryFn = proxyConfig.ajax!.query as (params: any) => Promise<any>;
      const result = await queryFn(queryParams);

      // 4. 更新数据
      if (Array.isArray(result)) {
        this.tableData.value = result;
        this.total.value = result.length;
      } else if (result && typeof result === 'object') {
        this.tableData.value = result.items || result.data || [];

        // 游标模式下更新游标状态，不更新 total
        if (isCursorMode) {
          this.updateCursorState({
            hasMore: result.has_more ?? false,
            hasPrev: this.cursorVirtualPage.value > 1,
            nextCursor: result.next_cursor ?? null,
            prevCursor: result.prev_cursor ?? null,
          });
        } else {
          this.total.value = result.total || 0;
        }
      }

      if (!isCursorMode) {
        this.pagination.total = this.total.value;
      }
    } catch (error) {
      console.error('Load data failed', error);
    } finally {
      this.setLoading(false);
    }
  }

  setGridOptions(options: Partial<ZqTableProps['gridOptions']>) {
    this.setState({
      gridOptions: options,
    });
  }

  setLoading(isLoading: boolean) {
    this.loading.value = isLoading;
  }

  setState(
    stateOrFn:
      | ((prev: ZqTableProps<T>) => Partial<ZqTableProps<T>>)
      | Partial<ZqTableProps<T>>,
  ) {
    if (isFunction(stateOrFn)) {
      this.store.setState((prev) => {
        return mergeWithArrayOverride(stateOrFn(prev), prev);
      });
    } else {
      this.store.setState((prev) => mergeWithArrayOverride(stateOrFn, prev));
    }
  }

  toggleSearchForm(show?: boolean) {
    this.setState({
      showSearchForm: isBoolean(show) ? show : !this.state?.showSearchForm,
    });
    return this.state?.showSearchForm;
  }

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

  private syncStateToRefs() {
    if (this.state?.gridOptions?.data) {
      this.tableData.value = this.state.gridOptions.data;
    }
    if (this.state?.gridOptions?.pagerConfig) {
      const { currentPage, pageSize, total } =
        this.state.gridOptions.pagerConfig;
      if (currentPage !== undefined) this.pagination.currentPage = currentPage;
      if (pageSize !== undefined) this.pagination.pageSize = pageSize;
      if (total !== undefined) this.pagination.total = total;
    }
  }
}
