import {
  Fragment,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from "react";
import { Checkbox, Text, View } from "@tarojs/components";
import Taro, { useDidShow } from "@tarojs/taro";
import {
  Button,
  InfiniteLoading,
  Picker,
  SafeArea,
  SearchBar,
  Tabs,
  VirtualList,
} from "@nutui/nutui-react-taro";
import { Icon } from "@/components";
import classNames from "classnames";
import { ActionType, IRecordListProps, Query, Record } from "./typing";

export default <T extends {}, Q extends Query = Query>(
  props: IRecordListProps<T, Q>,
) => {
  const {
    px = true,
    rowId,
    height,
    itemHeight,
    type,
    skeleton,
    actionRef,
    toolbar,
    render,
    request,
    pagination,
    tabbar,
    params,
  } = props;

  const [tab, setTab] = useState<string | number>(
    toolbar?.tabs?.defaultActiveKey || "",
  );

  const [searchType, setSearchType] = useState<string>(
    toolbar?.search?.defaultActiveKey || "",
  );

  const [lightTheme, setLightTheme] = useState(false);
  const [data, setData] = useState<T[]>([]);
  const [query, setQuery] = useState<Query>();

  const [selectRows, setSelectRows] = useState<any[]>([]);

  const [selectAll, setSelectAll] = useState("0");

  const [topBarHeight, setTopBarHeight] = useState<number>(0);
  const [bottomBarHeight, setBottomBarHeight] = useState<number>(0);
  const topBarRef = useRef<any>(null);
  const bottomBarRef = useRef<any>(null);

  useDidShow(() => {
    refresh().then();
  });

  useImperativeHandle(actionRef, () => {
    return {
      reload: () => {
        setQuery({
          ...query,
          ...params,
          pageIndex: 1,
          pageSize: pagination.pageSize || 10,
        });
      },
    } as ActionType;
  }, [pagination.pageSize, params]);

  useEffect(() => {
    setQuery({
      ...query,
      ...params,
      pageIndex: 1,
      pageSize: pagination.pageSize || 10,
    });
  }, [params]);

  useEffect(() => {
    // 获取 topBar 和 bottomBar 的实际高度
    const queryTopBar = Taro.createSelectorQuery();
    queryTopBar
      .select("#topBar")
      .boundingClientRect((rect: any) => {
        if (rect) {
          setTopBarHeight(rect.height);
        }
      })
      .exec();

    const queryBottomBar = Taro.createSelectorQuery();
    queryBottomBar
      .select("#bottomBar")
      .boundingClientRect((rect: any) => {
        if (rect) {
          setBottomBarHeight(rect.height);
        }
      })
      .exec();
  }, [toolbar]);

  useEffect(() => {
    if (query) {
      request(query as any).then((res: Record<any>) => {
        const list = res.data;
        if (res.success) {
          if (query.pageIndex === 1) {
            // 如果是第一页，则替换数据
            setData(list as any);
          } else {
            // 如果不是第一页，则追加数据
            if (data) {
              data.push(...(list as any));
              setData(data.slice());
            } else {
              setData(list as any);
            }
          }
          if (res.hasMore !== undefined) {
            setHasMore(res.hasMore);
          }
        }
      });
    }
  }, [query]);

  const [hasMore, setHasMore] = useState<boolean>();

  const loadMore = async () => {
    if (hasMore && query?.pageIndex) {
      setQuery({
        ...query,
        pageIndex: query.pageIndex + 1,
      });
    }
  };
  const refresh = async () => {
    await actionRef.current.reload();
  };

  // 可视区域条数
  const renderSkeleton = () => {
    return (
      <View className={"mx-2 flex flex-col gap-2"}>
        {new Array(Math.ceil(calculateScrollHeight() / (itemHeight + 8)))
          .fill(0)
          .map((_, index) => (
            <Fragment key={index}>{skeleton}</Fragment>
          ))}
      </View>
    );
  };

  if (!data) {
    if (skeleton) {
      return renderSkeleton();
    }
  }

  // 计算滚动区域高度：窗口高度 - topBar高度 - bottomBar高度
  const calculateScrollHeight = () => {
    if (height) return height;
    const windowHeight = Taro.getSystemInfoSync().windowHeight;
    return windowHeight - topBarHeight - bottomBarHeight;
  };

  return (
    <>
      {(toolbar?.tabs || toolbar?.search) && (
        <View
          className={"flex flex-col gap-2.5 px-2.5 pt-2.5"}
          id={"topBar"}
          ref={topBarRef}
        >
          {toolbar?.tabs && (
            <Tabs
              value={tab}
              onChange={(value) => {
                setTab(value);
                toolbar.tabs?.onChange(value);
              }}
            >
              {toolbar.tabs.items?.map((item, index) => (
                <Tabs.TabPane
                  title={item.title}
                  value={item.value}
                  key={index}
                />
              ))}
            </Tabs>
          )}
          {toolbar?.search && (
            <SearchBar
              className={"!p-0"}
              clearable
              placeholder={
                toolbar?.search?.items?.filter(
                  (item) => item.key === searchType,
                )[0].placeholder
              }
              onClear={() => actionRef.current.reload()}
              onSearch={(val) => {
                // 将所有 search items 的 key 设置为 undefined
                const clearedSearchKeys = (toolbar?.search?.items || []).reduce(
                  (acc, item) => ({
                    ...acc,
                    [item.key]: undefined,
                  }),
                  {},
                );

                // 只保留当前搜索类型的值
                setQuery({
                  ...query,
                  ...clearedSearchKeys,
                  [searchType]: val == "" ? undefined : val,
                  pageIndex: 1,
                });
              }}
              leftIn={
                <View
                  className={"flex flex-row items-center"}
                  onClick={() => {
                    setLightTheme(true);
                  }}
                >
                  {
                    toolbar?.search?.items?.filter(
                      (item) => item.key === searchType,
                    )[0].name
                  }
                  <Icon name="chevron-down" size={16} />
                </View>
              }
            />
          )}
          {toolbar?.render && toolbar.render()}
        </View>
      )}

      {type === "virtual" && data && (
        <VirtualList
          itemHeight={itemHeight || 66}
          list={data}
          itemRender={(item, index) =>
            (toolbar?.selectRow && (
              <View className={"flex items-center justify-center bg-white"}>
                <Checkbox
                  className={"pl-2"}
                  checked={selectRows.indexOf(item[rowId]) != -1}
                  value={item[rowId]}
                  onClick={() => {
                    if (selectRows.indexOf(item[rowId]) != -1) {
                      setSelectRows((prev) => {
                        return prev.filter((item) => item !== item[rowId]);
                      });
                    } else {
                      setSelectRows((prev) => {
                        return [...prev, item[rowId]];
                      });
                    }
                  }}
                ></Checkbox>
                {render(item, index)}
              </View>
            )) ||
            render(item, index)
          }
          containerHeight={calculateScrollHeight() || 667}
          onScroll={loadMore}
          itemEqual
          key={"couponId"}
          overscan={2}
          margin={8}
        />
      )}

      {type === "infinite" && data && (
        <View
          id={"scrollDemo"}
          className={classNames(
            "w-full overflow-x-hidden overflow-y-auto pt-2.5",
            {
              "px-2.5": px,
            },
          )}
          style={{
            height: calculateScrollHeight() || 667,
          }}
        >
          <InfiniteLoading
            pullingText={<>松开刷新</>}
            loadingText={<>加载中</>}
            loadMoreText={<>没有更多了</>}
            pullRefresh
            target="scrollDemo"
            hasMore={hasMore}
            onLoadMore={loadMore}
            onRefresh={refresh}
          >
            {data.map(
              (item, index) =>
                (toolbar?.selectRow && (
                  <View
                    className={
                      "mb-2.5 flex flex-1 items-start gap-2.5 rounded-md bg-white p-2.5 shadow-md"
                    }
                    key={index}
                  >
                    <Checkbox
                      checked={selectRows.some(
                        (item1) => item1[rowId] == item[rowId],
                      )}
                      value={item[rowId]}
                      onClick={() => {
                        if (
                          selectRows.some(
                            (item1) => item1[rowId] === item[rowId],
                          )
                        ) {
                          setSelectRows((prev) => {
                            return prev.filter(
                              (item1) => item1[rowId] !== item[rowId],
                            );
                          });
                        } else {
                          setSelectRows((prev) => {
                            return [...prev, item];
                          });
                        }
                      }}
                    ></Checkbox>
                    {render(item as any, index)}
                  </View>
                )) ||
                render(item as any, index),
            )}
          </InfiniteLoading>
        </View>
      )}

      <View
        className={"fixed bottom-0 flex w-full flex-col bg-white"}
        id={"bottomBar"}
        ref={bottomBarRef}
      >
        {toolbar?.actions && toolbar?.actions.map((item) => item)}

        {toolbar?.selectRow?.onClick && !toolbar?.footer && (
          <View key={"confirm"} className={"flex justify-between gap-2 p-2.5"}>
            <View className={"flex flex-1 items-center justify-between gap-1"}>
              <View className={"flex items-center gap-2"}>
                <Checkbox
                  className={"ml-2"}
                  checked={selectAll == "1"}
                  value={"1"}
                  onClick={() => {
                    if (selectAll === "1") {
                      setSelectAll("0");
                      setSelectRows([]);
                    } else {
                      setSelectAll("1");
                      data?.forEach((item) => {
                        if (
                          !selectRows.some(
                            (item1) => item1[rowId] === item[rowId],
                          )
                        ) {
                          setSelectRows((prev) => {
                            return [...prev, item];
                          });
                        }
                      });
                    }
                  }}
                />
                <Text className={"text-xs font-normal text-gray-400"}>
                  全选
                </Text>
              </View>
              <Text className={"text-sm text-stone-950"}>
                共{selectRows.length || 0}项
              </Text>
            </View>
            <Button
              type={"primary"}
              size={"large"}
              disabled={!selectRows.length}
              block={false}
              onClick={async () => toolbar?.selectRow?.onClick(selectRows)}
            >
              确认选择
            </Button>
          </View>
        )}

        {toolbar?.footer && toolbar?.footer?.(data || [])}
        {tabbar ? tabbar : <SafeArea position="bottom" />}

        <Picker
          title="请选择查询条件"
          visible={lightTheme}
          defaultValue={
            toolbar?.search?.defaultActiveKey
              ? [toolbar?.search?.defaultActiveKey]
              : []
          }
          options={[
            toolbar?.search?.items?.map((c) => ({
              value: c.key,
              label: c.name,
            })) || [],
          ]}
          onConfirm={(value: any) => {
            setSearchType(value[0]?.value);
          }}
          onClose={() => setLightTheme(false)}
        />
      </View>
    </>
  );
};
