import React, { Component } from 'react';
import Box from '@mui/material/Box';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import CloseIcon from '@mui/icons-material/Close';
import CircularProgress from '@mui/material/CircularProgress';
import Avatar from '@mui/material/Avatar';
import SmartToyIcon from '@mui/icons-material/SmartToy';
import PersonIcon from '@mui/icons-material/Person';
import MicIcon from '@mui/icons-material/Mic';
import StopIcon from '@mui/icons-material/Stop';
import PhotoCameraIcon from '@mui/icons-material/PhotoCamera';
import parse, { domToReact } from 'html-react-parser';
import { Link } from 'react-router-dom';
import MuiLink from '@mui/material/Link';
import { alpha } from '@mui/material/styles';
import TelegramIcon from '@mui/icons-material/Telegram';
import { isUserLoggedIn } from './LoginComponent.js';
import { withTranslation } from '../i18n/withTranslation.js';

const TELEGRAM_ASSISTANT_URL = 'https://t.me/Growheads_de_Bot';
// Initialize window object for storing messages
if (!window.chatMessages) {
  window.chatMessages = [];
}

class ChatAssistant extends Component {
  constructor(props) {
    super(props);

    const privacyConfirmed = sessionStorage.getItem('privacyConfirmed') === 'true';

    this.state = {
      messages: window.chatMessages,
      inputValue: '',
      isTyping: false,
      isRecording: false,
      recordingTime: 0,
      mediaRecorder: null,
      audioChunks: [],
      aiThink: false,
      atDatabase: false,
      atWeb: false,
      privacyConfirmed: privacyConfirmed,
      isGuest: false
    };
    
    this.messagesEndRef = React.createRef();
    this.fileInputRef = React.createRef();
    this.recordingTimer = null;
  }

  buildPrivacyPromptHtml = () => {
    const { t } = this.props;
    return `${t('chat.privacyPromptBefore')}<a href="/datenschutz" target="_blank" rel="noopener noreferrer">${t('chat.privacyPolicyLink')}</a>${t('chat.privacyPromptAfter')}<button data-confirm-privacy="true">${t('chat.privacyRead')}</button>`;
  };

  /** Keep stored privacy bubble in sync with i18n (language switcher, lazy bundle load). */
  applyPrivacyPromptTranslation = () => {
    this.setState((prev) => {
      if (prev.privacyConfirmed) return null;
      const idx = prev.messages.findIndex((m) => m.id === 'privacy-prompt');
      if (idx === -1) return null;
      const updatedMessages = [...prev.messages];
      updatedMessages[idx] = {
        ...updatedMessages[idx],
        text: this.buildPrivacyPromptHtml(),
      };
      window.chatMessages = updatedMessages;
      return { messages: updatedMessages };
    });
  };

  handleI18nLanguageChanged = () => {
    this.applyPrivacyPromptTranslation();
  };

  componentDidMount() {
    // Add socket listeners if socket is available and connected
    this.addSocketListeners();

    this.props.i18n?.on('languageChanged', this.handleI18nLanguageChanged);

    const userStatus = isUserLoggedIn();
    const isGuest = !userStatus.isLoggedIn;

    if (isGuest && !this.state.privacyConfirmed) {
      this.setState(prevState => {
        if (prevState.messages.find(msg => msg.id === 'privacy-prompt')) {
          const updatedMessages = prevState.messages.map((msg) =>
            msg.id === 'privacy-prompt'
              ? { ...msg, text: this.buildPrivacyPromptHtml() }
              : msg
          );
          window.chatMessages = updatedMessages;
          return {
            messages: updatedMessages,
            isGuest: true,
          };
        }

        const privacyMessage = {
          id: 'privacy-prompt',
          sender: 'bot',
          text: this.buildPrivacyPromptHtml(),
        };
        const updatedMessages = [privacyMessage, ...prevState.messages];
        window.chatMessages = updatedMessages;
        return { 
          messages: updatedMessages,
          isGuest: true 
        };
      });
    } else {
      this.setState({ isGuest });
    }
  }
  
  componentDidUpdate(prevProps, prevState) {
    if (prevProps.i18n?.language !== this.props.i18n?.language) {
      this.applyPrivacyPromptTranslation();
    }
    if (prevState.messages !== this.state.messages || prevState.isTyping !== this.state.isTyping) {
      this.scrollToBottom();
    }
  }
  
  componentWillUnmount() {
    this.props.i18n?.off('languageChanged', this.handleI18nLanguageChanged);
    this.removeSocketListeners();
    this.stopRecording();
    if (this.recordingTimer) {
      clearInterval(this.recordingTimer);
    }
  }

