import { Box, Button, Typography, Chip, List, ListItem } from '@mui/material';
import { Icon } from '@iconify/react';
import externalLinkIcon from '@iconify-icons/tabler/external-link';
import lockOutlineIcon from '@iconify-icons/material-symbols/lock-outline';
import checkCircleIcon from '@iconify-icons/material-symbols/check-circle';
import rocketLaunchRoundedIcon from '@iconify-icons/material-symbols/rocket-launch-rounded';
import { useMemoizedFn, useReactive } from 'ahooks';
import { memo, useImperativeHandle, useRef } from 'react';
import noop from 'lodash/noop';

import { Locale } from '../type';
import { translate } from '../Locale/util';
import DIDConnectContainer from './did-connect-container';
import CloseButton from '../CloseButton';
import SharedBridge from '../SharedBridge';
import { setVisitorId } from '../Util';

type StorageAccessState = 'prompt' | 'granted' | 'denied';

const translations: Record<
  Locale,
  {
    allow: string;
    dataUsage: string;
    title: string;
    clickAllow: ({ allowButton }: { allowButton: React.ReactNode }) => React.ReactNode;
    reason: ({ site }: { site: React.ReactNode }) => React.ReactNode;
    afterAllow: {
      title: string;
      list1: string;
      list2: string;
    };
  }
> = {
  en: {
    allow: 'Allow',
    dataUsage:
      'Your data is only used for identity authentication, and will not be collected or used for any other purpose.',
    title: 'Authorization Request',
    clickAllow: ({ allowButton }: { allowButton: React.ReactNode }) => {
      return <>You only need to click the {allowButton} button below, and you will not see this request again.</>;
    },
    reason: ({ site }) => {
      return <>For a better login experience, we need to apply for the storage permission of the {site} site.</>;
    },
    afterAllow: {
      title: 'After authorization, you will enjoy:',
      list1: 'More convenient login experience',
      list2: 'Faster access speed',
    },
  },
  zh: {
    allow: '允许',
    dataUsage: '您的数据仅用于身份认证，不会被收集或用于其他用途。',
    title: '授权请求',
    clickAllow: ({ allowButton }) => {
      return <>您只需要点击下方的 {allowButton} 按钮，后续将不会再看到这个请求。</>;
    },
    reason: ({ site }) => {
      return <>为了让您获得更好的登录体验，我们需要申请 {site} 站点存储权限。</>;
    },
    afterAllow: {
      title: '授权后，您将享受：',
      list1: '更便捷的登录体验',
      list2: '更快的访问速度',
    },
  },
};

