import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { Box, LinearProgress, Skeleton, Typography } from '@mui/material';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Check } from '@mui/icons-material';

export function VendorPlaceholder() {
  return (
    <Box sx={{ mb: 2 }}>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
        <Skeleton variant="rounded" height={16} width={150} />
        <Skeleton variant="rounded" height={16} width={50} />
      </Box>
      <Skeleton variant="rounded" height={8} width="100%" />
    </Box>
  );
}

interface VendorStatus {
  success: boolean;
  name?: string;
  key?: string;
  status: 'delivered' | 'pending' | 'failed';
  progress: number;
  message: string;
  appUrl?: string;
  title?: string;
  vendorType: string;
}

const getVendorLabel = (vendor: VendorStatus, isFailed: boolean, t: any) => {
  const name = vendor.name || vendor.title;
  const isCompleted = vendor.status === 'delivered';

  if (vendor.vendorType === 'didnames') {
    if (isFailed) {
      return t('payment.checkout.vendor.didnames.failed', { name });
    }
    if (isCompleted) {
      return t('payment.checkout.vendor.didnames.completed', { name });
    }
    return t('payment.checkout.vendor.didnames.processing', { name });
  }

  // Default to launcher type
  if (isFailed) {
    return t('payment.checkout.vendor.launcher.failed', { name });
  }
  if (isCompleted) {
    return t('payment.checkout.vendor.launcher.completed', { name });
  }
  return t('payment.checkout.vendor.launcher.processing', { name });
};

export function VendorProgressItem({ vendor }: { vendor: VendorStatus }) {
  const { t } = useLocaleContext();
  const [displayProgress, setDisplayProgress] = useState(0);
  const animationRef = useRef<number>();

  const startAnimation = useCallback(() => {
    const realProgress = vendor.progress || 0;
    let startTime: number;
    let startProgress: number;

    const animate = (currentTime: number) => {
      if (!startTime) {
        startTime = currentTime;
        startProgress = displayProgress;
      }

      const elapsed = currentTime - startTime;
      let newProgress: number;

      if (realProgress === 100) {
        // If progress is 100%, set directly to 100% without animation
        newProgress = 100;
      } else if (realProgress === 0) {
        // When no data available, increase 1% per second
        newProgress = Math.min(startProgress + elapsed / 1000, 99);
      } else if (realProgress > startProgress) {
        const duration = 1000; // 1 second to reach target quickly
        const progress = Math.min(elapsed / duration, 1);
        newProgress = startProgress + (realProgress - startProgress) * progress;
      } else {
        // After reaching target, increase 1% per second, max 99%
        newProgress = Math.min(startProgress + elapsed / 1000, 99);
      }

      // Ensure progress is an integer
      newProgress = Math.round(newProgress);
      setDisplayProgress((pre) => Math.min(pre > newProgress ? pre : newProgress, 100));

      // Stop animation immediately when 100%
      if (realProgress === 100) {
        return;
      }

      // Continue animation in other cases
      if (newProgress < 99 && realProgress < 100) {
        animationRef.current = requestAnimationFrame(animate);
      }
    };

    if (animationRef.current) {
      cancelAnimationFrame(animationRef.current);
    }
    animationRef.current = requestAnimationFrame(animate);
  }, [vendor.progress, displayProgress]);

  useEffect(() => {
    startAnimation();
    return () => {
      if (animationRef.current) {
        cancelAnimationFrame(animationRef.current);
      }
    };
  }, [startAnimation]);

  const isCompleted = displayProgress >= 100;
  const isFailed = vendor.status === 'failed';

  const nameText = getVendorLabel(vendor, isFailed, t);

  // 如果是失败状态，显示错误 UI
  if (isFailed) {
    return (
      <Box sx={{ mb: 2 }}>
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {nameText}
          </Typography>
          <Typography variant="body2" sx={{ color: 'error.main', fontWeight: 500 }}>
            {t('payment.checkout.vendor.progress', { progress: 0 })}
          </Typography>
        </Box>
        <LinearProgress
          variant="determinate"
          value={100}
          sx={{
            height: 8,
            borderRadius: 4,
            backgroundColor: 'grey.200',
            '& .MuiLinearProgress-bar': {
              borderRadius: 4,
              backgroundColor: 'error.main',
            },
          }}
        />
      </Box>
    );
  }

  if (!vendor.name && !vendor.title) {
    return <VendorPlaceholder />;
  }

  return (
    <Box sx={{ mb: 2 }}>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
        <Typography variant="body2" sx={{ color: 'text.secondary', display: 'flex', alignItems: 'center' }}>
          {nameText} {isCompleted ? <Check sx={{ color: 'success.main', ml: 0.5 }} fontSize="small" /> : null}
        </Typography>
        {isCompleted ? null : (
          <Typography variant="body2" sx={{ color: 'text.secondary', fontWeight: 500 }}>
            {t('payment.checkout.vendor.progress', { progress: displayProgress })}
          </Typography>
        )}
      </Box>
      <LinearProgress
        variant="determinate"
        value={displayProgress || 0}
        sx={{
          height: 8,
          borderRadius: 4,
          backgroundColor: 'grey.200',
          '& .MuiLinearProgress-bar': {
            borderRadius: 4,
            backgroundColor: isCompleted ? 'success.main' : 'primary.main',
            transition: 'background-color 0.3s linear',
          },
        }}
      />
    </Box>
  );
}