  addSocketListeners = () => {

      this.removeSocketListeners();
      window.socketManager.on('aiassyResponse', this.handleBotResponse);
      window.socketManager.on('aiassyStatus', this.handleStateResponse);

  }

  removeSocketListeners = () => {

      window.socketManager.off('aiassyResponse', this.handleBotResponse);
      window.socketManager.off('aiassyStatus', this.handleStateResponse);

  }
  
  handleBotResponse = (msgId,response) => {
    this.setState(prevState => {
      // Check if a message with this msgId already exists
      const existingMessageIndex = prevState.messages.findIndex(msg => msg.msgId === msgId);
      
      let updatedMessages;
      
      if (existingMessageIndex !== -1 && msgId) {
        // If message with this msgId exists, append the response
        updatedMessages = [...prevState.messages];
        updatedMessages[existingMessageIndex] = {
          ...updatedMessages[existingMessageIndex],
          text: updatedMessages[existingMessageIndex].text + response.content
        };
      } else {
        // Create a new message
        console.log('ChatAssistant: handleBotResponse', msgId, response);
        if(response && response.content) {
          const newBotMessage = {
            id: Date.now(),
           msgId: msgId,
            sender: 'bot',
            text: response.content,
          };
          updatedMessages = [...prevState.messages, newBotMessage];
        }
      }
      
      // Store in window object
      window.chatMessages = updatedMessages;
      return { 
        messages: updatedMessages,
        isTyping: false
      };
    });
  }
  handleStateResponse = (msgId,response) => {
    if(response == 'think') this.setState({ aiThink: true });
    if(response == 'nothink') this.setState({ aiThink: false });
    if(response == 'database') this.setState({ atDatabase: true });
    if(response == 'nodatabase') this.setState({ atDatabase: false });
    if(response == 'web') this.setState({ atWeb: true });
    if(response == 'noweb') this.setState({ atWeb: false });
  }
  
  scrollToBottom = () => {
    this.messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }
  
  handleInputChange = (event) => {
    this.setState({ inputValue: event.target.value });
  }
  
  handleSendMessage = () => {
    const userMessage = this.state.inputValue.trim();
    if (!userMessage) return;

    const newUserMessage = {
      id: Date.now(),
      sender: 'user',
      text: userMessage,
    };

    // Update messages in component state
    this.setState(prevState => {
      const updatedMessages = [...prevState.messages, newUserMessage];
      // Store in window object
      window.chatMessages = updatedMessages;
      return {
        messages: updatedMessages,
        inputValue: '',
        isTyping: true
      };
    }, () => {
      // Emit message to socket server after state is updated
      if (userMessage.trim()) {
        window.socketManager.emit('aiassyMessage', userMessage);
      }
    });
  }
  
  handleKeyDown = (event) => {
    if (event.key === 'Enter') {
      this.handleSendMessage();
    }
  }
  
  startRecording = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const mediaRecorder = new MediaRecorder(stream);
      const audioChunks = [];
      
      mediaRecorder.addEventListener("dataavailable", event => {
        audioChunks.push(event.data);
      });
      
      mediaRecorder.addEventListener("stop", () => {
        if (audioChunks.length > 0) {
          const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
          this.sendAudioMessage(audioBlob);
        }
        
        // Stop all tracks on the stream to release the microphone
        stream.getTracks().forEach(track => track.stop());
      });
      
      // Start recording
      mediaRecorder.start();
      
      // Set up timer - limit to 60 seconds
      this.recordingTimer = setInterval(() => {
        this.setState(prevState => {
          const newTime = prevState.recordingTime + 1;
          
          // Auto-stop after 10 seconds
          if (newTime >= 10) {
            this.stopRecording();
          }
          
          return { recordingTime: newTime };
        });
      }, 1000);
      