function RequestStorageAccessApiDialog({
  ref = undefined,
  locale = 'en',
  src,
  storageAccessState,
}: {
  locale?: Locale;
  src: string;
  storageAccessState: StorageAccessState;
} & {
  ref?: React.Ref<unknown>;
}) {
  const sharedBridgeRef = useRef<{ callIframe: (method: string) => Promise<any> }>(null);
  const currentState = useReactive({
    callback: noop,
    open: false,
    get origin() {
      try {
        return new URL(src).origin;
      } catch (error) {
        return src;
      }
    },
    get host() {
      try {
        return new URL(src).host;
      } catch (error) {
        return src;
      }
    },
  });
  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });

  const reset = useMemoizedFn(() => {
    currentState.open = false;
    currentState.callback = noop;
  });

  const open = useMemoizedFn(() => {
    currentState.open = true;
  });
  const close = useMemoizedFn(() => {
    currentState.open = false;
  });

  const _requestStorageAccess = useMemoizedFn(
    async (callback: (result: boolean, origin?: 'broswer' | 'system') => void) => {
      const result = await sharedBridgeRef.current?.callIframe('requestStorageAccess');
      if (result.value) {
        callback(true, 'broswer');
      } else if (storageAccessState === undefined) {
        // 用户未在当前网页交互过，此时必然需要进行一次弹窗
        callback(false, 'system');
      } else if (storageAccessState === 'denied') {
        // 用户已经明确拒绝过跨站授权，直接弹窗
        callback(false);
      } else {
        // NOTICE: 暂时保留这部分逻辑，后续可能会用上
        // else if (
        //   result.error?.name === 'NotAllowedError' &&
        //   result.error?.message === 'requestStorageAccess not allowed'
        // ) {
        //   // 操作被浏览器禁止，需要用户手动与 iframe 交互一次才可以
        //   currentState.open = true;
        //   currentState.callback = callback;
        // }
        currentState.open = true;
        currentState.callback = callback;
      }
    }
  );
  const requestStorageAccess = useMemoizedFn(() => {
    return new Promise((resolve) => {
      _requestStorageAccess((result, origin) => {
        reset();
        resolve({ value: result, origin });
      });
    });
  });

  const handleAllow = useMemoizedFn(() => {
    currentState.open = false;
  });
  const handleClose = useMemoizedFn(() => {
    currentState.open = false;
    currentState.callback(false, 'system');
  });

  useImperativeHandle(ref, () => ({
    open,
    close,
    requestStorageAccess,
  }));

  return (
    <DIDConnectContainer popup open={currentState.open} onClose={handleClose} keepMounted>
      <Box
        sx={{
          backgroundColor: 'background.default',
          display: 'flex',
          flexDirection: 'column',
          height: '100%',
          position: 'relative',
          maxWidth: '100%',
          transition: 'width 0.2s ease-in-out',
          margin: 'auto',
          p: 3,
          gap: 2,
        }}>
        <CloseButton
          onClose={handleClose}
          sx={{
            position: 'absolute',
            right: 14,
            top: 14,
          }}
        />
        <Typography
          component="div"
          variant="h4"
          sx={{
            fontWeight: 700,
            fontFamily: 'Lexend',
            display: 'flex',
            alignItems: 'center',
            gap: 1,
          }}>
          <Box
            component={Icon}
            icon={lockOutlineIcon}
            sx={{
              fontSize: 28,
              color: 'warning.main',
            }}
          />
          {t('title')}
        </Typography>
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
          {/* 不需要随意更改以下内容的格式化，否则会影响到 UI 的展示 */}
          <Typography>
            {t('reason', {
              site: (
                <Chip
                  clickable
                  component="a"
                  href={currentState.origin}
                  label={currentState.host}
                  size="small"
                  deleteIcon={<Icon icon={externalLinkIcon} />}
                  onDelete={() => {}}
                  target="_blank"
                />
              ),
            })}
          </Typography>
          <Typography component="div">
            {t('clickAllow', {
              allowButton: <Chip label={t('allow')} size="small" color="success" />,
            })}
          </Typography>
          <Box sx={{ mt: 2 }}>
            <Typography sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}>
              <Box
                component={Icon}
                icon={checkCircleIcon}
                sx={{
                  fontSize: 24,
                  color: 'success.main',
                }}
              />
              {t('afterAllow.title')}
            </Typography>
            <List dense sx={{ py: 0, pl: 2 }}>
              <ListItem sx={{ display: 'flex', alignItems: 'center', gap: 0.8 }}>
                <Box
                  component={Icon}
                  icon={rocketLaunchRoundedIcon}
                  sx={{
                    fontSize: 20,
                    color: 'success.main',
                  }}
                />
                {t('afterAllow.list1')}
              </ListItem>
              <ListItem sx={{ display: 'flex', alignItems: 'center', gap: 0.8 }}>
                <Box
                  component={Icon}
                  icon={rocketLaunchRoundedIcon}
                  sx={{
                    fontSize: 20,
                    color: 'success.main',
                  }}
                />
                {t('afterAllow.list2')}
              </ListItem>
            </List>
          </Box>

          <Typography
            component="div"
            variant="body2"
            sx={{
              color: 'grey.700',
            }}>
            {t('dataUsage')}
          </Typography>
        </Box>

        <Box sx={{ display: 'flex', justifyContent: 'center' }}>
          <Box sx={{ position: 'relative', display: 'inline-block', cursor: 'pointer' }}>
            <Button variant="contained" color="success" onClick={handleAllow} sx={{ minWidth: 100, letterSpacing: 1 }}>
              {t('allow')}
            </Button>
            <SharedBridge
              ref={sharedBridgeRef}
              onClick={({ value, visitorId }) => {
                if (visitorId) setVisitorId(visitorId);

                currentState.callback(value, 'broswer');
              }}
              src={src}
              sx={{
                zIndex: 1,
              }}
            />
          </Box>
        </Box>
      </Box>
    </DIDConnectContainer>
  );
}

export default memo(RequestStorageAccessApiDialog);
