/**
 * orgs switch
 */
import PropTypes from 'prop-types';
import { useState, useRef, useMemo, useEffect } from 'react';
import { useDebounce, useInfiniteScroll, useMemoizedFn, useRequest } from 'ahooks';
import { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
import {
  Box,
  Button,
  Typography,
  Menu,
  MenuItem,
  TextField,
  Divider,
  Avatar,
  ListItemAvatar,
  ListItemText,
  InputAdornment,
} from '@mui/material';
import { joinURL, withQuery } from 'ufo';
import { KeyboardArrowDown, Search, Add, OpenInNew } from '@mui/icons-material';
import { translate } from '@arcblock/ux/lib/Locale/util';

import useOrg from './use-org';
import CreateOrgDialog from './create';
import translations from './locales';

const PAGE_SIZE = 20;

export default function OrgsSwitch({ session, locale = 'en' }) {
  const [anchorEl, setAnchorEl] = useState(null);
  const [searchText, setSearchText] = useState('');
  const [visible, setVisible] = useState(false);
  const buttonRef = useRef(null);

  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });

  const { getOrgs, getCurrentOrg } = useOrg(session);

  const role = useMemo(() => {
    return session?.user?.role || '';
  }, [session?.user?.role]);

  // 根据登录用户的 role 找到对应的 org
  const { data: loggedOrg = {} } = useRequest(
    () => {
      return getCurrentOrg(role);
    },
    {
      ready: !!role,
      refreshDeps: [role],
      onError: (error) => {
        console.error('Failed to get organization role', error);
      },
    }
  );

  const currentOrg = useMemo(() => {
    if (loggedOrg) {
      return loggedOrg;
    }
    const passport = session?.user?.passports?.find((p) => p.name === role);
    return {
      name: passport?.title || role || '-',
    };
  }, [loggedOrg, role, session?.user?.passports]);

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

  const { data, loadMore, loadingMore, reload } = useInfiniteScroll(
    async (d) => {
      const page = d ? Math.ceil(d.list.length / PAGE_SIZE) + 1 : 1;
      const params = { page, pageSize: PAGE_SIZE, search: searchText };
      const response = await getOrgs(params);

      const { orgs: resultOrgs = [], paging } = response || {};
      return { list: resultOrgs, total: paging?.total || 0 };
    },
    {
      ready: !!role,
      reloadDeps: [debouncedSearchText],
      isNoMore: (d) => {
        if (!d?.list.length) return true;
        return d.list.length >= d?.total;
      },
      onError: (error) => {
        console.error('Failed to fetch organizations list', error);
      },
    }
  );

  const { list: allOrgs = [], total = 0 } = data || {};

  const hasMore = allOrgs.length < total;

  // 处理滚动事件
  const handleListboxScroll = useMemoizedFn((event) => {
    const listbox = event.target;
    const { scrollTop, scrollHeight, clientHeight } = listbox;
    // 当滚动到距离底部50px时开始加载
    if (scrollHeight - scrollTop - clientHeight < 50 && !loadingMore && hasMore) {
      loadMore();
    }
  });

  const open = Boolean(anchorEl);

  useEffect(() => {
    if (open) {
      reload();
    }
  }, [open, reload]);

  const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
    setVisible(false);
    setSearchText('');
  };

  const handleOrgSelect = (org) => {
    session.switchPassport(
      () => {
        window.location.reload();
      },
      { orgId: org.id }
    );
    handleClose();
  };

  const handleCreateNew = () => {
    setVisible(true);
  };

  const handleViewAll = () => {
    const targetUrl = withQuery(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, 'user/orgs'), { locale });
    window.location.href = targetUrl;
    handleClose();
  };

  // 渲染组织项目
  const renderOrgItem = (org) => (
    <MenuItem
      key={org.id}
      onClick={() => handleOrgSelect(org)}
      selected={org.id === currentOrg.id}
      sx={{
        py: 1.5,
        px: 2,
        '&.Mui-selected': {
          backgroundColor: 'action.selected',
          '&:hover': {
            backgroundColor: 'action.hover',
          },
        },
      }}>
      <ListItemAvatar sx={{ minWidth: 40 }}>
        <Avatar
          sx={{
            width: 28,
            height: 28,
            fontSize: 14,
            bgcolor: org.isOwner ? 'primary.main' : 'grey.400',
          }}>
          {org.name?.[0]}
        </Avatar>
      </ListItemAvatar>
      <Box sx={{ display: 'flex', alignItems: 'center', flex: 1 }}>
        <ListItemText
          sx={{
            '& .MuiListItemText-primary': {
              mb: 0,
            },
            '& .MuiListItemText-secondary': {
              mt: '-2px',
            },
          }}
          primary={
            <Typography variant="body2" sx={{ fontWeight: 500, lineHeight: 1.2 }}>
              {org.name}
            </Typography>
          }
          secondary={
            <Typography variant="caption" color="text.secondary" sx={{ lineHeight: 1.1 }}>
              {org.passports?.[0]?.title}
            </Typography>
          }
        />
        {org.id === currentOrg.id && (
          <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', ml: 1 }}>
            <Typography variant="caption" color="primary" sx={{ fontSize: 10 }}>
              ✓
            </Typography>
          </Box>
        )}
      </Box>
    </MenuItem>
  );

  return (
    <Box>
      <Button
        ref={buttonRef}
        onClick={handleClick}
        endIcon={<KeyboardArrowDown />}
        sx={{
          display: 'flex',
          alignItems: 'center',
          gap: 1,
          px: 2,
          py: 1,
          borderRadius: 1,
          textTransform: 'none',
          color: 'text.primary',
          '&:hover': {
            backgroundColor: 'action.hover',
          },
        }}
        data-testid="org-switch-button">
        <Avatar
          sx={{
            width: 24,
            height: 24,
            fontSize: 12,
            bgcolor: 'primary.main',
          }}>
          {currentOrg.name?.[0]}
        </Avatar>
        <Typography variant="body2" sx={{ fontWeight: 500 }}>
          {currentOrg.name}
        </Typography>
      </Button>

      <Menu
        anchorEl={anchorEl}
        open={open}
        onClose={handleClose}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'left',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'left',
        }}
        PaperProps={{
          sx: {
            width: 340,
            maxHeight: 480,
            overflow: 'visible',
            mt: 0.5,
            borderRadius: 2,
            boxShadow: '0px 4px 20px rgba(0, 0, 0, 0.08)',
            border: (theme) => `1px solid ${theme.palette.divider}`,
          },
        }}
        MenuListProps={{
          sx: { py: 0 },
        }}>
        {/* 搜索框 */}
        <Box sx={{ p: 1.5, pb: 1 }}>
          <TextField
            fullWidth
            size="small"
            placeholder={t('search')}
            value={searchText}
            onChange={(e) => setSearchText(e.target.value)}
            InputProps={{
              startAdornment: (
                <InputAdornment position="start">
                  <Search fontSize="small" color="action" />
                </InputAdornment>
              ),
            }}
            onClick={(e) => e.stopPropagation()}
            onKeyDown={(e) => e.stopPropagation()}
            sx={{
              '& .MuiOutlinedInput-root': {
                borderRadius: 1,
              },
            }}
          />
        </Box>

        {/* 组织标题 */}
        <Box sx={{ px: 2, pb: 1 }}>
          <Typography
            variant="subtitle2"
            color="text.secondary"
            sx={{
              fontSize: 11,
              fontWeight: 600,
              textTransform: 'uppercase',
              letterSpacing: 0.5,
            }}>
            {t('orgs')}
          </Typography>
        </Box>

        {/* 组织列表 */}
        <Box sx={{ maxHeight: 240, overflow: 'auto' }} onScroll={handleListboxScroll}>
          {allOrgs.length > 0 ? (
            <>
              {allOrgs.map((org, index) => {
                const isLast = index === allOrgs.length - 1;
                return (
                  <Box key={org.id}>
                    {renderOrgItem(org)}
                    {/* 加载更多指示器 */}
                    {isLast && hasMore && (
                      <Box
                        sx={{
                          display: 'flex',
                          justifyContent: 'center',
                          py: 1,
                          color: 'text.secondary',
                          fontSize: '0.875rem',
                        }}>
                        {loadingMore ? t('loadingMore') : ''}
                      </Box>
                    )}
                  </Box>
                );
              })}
            </>
          ) : (
            <Box sx={{ px: 2, py: 3, textAlign: 'center' }}>
              <Typography variant="body2" color="text.secondary">
                {t('myJoinedEmpty')}
              </Typography>
            </Box>
          )}
        </Box>

        <Divider />

        {/* 创建新组织 */}
        <MenuItem
          onClick={handleCreateNew}
          sx={{
            py: 1.5,
            px: 2,
            '&:hover': {
              backgroundColor: 'action.hover',
            },
          }}>
          <ListItemAvatar sx={{ minWidth: 40 }}>
            <Avatar
              sx={{
                width: 28,
                height: 28,
                bgcolor: 'success.main',
                color: 'success.contrastText',
              }}>
              <Add fontSize="small" />
            </Avatar>
          </ListItemAvatar>
          <ListItemText
            primary={
              <Typography variant="body2" sx={{ fontWeight: 500 }}>
                {t('createNew')}
              </Typography>
            }
          />
        </MenuItem>

        <Divider />

        {/* 查看所有组织链接 */}
        <Box sx={{ p: 1.5 }}>
          <Button
            onClick={handleViewAll}
            variant="text"
            component="a"
            size="small"
            endIcon={<OpenInNew fontSize="small" />}
            sx={{
              color: 'primary.main',
              fontWeight: 500,
              p: 0,
              fontSize: 14,
              minWidth: 'auto',
              '&:hover': {
                backgroundColor: 'transparent',
                textDecoration: 'underline',
              },
            }}>
            {t('viewAll')}
          </Button>
        </Box>
      </Menu>

      {visible && <CreateOrgDialog onSuccess={handleViewAll} onCancel={() => setVisible(false)} locale={locale} />}
    </Box>
  );
}

OrgsSwitch.propTypes = {
  session: PropTypes.object.isRequired,
  locale: PropTypes.string,
};
