import {
  fillColumnDetailLink,
  makeTableUI,
  parseParam,
  rowOptionColumn,
} from '@/generated/utils/table-helpers';
import { history, useAccess } from 'umi';
import type { ReactText } from 'react';
import { useMemo, useRef, useState } from 'react';
import Cookies from 'js-cookie';
import type { FieldsType, FragmentsType } from '@/generated/services/utils';
import type { SortOrder } from 'antd/es/table/interface';

export function useUrlParams(
  originTableProps: Record<string, any>,
  requestTableList: any,
  initialParams?: Record<string, any>,
  fields?: FieldsType,
  fragments?: FragmentsType,
) {
  const queryContextRef = useRef({});
  return useMemo(() => {
    const originUrlParams = parseParam(window.location.href);
    // eslint-disable-next-line @typescript-eslint/dot-notation
    const uiConfig = JSON.parse(originUrlParams['_UI'] || '{}');

    const validFields = [
      ...originTableProps.columns
        .filter((field) => !field.relation)
        .map((field) => field.dataIndex),
      'current',
      'pageSize',
    ];
    const urlParams = Object.entries(originUrlParams)
      .filter(([key]) => validFields.includes(key))
      .reduce((acc, [key, value]) => {
        if (value.startsWith('$cookie.')) {
          acc[key] = Cookies.get(value.replace('$cookie.', ''));
        } else {
          acc[key] = value;
        }
        return acc;
      }, {});

    const tableProps = {
      ...originTableProps,
      ...makeTableUI(originTableProps.columns, uiConfig, 'url'),
    };
    const defaultFields = originTableProps.columns
      .filter((column) => !column.hideInTable && !column.key.startsWith('__'))
      .map((column) => column.key);

    function requestListWrapper(
      params: any,
      sorter?: Record<string, SortOrder>,
      filter?: Record<string, ReactText[] | null>,
    ) {
      Object.assign(queryContextRef.current, { params, sorter, filter });
      return requestTableList(
        { ...initialParams, ...params, ...urlParams },
        sorter,
        filter,
        fields || defaultFields,
        fragments,
      );
    }

    return { tableProps, urlParams, queryContextRef, requestListWrapper };
  }, []);
}

export function useColumnsOption(
  tableColumns,
  tableRowOptionConfig,
  formProps,
  tableContext,
  tableName,
  createFn,
  updateFn,
  deleteFn,
  customHandler: any = () => {}, // 自定义操作的handler
  columnWidth = 140,
  visibleCnt = 2,
) {
  const accessInfo = useAccess();
  const columns = useMemo(() => {
    const optionColumn = tableColumns.find(({ key }) => key === '__OPTION__');
    const cols = optionColumn
      ? [
          ...tableColumns.filter(({ key }) => key !== '__OPTION__'),
          {
            ...optionColumn,
            ...rowOptionColumn(
              customHandler,
              columnWidth,
              tableRowOptionConfig,
              tableColumns,
              formProps,
              tableContext,
              tableName,
              createFn,
              updateFn,
              deleteFn,
              accessInfo,
              visibleCnt,
            ),
          },
        ]
      : tableColumns;
    fillColumnDetailLink(cols, tableContext);

    return cols;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [accessInfo]);
  return columns;
}

export type PageRouteActions = {
  hasDetailPage?: boolean;
  editOnNewPage?: boolean;
  detailOnNewPage?: boolean;
  detailOnNewWindow?: boolean;
  createOnNewPage?: boolean;
  editOnDetailPage?: boolean;
};

export type ModifyContextOptions = {
  pathname?: string;
};

export type ChangeValueData = {
  title?: string;
  column?: Record<string, any>[];
  id?: string | number;
};

export function useModifyContext(routeActions: PageRouteActions, options?: ModifyContextOptions) {
  const [currentRow, setCurrentRow] = useState<Record<string, any> | null>(null);
  const [createModalVisible, setCreateModalVisible] = useState(false);
  const [updateModalVisible, setUpdateModalVisible] = useState(false);
  const [detailModalVisible, setDetailModalVisible] = useState(false);
  const [changeValueModalVisible, setChangeValueModalVisible] = useState(false);
  const [changeValueModal, setChangeValueModal] = useState<ChangeValueData>({
    title: null,
    column: [],
    id: null,
  });

  const pathname = options?.pathname || history.location.pathname;
  const setCreate = (visible: boolean) => {
    if (routeActions.createOnNewPage) {
      history.push(`${pathname}/add`);
      return;
    }
    setCreateModalVisible(visible);
  };
  const setUpdate = (visible: boolean, record?: any) => {
    if (routeActions.editOnNewPage) {
      history.push(`${pathname}/${record?.id}/edit`);
      return;
    }
    setCurrentRow(record);
    setUpdateModalVisible(visible);
  };
  const setDetail = (visible: boolean, record?: any) => {
    if (!routeActions.hasDetailPage) {
      setUpdate(visible, record);
      return;
    }
    if (routeActions.detailOnNewWindow) {
      window.open(`${pathname}/${record?.id}/detail`);
      return;
    }
    if (routeActions.detailOnNewPage) {
      window.open(`${pathname}/${record?.id}/detail`);
      return;
    }
    setCurrentRow(record);
    setDetailModalVisible(visible);
  };

  return {
    currentRow,
    setCurrentRow,
    createModalVisible,
    setCreateModalVisible,
    updateModalVisible,
    setUpdateModalVisible,
    detailModalVisible,
    setDetailModalVisible,
    changeValueModalVisible,
    setChangeValueModalVisible,
    changeValueModal,
    setChangeValueModal,
    setCreate,
    setUpdate,
    setDetail,
  };
}