      this.setState({
        isRecording: true,
        mediaRecorder,
        audioChunks,
        recordingTime: 0
      });
    } catch (err) {
      console.error("Error accessing microphone:", err);
      alert(this.props.t('chat.micPermissionDenied'));
    }
  };
  
  stopRecording = () => {
    const { mediaRecorder, isRecording } = this.state;
    
    if (this.recordingTimer) {
      clearInterval(this.recordingTimer);
    }
    
    if (mediaRecorder && isRecording) {
      mediaRecorder.stop();
      this.setState({
        isRecording: false,
        recordingTime: 0
      });
    }
  };
  
  sendAudioMessage = async (audioBlob) => {
    // Create a URL for the audio blob
    const audioUrl = URL.createObjectURL(audioBlob);
    
    // Create a user message with audio content
    const newUserMessage = {
      id: Date.now(),
      sender: 'user',
      text: `<audio controls src="${audioUrl}"></audio>`,
      isAudio: true
    };
    
    // Update UI with the audio message
    this.setState(prevState => {
      const updatedMessages = [...prevState.messages, newUserMessage];
      // Store in window object
      window.chatMessages = updatedMessages;
      return {
        messages: updatedMessages,
        isTyping: true
      };
    });
    
    // Convert audio to base64 for sending to server
    const reader = new FileReader();
    reader.readAsDataURL(audioBlob);
    reader.onloadend = () => {
      const base64Audio = reader.result.split(',')[1];
      // Send audio data to server
        window.socketManager.emit('aiassyAudioMessage', { 
          audio: base64Audio,
          format: 'wav'
        });
    };
  };
  
  handleImageUpload = () => {
    this.fileInputRef.current?.click();
  };

  handleFileChange = (event) => {
    const file = event.target.files[0];
    if (file && file.type.startsWith('image/')) {
      this.resizeAndSendImage(file);
    }
    // Reset the file input
    event.target.value = '';
  };

  resizeAndSendImage = (file) => {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const img = new Image();
    
    img.onload = () => {
      // Calculate new dimensions (max 450px width/height)
      const maxSize = 450;
      let { width, height } = img;
      
      if (width > height) {
        if (width > maxSize) {
          height *= maxSize / width;
          width = maxSize;
        }
      } else {
        if (height > maxSize) {
          width *= maxSize / height;
          height = maxSize;
        }
      }
      
      // Set canvas dimensions
      canvas.width = width;
      canvas.height = height;
      
      // Draw and compress image
      ctx.drawImage(img, 0, 0, width, height);
      
      // Convert to blob with compression
      canvas.toBlob((blob) => {
        this.sendImageMessage(blob);
      }, 'image/jpeg', 0.8);
    };
    
    img.src = URL.createObjectURL(file);
  };

  sendImageMessage = async (imageBlob) => {
    // Create a URL for the image blob
    const imageUrl = URL.createObjectURL(imageBlob);
    
    // Create a user message with image content
    const newUserMessage = {
      id: Date.now(),
      sender: 'user',
      text: `<img src="${imageUrl}" alt="${this.props.t('chat.uploadedImageAlt')}" style="max-width: 100%; height: auto; border-radius: 8px;" />`,
      isImage: true
    };
    
    // Update UI with the image message
    this.setState(prevState => {
      const updatedMessages = [...prevState.messages, newUserMessage];
      // Store in window object
      window.chatMessages = updatedMessages;
      return {
        messages: updatedMessages,
        isTyping: true
      };
    });
    
    // Convert image to base64 for sending to server
    const reader = new FileReader();
    reader.readAsDataURL(imageBlob);
    reader.onloadend = () => {
      const base64Image = reader.result.split(',')[1];
      // Send image data to server

        window.socketManager.emit('aiassyPicMessage', { 
          image: base64Image,
          format: 'jpeg'
        });

    };
  };
  
  formatTime = (seconds) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
  };
  
  handlePrivacyConfirm = () => {
    sessionStorage.setItem('privacyConfirmed', 'true');
    this.setState(prevState => {
      const updatedMessages = prevState.messages.filter(msg => msg.id !== 'privacy-prompt');
      window.chatMessages = updatedMessages;
      return { 
        privacyConfirmed: true,
        messages: updatedMessages
      };
    });
  };

  formatMarkdown = (text) => {
    // Replace code blocks with formatted HTML
    return text.replace(/```(.*?)\n([\s\S]*?)```/g, (match, language, code) => {
      return `<pre class="code-block" data-language="${language.trim()}"><code>${code.trim()}</code></pre>`;
    });
  };

  getParseOptions = () => ({
    replace: (domNode) => {
      // Convert <a> tags to React Router Links
      if (domNode.name === 'a' && domNode.attribs && domNode.attribs.href) {
        const href = domNode.attribs.href;
        
        // Only convert internal links (not external URLs)
        if (!href.startsWith('http://') && !href.startsWith('https://') && !href.startsWith('//')) {
          return (
            <Link to={href} style={{ color: 'inherit', textDecoration: 'underline' }}>
              {domToReact(domNode.children, this.getParseOptions())}
            </Link>
          );
        }
      }
      
      // Style pre/code blocks
      if (domNode.name === 'pre' && domNode.attribs && domNode.attribs.class === 'code-block') {
        const language = domNode.attribs['data-language'] || '';
        return (
          <pre style={{ 
            backgroundColor: '#c0f5c0', 
            padding: '8px', 
            borderRadius: '4px',
            overflowX: 'auto',
            fontFamily: 'monospace',
            fontSize: '0.9em',
            whiteSpace: 'pre-wrap',
            margin: '8px 0'
          }}>
            {language && <div style={{ marginBottom: '4px', color: '#666' }}>{language}</div>}
            {domToReact(domNode.children, this.getParseOptions())}
          </pre>
        );
      }
      
      if (domNode.name === 'button' && domNode.attribs && domNode.attribs['data-confirm-privacy']) {
        return <Button variant="contained" size="small" onClick={this.handlePrivacyConfirm}>{this.props.t('chat.privacyRead')}</Button>;
      }
    }
  });
  
  render() {
    const { open, onClose, t } = this.props;
    const { messages, inputValue, isTyping, isRecording, recordingTime, isGuest, privacyConfirmed } = this.state;
    const showTelegramHint = !messages.some((m) => m.sender === 'user');
    
    if (!open) {
      return null;
    }

    const inputsDisabled = isGuest && !privacyConfirmed;

    return (
      <Paper
        elevation={4}
        sx={{
          position: 'fixed',
          bottom: { xs: 0, sm: 80 },
          right: { xs: 0, sm: 16 },
          left: { xs: 0, sm: 'auto' },
          top: { xs: 0, sm: 'auto' },
          width: { xs: '100vw', sm: 450, md: 600, lg: 750 },
          height: { xs: '100vh', sm: 600, md: 650, lg: 700 },
          maxWidth: { xs: 'none', sm: 450, md: 600, lg: 750 },
          maxHeight: { xs: '100vh', sm: 600, md: 650, lg: 700 },
          bgcolor: 'background.paper',
          borderRadius: { xs: 0, sm: 2 },
          display: 'flex',
          flexDirection: 'column',
          zIndex: 1300,
          overflow: 'hidden'
        }}
      >
        <Box 
          sx={{ 
            display: 'flex', 
            justifyContent: 'space-between', 
            alignItems: 'center', 
            px: 2, 
            py: 1, 
            borderBottom: 1, 
            borderColor: 'divider',
            bgcolor: 'primary.main',
            color: 'primary.contrastText',
            borderTopLeftRadius: 'inherit',
            borderTopRightRadius: 'inherit',
            flexShrink: 0,
          }}
        >
          <Typography variant="h6" component="div">
            {t('chat.assistantTitle')}
            <Typography component="span" color={this.state.aiThink ? "error" : "text.disabled"} sx={{ display: 'inline' }}>🧠</Typography>
            <Typography component="span" color={this.state.atDatabase ? "error" : "text.disabled"} sx={{ display: 'inline' }}>🛢</Typography>
            <Typography component="span" color={this.state.atWeb ? "error" : "text.disabled"} sx={{ display: 'inline' }}>🌐</Typography>
          </Typography>
          <IconButton onClick={onClose} size="small" aria-label={t('chat.closeAria')} sx={{ color: 'primary.contrastText' }}>
            <CloseIcon />
          </IconButton>
        </Box>
        <Box 
          sx={{ 
            flexGrow: 1, 
            overflowY: 'auto', 
            p: 2,
            display: 'flex',
            flexDirection: 'column',
            gap: 2,
          }}
        >
          {showTelegramHint && (
            <Paper
              elevation={4}
              sx={{
                p: 2,
                borderRadius: 2,
                border: 2,
                borderColor: 'primary.main',
                bgcolor: (theme) => alpha(theme.palette.primary.main, 0.14),
                boxShadow: (theme) =>
                  `0 4px 14px ${alpha(theme.palette.primary.main, 0.35)}`,
              }}
            >
              <Box sx={{ display: 'flex', gap: 1.5, alignItems: 'flex-start' }}>
                <TelegramIcon
                  sx={{
                    fontSize: 40,
                    color: 'primary.main',
                    flexShrink: 0,
                    filter: (theme) =>
                      `drop-shadow(0 1px 2px ${alpha(theme.palette.primary.dark, 0.45)})`,
                  }}
                />
                <Box sx={{ minWidth: 0 }}>
                  <Typography
                    variant="subtitle1"
                    component="div"
                    fontWeight={700}
                    color="text.primary"
                    sx={{ lineHeight: 1.45, mb: 0.25 }}
                  >
                    {t('chat.telegramAssistantIntro')}
                  </Typography>
                  <MuiLink
                    href={TELEGRAM_ASSISTANT_URL}
                    target="_blank"
                    rel="noopener noreferrer"
                    variant="subtitle1"
                    fontWeight={800}
                    sx={{
                      wordBreak: 'break-all',
                      color: 'primary.dark',
                      textDecorationColor: 'primary.main',
                      '&:hover': { color: 'primary.main' },
                    }}
                  >
                    {t('chat.telegramAssistantLink')}
                  </MuiLink>
                </Box>
              </Box>
            </Paper>
          )}
          {messages &&messages.map((message) => (
            <Box 
              key={message.id} 
              sx={{ 
                display: 'flex', 
                justifyContent: message.sender === 'user' ? 'flex-end' : 'flex-start',
                gap: 1,
              }}
            >
              {message.sender === 'bot' && (
                <Avatar sx={{ bgcolor: 'primary.main', width: 30, height: 30 }}>
                  <SmartToyIcon fontSize="small" />
                </Avatar>
              )}
              <Paper 
                elevation={1}
                sx={{
                  py: 1,
                  px: 3,
                  borderRadius: 2,
                  bgcolor: message.sender === 'user' ? 'secondary.light' : 'grey.200',
                  maxWidth: '75%',
                  fontSize: '0.8em'
                }}
              >
                {message.text ? parse(this.formatMarkdown(message.text), this.getParseOptions()) : ''}
              </Paper>
              {message.sender === 'user' && (
                <Avatar sx={{ bgcolor: 'secondary.main', width: 30, height: 30 }}>
                  <PersonIcon fontSize="small" />
                </Avatar>
              )}
            </Box>
          ))}
          {isTyping && (
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
               <Avatar sx={{ bgcolor: 'primary.main', width: 30, height: 30 }}>
                  <SmartToyIcon fontSize="small" />
                </Avatar>
              <Paper elevation={1} sx={{ p: 1, borderRadius: 2, bgcolor: 'grey.200', display: 'inline-flex', alignItems: 'center' }}>
                <CircularProgress size={16} sx={{ mx: 1 }} />
              </Paper>
            </Box>
          )}
          <div ref={this.messagesEndRef} />
        </Box>
        <Box
          sx={{
            display: 'flex',
            flexDirection: { xs: 'column', sm: 'row' },
            gap: { xs: 1, sm: 0 },
            p: 1,
            borderTop: 1,
            borderColor: 'divider',
            flexShrink: 0,
          }}
        >
          <input
            type="file"
            ref={this.fileInputRef}
            accept="image/*"
            onChange={this.handleFileChange}
            style={{ display: 'none' }}
          />
          <TextField
            fullWidth
            variant="outlined"
            size="small"
            autoComplete="off"
            autoFocus
            autoCapitalize="off"
            autoCorrect="off"
            placeholder={isRecording ? t('chat.placeholderRecording') : t('chat.inputPlaceholder')}
            value={inputValue}
            onChange={this.handleInputChange}
            onKeyDown={this.handleKeyDown}
            disabled={isRecording || inputsDisabled}
            slotProps={{
              input: {
                maxLength: 300,
                endAdornment: isRecording && (
                  <Typography variant="caption" color="primary" sx={{ mr: 1 }}>
                    {this.formatTime(recordingTime)}
                  </Typography>
                )
              }
            }}
          />
          
          <Box sx={{ display: 'flex', gap: 1, justifyContent: 'flex-end' }}>
            {isRecording ? (
              <IconButton
                color="error"
                onClick={this.stopRecording}
                aria-label={t('chat.micStopAria')}
                sx={{ ml: { xs: 0, sm: 1 } }}
              >
                <StopIcon />
              </IconButton>
            ) : (
              <IconButton
                color="primary"
                onClick={this.startRecording}
                aria-label={t('chat.micStartAria')}
                sx={{ ml: { xs: 0, sm: 1 } }}
                disabled={isTyping || inputsDisabled}
              >
                <MicIcon />
              </IconButton>
            )}
            
            <IconButton
              color="primary"
              onClick={this.handleImageUpload}
              aria-label={t('chat.uploadImageAria')}
              sx={{ ml: { xs: 0, sm: 1 } }}
              disabled={isTyping || isRecording || inputsDisabled}
            >
              <PhotoCameraIcon />
            </IconButton>
            
            <Button
              variant="contained"
              sx={{ ml: { xs: 0, sm: 1 } }}
              onClick={this.handleSendMessage}
              disabled={isTyping || isRecording || inputsDisabled}
            >
              {t('chat.send')}
            </Button>
          </Box>
        </Box>
      </Paper>
    );
  }
}

export default withTranslation()(ChatAssistant);
