import { ChangeEvent, useMemo, useState } from 'react';
import { Box, Button, FormControl, IconButton, styled, TextField, Typography, useTheme } from '@mui/material';
import { Remove as RemoveIcon, Add as AddIcon } from '@mui/icons-material';
import { translate } from '@arcblock/ux/lib/Locale/util';
import { useMemoizedFn } from 'ahooks';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import LinkIcon from '@arcblock/icons/lib/Link';
import { mergeSx } from '@arcblock/ux/lib/Util/style';
import { withoutProtocol } from 'ufo';
import { Icon } from '@iconify/react';
import { getLogoByUrl, isDuplicateUrl, isValidUrl } from './utils';
import { translations } from '../../libs/locales';
import { commonInputStyle, inputFieldStyle } from '../editable-field';

const MAX_LINK_COUNT = 10;

/**
 * 格式化链接显示
 * 对于 http/https 协议只显示域名，其他协议显示完整链接
 */
function formatLinkDisplay(link: string): string {
  return withoutProtocol(link);
}

/**
 * 链接预览输入框
 */
function LinkInput({
  value,
  onChange,
  errorMsg,
}: {
  value: string;
  onChange: (value: string) => void;
  errorMsg: string;
}) {
  const handleUrlChange = (event: ChangeEvent<HTMLInputElement>) => {
    const inputValue = event.target.value;
    onChange(inputValue);
  };

  return (
    <FormControl fullWidth>
      <TextField
        variant="outlined"
        value={value}
        onChange={handleUrlChange}
        fullWidth
        error={!!errorMsg}
        helperText={errorMsg}
        sx={mergeSx(inputFieldStyle, !errorMsg ? commonInputStyle : {})}
      />
    </FormControl>
  );
}

/**
 * 动态链接输入框
 */
function DynamicLinkForm({ links = [], onChange }: { links?: string[]; onChange: (links: string[]) => void }) {
  const { locale } = useLocaleContext();
  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });
  const [errors, setErrors] = useState<(boolean | string)[]>(['']); // 记录 URL 输入错误状态

  const isLastError = useMemo(() => {
    const lastLink = links[links.length - 1];
    return !isValidUrl(lastLink) || (errors.length > 0 && errors[errors.length - 1]);
  }, [errors, links]);

  const handleAddLink = () => {
    if (links.length < MAX_LINK_COUNT || !isLastError) {
      onChange([...links, '']);
    }
  };

  // 删除指定索引的输入框
  const handleRemoveLink = (index: number) => {
    const updatedLinks = links.filter((_, i) => i !== index);
    const updatedErrors = errors.filter((_, i) => i !== index);
    setErrors(updatedErrors);
    onChange(updatedLinks);
  };

  // 处理输入框变化
  const handleInputChange = (index: number, value: string) => {
    const updatedLinks = [...links];
    updatedLinks[index] = value;

    // 校验 URL 是否有效
    const updatedErrors = [...errors];
    const isInvalidUrl = !!(value && !isValidUrl(value));
    updatedErrors[index] = false;
    // 如果 URL 有效，则校验是否重复
    if (!isInvalidUrl) {
      const validLinks = updatedLinks.filter((l, i) => l && isValidUrl(l) && i !== index);
      const isDuplicate = validLinks.some((v) => isDuplicateUrl(v, value));
      if (isDuplicate) {
        updatedErrors[index] = 'duplicate';
      }
    } else {
      updatedErrors[index] = isInvalidUrl; // 如果有输入但格式错误，标记错误
    }
    setErrors(updatedErrors);
    onChange(updatedLinks);
  };

  return (
    <Box
      sx={{
        width: '100%',
      }}>
      <Box
        sx={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          gap: 1,
        }}>
        <Typography variant="subtitle1" gutterBottom sx={{ mb: 0, fontSize: '12px', color: 'text.primary' }}>
          {t('profile.socialMedia')}
        </Typography>
      </Box>
      {links.map((link, index) => {
        let errorMsg = '';
        if (errors[index] === 'duplicate') {
          errorMsg = t('profile.duplicateURL');
        } else if (errors[index] === true) {
          errorMsg = t('profile.invalidURL');
        } else {
          errorMsg = '';
        }
        return (
          <Box
            // eslint-disable-next-line react/no-array-index-key
            key={index}
            sx={{
              display: 'flex',
              alignItems: 'flex-start',
              mb: 1,
            }}>
            <LinkInput value={link} onChange={(value) => handleInputChange(index, value)} errorMsg={errorMsg} />
            <IconButton onClick={() => handleRemoveLink(index)}>
              <RemoveIcon sx={{ color: 'text.secondary' }} />
            </IconButton>
          </Box>
        );
      })}
      {links.length < MAX_LINK_COUNT ? (
        <Button
          fullWidth
          variant="outlined"
          disabled={!!isLastError}
          onClick={handleAddLink}
          size="small"
          sx={{
            height: '40px',
            border: '1px dashed',
            borderColor: 'grey.100',
            color: 'text.primary',
            '&:hover': {
              borderColor: 'grey.100',
              backgroundColor: 'action.hover',
            },
            '&.Mui-disabled': {
              borderStyle: 'dashed',
            },
          }}>
          <AddIcon /> <span>{t('profile.addLink')}</span>
        </Button>
      ) : (
        <Typography variant="subtitle1" gutterBottom sx={{ mb: 0, fontSize: '12px', color: 'text.secondary' }}>
          {t('profile.maxLinkCount', { count: MAX_LINK_COUNT })}
        </Typography>
      )}
    </Box>
  );
}

/**
 * favicon 预览
 */
function FaviconPreview({ link }: { link: string }) {
  const theme = useTheme();
  const isDark = theme.palette.mode === 'dark';

  if (!link) {
    return null;
  }

  const { icon: logoIcon, options } = getLogoByUrl(link) || {};

  if (logoIcon) {
    return (
      <Icon
        icon={logoIcon}
        width={20}
        height={20}
        style={{
          filter: isDark && !options?.skipDarkInvert ? 'brightness(0) saturate(100%) invert(1)' : 'none',
          transform: 'scale(0.8)',
        }}
        {...options}
      />
    );
  }

  return (
    <LinkIcon width={20} height={20} style={{ filter: isDark ? 'brightness(0) saturate(100%) invert(1)' : 'none' }} />
  );
}

export function LinkPreviewInput({
  editable = false,
  links = [],
  onChange,
}: {
  editable?: boolean;
  links?: string[];
  onChange: (links: string[]) => void;
}) {
  if (editable) {
    return <DynamicLinkForm links={links} onChange={onChange} />;
  }

  return (
    <Box
      sx={{
        width: '100%',
        display: 'flex',
        flexDirection: 'column',
        gap: 2,
      }}>
      {links.map((link) => (
        <Box
          key={link}
          sx={{
            display: 'flex',
            alignItems: 'center',
            gap: 1,
            overflow: 'hidden',
            width: '100%',
          }}>
          <FaviconPreview link={link} />
          <LinkDiv>
            <Box component="a" href={link} style={{ textDecoration: 'none' }} target="_blank" rel="noopener noreferrer">
              {formatLinkDisplay(link)}
            </Box>
          </LinkDiv>
        </Box>
      ))}
    </Box>
  );
}

const LinkDiv = styled('span')`
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  &,
  & > * {
    color: ${({ theme }) => theme.palette.text.primary};
  }

  & > * {
    word-break: break-all;
  }

  .status {
    margin-left: 8px;
  }
`;
