import React, { Component, ErrorInfo, ReactNode } from 'react';
import { Box, Button, Heading, Text, VStack, Icon, Code } from '@chakra-ui/react';
import { FiAlertTriangle, FiRefreshCw } from 'react-icons/fi';

interface Props {
  children: ReactNode;
  onReset?: () => void;
}

interface State {
  hasError: boolean;
  error: Error | null;
  errorInfo: ErrorInfo | null;
  errorCount: number;
}

/**
 * Error boundary specifically for MyUIbrix editor to catch DOM manipulation errors
 */
class MyUIbrixErrorBoundary extends Component<Props, State> {
  private resetTimeout: NodeJS.Timeout | null = null;

  constructor(props: Props) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      errorInfo: null,
      errorCount: 0,
    };
  }

  static getDerivedStateFromError(error: Error): Partial<State> {
    // Update state so the next render will show the fallback UI
    return {
      hasError: true,
      error,
    };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // Log error details for debugging
    console.error('MyUIbrix Error Boundary caught an error:', error, errorInfo);
    
    this.setState(prev => ({
      errorInfo,
      errorCount: prev.errorCount + 1,
    }));

    // Auto-reset after 3 seconds for DOM manipulation errors
    if (
      error.message.includes('removeChild') ||
      error.message.includes('insertBefore') ||
      error.message.includes('replaceChild') ||
      error.name === 'DOMException'
    ) {
      console.warn('DOM manipulation error detected - will auto-reset in 3 seconds');
      this.scheduleAutoReset();
    }
  }

  componentWillUnmount() {
    if (this.resetTimeout) {
      clearTimeout(this.resetTimeout);
    }
  }

  scheduleAutoReset = () => {
    if (this.resetTimeout) {
      clearTimeout(this.resetTimeout);
    }
    
    this.resetTimeout = setTimeout(() => {
      this.handleReset();
    }, 3000);
  };

  handleReset = () => {
    if (this.resetTimeout) {
      clearTimeout(this.resetTimeout);
      this.resetTimeout = null;
    }

    // Clean up any orphaned DOM elements
    this.cleanupDOMElements();

    this.setState({
      hasError: false,
      error: null,
      errorInfo: null,
    });

    // Call parent reset handler if provided
    if (this.props.onReset) {
      this.props.onReset();
    }
  };

  cleanupDOMElements = () => {
    try {
      // Remove all MyUIbrix overlays
      document.querySelectorAll('.elementor-overlay').forEach(el => {
        try {
          el.remove();
        } catch (e) {
          console.warn('Failed to remove overlay:', e);
        }
      });

      // Remove viewport wrapper if exists
      const wrapper = document.querySelector('.myuibrix-viewport-wrapper');
      if (wrapper && wrapper.parentElement) {
        try {
          const parent = wrapper.parentElement;
          Array.from(wrapper.children).forEach(child => {
            try {
              parent.appendChild(child);
            } catch (e) {
              console.warn('Failed to move child:', e);
            }
          });
          wrapper.remove();
        } catch (e) {
          console.warn('Failed to cleanup viewport wrapper:', e);
        }
      }

      // Reset body styles
      document.body.style.paddingTop = '0';
      document.body.style.backgroundColor = '';
      document.body.style.userSelect = '';
    } catch (e) {
      console.error('Error during DOM cleanup:', e);
    }
  };

  render() {
    if (this.state.hasError && this.state.error) {
      const isDOMError = 
        this.state.error.message.includes('removeChild') ||
        this.state.error.message.includes('insertBefore') ||
        this.state.error.message.includes('replaceChild') ||
        this.state.error.name === 'DOMException';

      return (
        <Box
          position="fixed"
          top="0"
          left="0"
          right="0"
          bottom="0"
          bg="rgba(0, 0, 0, 0.85)"
          backdropFilter="blur(8px)"
          display="flex"
          alignItems="center"
          justifyContent="center"
          zIndex={99999}
        >
          <VStack
            spacing={6}
            bg="white"
            p={8}
            borderRadius="2xl"
            boxShadow="0 20px 60px rgba(0,0,0,0.5)"
            maxW="600px"
            w="90%"
          >
            <Icon as={FiAlertTriangle} boxSize={16} color="orange.500" />
            
            <VStack spacing={2}>
              <Heading size="lg" color="gray.800">
                {isDOMError ? 'Chyba při manipulaci s prvky' : 'Chyba editoru'}
              </Heading>
              <Text color="gray.600" textAlign="center">
                {isDOMError 
                  ? 'Nastala chyba při přesouvání nebo upravování prvků. Editor se automaticky obnoví za 3 sekundy.'
                  : 'V editoru nastala neočekávaná chyba. Klikněte na tlačítko pro obnovení.'}
              </Text>
            </VStack>

            {process.env.NODE_ENV === 'development' && (
              <VStack spacing={2} w="100%" align="stretch">
                <Text fontSize="sm" fontWeight="bold" color="gray.700">
                  Detaily chyby:
                </Text>
                <Code
                  p={3}
                  borderRadius="md"
                  fontSize="xs"
                  bg="red.50"
                  color="red.800"
                  maxH="120px"
                  overflow="auto"
                  w="100%"
                >
                  {this.state.error.toString()}
                </Code>
                {this.state.errorInfo && (
                  <Code
                    p={3}
                    borderRadius="md"
                    fontSize="xs"
                    bg="gray.50"
                    color="gray.800"
                    maxH="120px"
                    overflow="auto"
                    w="100%"
                  >
                    {this.state.errorInfo.componentStack}
                  </Code>
                )}
              </VStack>
            )}

            <VStack spacing={3} w="100%">
              <Button
                leftIcon={<FiRefreshCw />}
                colorScheme="blue"
                size="lg"
                w="100%"
                onClick={this.handleReset}
              >
                Obnovit editor
              </Button>
              
              {this.state.errorCount > 3 && (
                <Text fontSize="sm" color="orange.600" textAlign="center">
                  ⚠️ Opakované chyby ({this.state.errorCount}x). Zvažte obnovení stránky.
                </Text>
              )}
              
              {this.state.errorCount > 3 && (
                <Button
                  size="sm"
                  variant="ghost"
                  colorScheme="gray"
                  onClick={() => window.location.reload()}
                >
                  Obnovit celou stránku
                </Button>
              )}
            </VStack>
          </VStack>
        </Box>
      );
    }

    return this.props.children;
  }
}

export default MyUIbrixErrorBoundary;
