/**
 * Org transfer selector
 */
import { useImperativeHandle, useState } from 'react';
import { useReactive, useDebounce, useInfiniteScroll, useMemoizedFn } from 'ahooks';
import { Button, Typography, Box, Autocomplete, TextField, CircularProgress } from '@mui/material';
import { AxiosError } from 'axios';
import Toast from '../Toast';
import Dialog from '../Dialog';
import { Org, OrgTransferSelectorProps } from './type';
import { client, OrgQueryType } from '../Util/client';
import { formatAxiosError } from '../Util';
import { translate } from '../Locale/util';
import translations from './locales';

const PAGE_SIZE = 20;

export default function OrgTransferSelector({
  ref,
  org,
  onSuccess,
  resourceId,
  locale = 'en',
  dialogProps,
}: OrgTransferSelectorProps) {
  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });
  const [searchText, setSearchText] = useState('');

  const state = useReactive<{
    open: boolean;
    selectedOrg: Org | null;
  }>({
    open: false,
    selectedOrg: null,
  });

  const debouncedSearchText = useDebounce(searchText, { wait: 500 });

  const { data, loadMore, loadingMore, loading, reload } = useInfiniteScroll(
    async (d) => {
      // 只有对话框打开时才发起请求
      if (!state.open) return { list: [], total: 0 };

      const page = d ? Math.ceil(d.list.length / PAGE_SIZE) + 1 : 1;
      const params = { page, pageSize: PAGE_SIZE, search: debouncedSearchText, type: OrgQueryType.OWNED };
      const response = await client.user.getOrgs(params);

      const { orgs: resultOrgs = [], paging } = response || {};
      return { list: resultOrgs, total: paging?.total || 0 };
    },
    {
      reloadDeps: [debouncedSearchText],
      isNoMore: (d) => {
        if (!d?.list.length) return true;
        return d.list.length >= d?.total;
      },
      onError: (error) => {
        // eslint-disable-next-line no-console
        console.error('Get orgs failed', error);
      },
      manual: true, // 手动触发，在对话框打开时再加载
    }
  );

  const handleClose = useMemoizedFn(() => {
    state.open = false;
    state.selectedOrg = null;
    setSearchText(''); // 关闭时重置搜索
  });

  const handleConfirm = useMemoizedFn(async () => {
    try {
      if (!resourceId) {
        throw new Error(t('resourceIdRequired'));
      }
      if (!state.selectedOrg) {
        throw new Error(t('placeholder'));
      }
      if (state.selectedOrg.id === org.id) {
        throw new Error(t('organizationSameAsCurrent'));
      }
      await client.user.migrateResourceToOrg({ form: org.id, to: state.selectedOrg.id, resourceId });
      handleClose();
      onSuccess?.(state.selectedOrg);
      Toast.success(t('tranferSuccess'));
    } catch (error) {
      console.error('Resource transfer failed', error);
      Toast.error(formatAxiosError(error as AxiosError));
    }
  });

  useImperativeHandle(ref, () => ({
    open: (options = {}) => {
      Object.assign(state, { open: true, selectedOrg: null }, options);
      // 对话框打开时重新加载数据
      setTimeout(() => {
        if (state.open) {
          reload();
        }
      }, 0);
    },
    close: handleClose,
  }));

  const organizations = data?.list || [];
  // const hasMore = data ? data.list.length < data.total : false;

  const { placeholder = '', ...rest } = dialogProps || {};
  return (
    <Dialog
      title={t('transferOrg')}
      fullWidth
      maxWidth="sm"
      open={state.open}
      onClose={handleClose}
      actions={
        <>
          <Button onClick={handleClose} color="secondary" variant="outlined">
            {t('cancel')}
          </Button>
          <Button onClick={handleConfirm} color="primary" variant="contained" disabled={!state.selectedOrg}>
            {t('confirm')}
          </Button>
        </>
      }
      {...(rest || {})}>
      <Box>
        <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
          {placeholder || t('placeholder')}
        </Typography>

        <Autocomplete
          options={organizations}
          getOptionLabel={(option) => option?.name || ''}
          isOptionEqualToValue={(option, value) => option?.id === value?.id}
          value={state.selectedOrg}
          onChange={(_, newValue) => {
            // 如果点击的是加载项，触发加载更多
            if (newValue?.isLoadingItem && !loadingMore) {
              loadMore();
              return;
            }
            // 忽略加载项的选择
            if (newValue?.isLoadingItem) {
              return;
            }
            state.selectedOrg = newValue;
            // 选择选项后清空搜索文本
            if (newValue) {
              setSearchText('');
            }
          }}
          inputValue={state.selectedOrg ? state.selectedOrg.name : searchText}
          onInputChange={(_, newInputValue, reason) => {
            // 只有用户键盘输入时才更新搜索文本
            if (reason === 'input') {
              // 用户开始输入时，清除当前选中的组织，进入搜索模式
              if (state.selectedOrg) {
                state.selectedOrg = null;
              }
              setSearchText(newInputValue);
            }
          }}
          loading={loading}
          loadingText={t('loading')}
          noOptionsText={loading ? t('loading') : t('noResults')}
          renderInput={(params) => (
            <TextField
              {...params}
              variant="outlined"
              fullWidth
              InputProps={{
                ...params.InputProps,
                endAdornment: (
                  <>
                    {loading && <CircularProgress color="inherit" size={20} />}
                    {params.InputProps.endAdornment}
                  </>
                ),
              }}
            />
          )}
          renderOption={(props, option) => {
            // 特殊处理加载项
            if (option.isLoadingItem) {
              return (
                <Box component="li" {...props} key={option.id}>
                  <Box
                    sx={{
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      flex: 1,
                      py: 1,
                      color: 'primary.main',
                      cursor: 'pointer',
                    }}>
                    {loadingMore && <CircularProgress size={16} sx={{ mr: 1 }} />}
                    <Typography variant="body2" sx={{ fontStyle: loadingMore ? 'italic' : 'normal' }}>
                      {option.name}
                    </Typography>
                  </Box>
                </Box>
              );
            }

            // 正常组织项的渲染
            return (
              <Box component="li" {...props} key={option.id}>
                <Box sx={{ display: 'flex', flexDirection: 'column', flex: 1, minWidth: 0 }}>
                  <Typography
                    variant="body1"
                    sx={{
                      overflow: 'hidden',
                      textOverflow: 'ellipsis',
                      whiteSpace: 'nowrap',
                    }}>
                    {option.name}
                  </Typography>
                  {option.description && (
                    <Typography
                      variant="body2"
                      color="text.secondary"
                      sx={{
                        display: '-webkit-box',
                        WebkitLineClamp: 3,
                        WebkitBoxOrient: 'vertical',
                        overflow: 'hidden',
                        textOverflow: 'ellipsis',
                      }}>
                      {option.description}
                    </Typography>
                  )}
                </Box>
              </Box>
            );
          }}
          sx={{
            '& .MuiAutocomplete-listbox': {
              maxHeight: 200,
            },
          }}
        />
      </Box>
    </Dialog>
  );
}
