import _ from 'lodash';
import {
  queryUser as queryUserDefault,
  likeQueryUserById as likeQueryUserByIdDefault,
} from '../server';
import { formatUserRender } from '../utils';
import { Button, Checkbox, Divider, Select, Space } from 'antd';
import { debounce } from 'lodash';
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
import { useIntl } from 'umi';
type UserType = {
  id: number;
  nameZh?: string;
  nameEn?: string;
  state?: number;
  account?: string;
  disabled?: boolean;
};
export interface UserSelectProps {
  /**
   * @description 是否禁用。
   * @default false
   * */
  disabled?: boolean;
  value?: any;
  onChange?: (value: any) => void;
  /**
   * @description 可以选择单选还是多选，multiple是多选。
   */
  mode?: 'multiple' | 'tags' | undefined;
  /**
   * @description 是否需要展示全选功能。
   */
  showAllChecked?: boolean;
  state?: 0 | 1;
  placeholder?: string;
  /**
   * @description 选择填入本人
   */
  currentUser?: UserType;
  /**
   * @description 自定义的用户查询，如果自定义了queryUser，就一定要自定义likeQueryUserById
   */
  queryUser?: (search: string, state?: 0 | 1) => Promise<{ data: { list: UserType[] } }>;

  /**
   * @description 自定义的用户根据id查询， 如果自定义了likeQueryUserById，就一定要自定义queryUser，如果没有自定义的likeQueryUserById 直接设置false就好了。
   */
  likeQueryUserById?: ((ids: number[]) => Promise<{ data: { list: UserType[] } }>) | false;
}
const UserSelect = ({
  disabled = false,
  value,
  onChange,
  placeholder,
  mode,
  showAllChecked = false,
  state,
  currentUser,
  queryUser = queryUserDefault,
  likeQueryUserById = likeQueryUserByIdDefault,
}: UserSelectProps) => {
  const { formatMessage } = useIntl();
  const [options, setOptions] = useState<any[]>([]);
  const [selectUserMap, setSelectUserMap] = useState<any>({});
  const [user, setUser] = useState<any>();
  const [disabledUserOptions, setDisabledUserOptions] = useState<UserType[]>([]);
  const disabledUsers = useMemo(
    () => (mode ? value?.filter((item) => item?.disabled)?.map((item) => item?.id) : []),
    [value, mode],
  );
  const valueIds = useMemo(() => (mode ? value?.map((item) => item?.id) : [value]), [value, mode]);
  const handleChange = useCallback(
    (val) => {
      if (mode) {
        // 原来的id
        // 删除的id
        const disabledIds = _.difference(
          valueIds,
          val?.map((item) => item),
        )?.filter((item) => _.includes(disabledUsers, item));
        // 存在操作情况，要么新增一个，要么删除一个，要么全删, 要么全选。
        // 所以要看有没有被删掉不能操作的id，有的话需要加进去。
        onChange?.(
          [...val, ...disabledIds]?.map((item) => ({
            ...(selectUserMap[item] || { id: item }),
            disabled: _.includes(disabledUsers, item),
          })),
        );
        return;
      }
      onChange?.(val);
    },
    [onChange, selectUserMap, mode, valueIds, disabledUsers],
  );
  const searchChange = useMemo(
    () =>
      debounce(async (val) => {
        if (!val) return;
        const {
          data: { list },
        } = await queryUser(val.trim(), state);
        const newUserMap = {};
        disabledUserOptions?.forEach((item) => {
          if (!_.find(list, { id: item.id })) {
            list?.push(item);
          }
        });
        const res = list?.map((item) => {
          newUserMap[item.id] = {
            ...item,
            disabled: item.disabled || _.includes(disabledUsers, item?.id),
          };
          return {
            label: (
              <div key={item.id} style={{ display: 'inline-block' }}>
                {formatUserRender(
                  {
                    nameZh: item?.nameZh,
                    account: item?.nameEn,
                    id: item?.id,
                    state: item?.state,
                  },
                  false,
                  false,
                )}
              </div>
            ),
            key: item.id,
            value: item.id,
            disabled: item.disabled || _.includes(disabledUsers, item?.id),
          };
        });
        setOptions(res);
        setSelectUserMap((susemap) => ({ ...newUserMap, ...susemap }));
      }, 200),
    [queryUser, state, disabledUsers, disabledUserOptions],
  );

  useEffect(() => {
    if (mode && value?.length > 0 && !_.isBoolean(likeQueryUserById)) {
      (likeQueryUserById as (ids: number[]) => Promise<{ data: { list: UserType[] } }>)?.(
        value?.map((item: { id: any }) => item?.id),
      ).then((resData) => {
        const {
          data: { list },
        } = resData;
        const newUserMap = {};
        setDisabledUserOptions(
          list
            ?.filter((item) => _.includes(disabledUsers, item?.id))
            ?.map((item) => ({
              ...item,
              disabled: true,
            })) || [],
        );
        const res = list?.map((item) => {
          const itemDisabled = _.includes(disabledUsers, item?.id);
          newUserMap[item.id] = {
            cnName: item.nameZh || item.nameEn,
            userName: item.account,
            state: item.state,
            id: item.id,
            disabled: itemDisabled,
          };
          return {
            label: (
              <div key={item.id} style={{ display: 'inline-block' }}>
                {formatUserRender(
                  {
                    nameZh: item?.nameZh || item?.nameEn,
                    account: item.account,
                    id: item?.id,
                    state: item?.state,
                  },
                  itemDisabled,
                  false,
                )}
              </div>
            ),
            key: item.id,
            value: item.id,
            disabled: itemDisabled,
          };
        });
        setOptions(res);
        setSelectUserMap((susermap) => ({ ...susermap, ...newUserMap }));
      });
    }
    if (!mode && value && !_.isBoolean(likeQueryUserById)) {
      (
        likeQueryUserById as (ids: (number | string)[]) => Promise<{ data: { list: UserType[] } }>
      )?.([value]).then((resData) => {
        const {
          data: { list },
        } = resData;
        const itemDisabled = _.includes(disabledUsers, list?.[0]?.id);
        const res = [
          {
            label: (
              <div key={list?.[0]?.id} style={{ display: 'inline-block' }}>
                {formatUserRender(
                  {
                    nameZh: list?.[0]?.nameZh || list?.[0]?.nameEn,
                    account: list?.[0].account,
                    id: list?.[0]?.id,
                    state: list?.[0]?.state,
                  },
                  itemDisabled,
                  false,
                )}
              </div>
            ),
            key: list?.[0].id,
            value: list?.[0].id,
            disabled: itemDisabled,
          },
        ];
        setOptions(res);
      });
    }
  }, [value, disabledUsers, mode, likeQueryUserById]);

  useEffect(() => {
    if (!currentUser || currentUser?.nameEn) {
      setUser(currentUser);
      return;
    }
    if (!_.isBoolean(likeQueryUserById)) {
      (likeQueryUserById as (ids: number[]) => Promise<{ data: { list: UserType[] } }>)?.([
        currentUser?.id,
      ])
        .then((resData) => {
          const {
            data: { list },
          } = resData;
          setUser(list[0]);
        })
        .catch((error) => {
          console.error(error);
        });
    }
  }, [currentUser, likeQueryUserById]);

  return (
    <Space.Compact block>
      <Select
        disabled={disabled}
        mode={mode}
        filterOption={false}
        showSearch={true}
        style={{ width: currentUser ? 'calc(100% - 64px)' : '100%' }}
        options={options}
        placeholder={placeholder || formatMessage({ id: 'component.UserSelect.placeholder' })}
        allowClear={true}
        onSearch={searchChange}
        value={mode ? valueIds : value}
        onChange={handleChange}
        dropdownRender={(menu) =>
          mode && showAllChecked ? (
            <>
              <Checkbox
                disabled={disabled}
                style={{ marginLeft: '8px' }}
                onChange={(e) => {
                  e.preventDefault();
                  if (e.target.checked) {
                    handleChange?.(options?.map((item) => item.value));
                  } else {
                    handleChange?.([]);
                  }
                }}
              >
                {formatMessage({ id: 'component.UserSelect.checkAll' })}
              </Checkbox>
              <Divider style={{ margin: '8px 0' }} />
              {menu}
            </>
          ) : (
            menu
          )
        }
      />
      {currentUser && (
        <Button
          style={{ width: '64px' }}
          disabled={disabled}
          type="primary"
          onClick={() => {
            handleChange(mode ? [user.id] : user.id);

            setOptions([
              {
                label: (
                  <div key={user.id} style={{ display: 'inline-block' }}>
                    {formatUserRender(
                      {
                        nameZh: user?.nameZh,
                        account: user?.nameEn,
                        id: user?.id,
                        state: user?.state,
                      },
                      false,
                      false,
                    )}
                  </div>
                ),
                key: user.id,
                value: user.id,
              },
            ]);
          }}
        >
          {formatMessage({ id: 'component.UserSelect.myself' })}
        </Button>
      )}
    </Space.Compact>
  );
};
export default memo(UserSelect);
