import React, { useRef, useState } from 'react';
import Avatar from '@mui/material/Avatar';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Paper from '@mui/material/Paper';
import Tooltip from '@mui/material/Tooltip';
import IconButton from '@mui/material/IconButton';
import ReplyIcon from '@mui/icons-material/Reply';
import type { NextcloudMessage } from '../../types/nextcloud.types';
import FileMessageContent from './FileMessageContent';
import RichMessageText from './RichMessageText';
import PollMessageContent from './PollMessageContent';
import { ReactionChips, AddReactionButton } from './MessageReactions';

const SENDER_COLORS = [
  '#E53935', '#D81B60', '#8E24AA', '#5E35B1',
  '#3949AB', '#1E88E5', '#00ACC1', '#00897B',
  '#43A047', '#F4511E',
];

function getSenderColor(actorId: string): string {
  let hash = 0;
  for (let i = 0; i < actorId.length; i++) hash = ((hash << 5) - hash + actorId.charCodeAt(i)) | 0;
  return SENDER_COLORS[Math.abs(hash) % SENDER_COLORS.length];
}

interface ChatMessageProps {
  message: NextcloudMessage;
  isOwnMessage: boolean;
  isOneToOne?: boolean;
  onReplyClick?: (message: NextcloudMessage) => void;
  onReactionToggled?: (messageId: number) => void;
  reactionsOverride?: { reactions: Record<string, number>; reactionsSelf: string[] };
}

function hasFileParams(params?: Record<string, any>): boolean {
  if (!params) return false;
  return Object.keys(params).some((k) => k === 'file' || k.startsWith('file'));
}

function hasPollParam(params?: Record<string, any>): boolean {
  return params?.object?.type === 'talk-poll';
}

const ChatMessage: React.FC<ChatMessageProps> = ({ message, isOwnMessage, isOneToOne, onReplyClick, onReactionToggled, reactionsOverride }) => {
  const [hovered, setHovered] = useState(false);
  const hoverDelayTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const longPressTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const hideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const handleMouseEnter = () => {
    hoverDelayTimer.current = setTimeout(() => {
      setHovered(true);
    }, 200);
  };

  const handleMouseLeave = () => {
    if (hoverDelayTimer.current) {
      clearTimeout(hoverDelayTimer.current);
      hoverDelayTimer.current = null;
    }
    setHovered(false);
  };

  const handleTouchStart = () => {
    longPressTimer.current = setTimeout(() => {
      setHovered(true);
      // Auto-hide after 4 seconds if the user doesn't interact
      hideTimer.current = setTimeout(() => setHovered(false), 4000);
    }, 500);
  };

  const handleTouchEnd = () => {
    if (longPressTimer.current) {
      clearTimeout(longPressTimer.current);
      longPressTimer.current = null;
    }
  };

  const handleTouchMove = () => {
    if (longPressTimer.current) {
      clearTimeout(longPressTimer.current);
      longPressTimer.current = null;
    }
    if (hideTimer.current) {
      clearTimeout(hideTimer.current);
      hideTimer.current = null;
    }
    setHovered(false);
  };

  const time = new Date(message.timestamp * 1000).toLocaleTimeString('de-DE', {
    hour: '2-digit',
    minute: '2-digit',
  });

  if (message.systemMessage) {
    return (
      <Box sx={{ display: 'flex', justifyContent: 'center', my: 0.5 }}>
        <Typography variant="caption" sx={{ fontStyle: 'italic', color: 'text.secondary' }}>
          <RichMessageText message={message.message} messageParameters={message.messageParameters} /> - {time}
        </Typography>
      </Box>
    );
  }

  const isFileMessage =
    hasFileParams(message.messageParameters) && message.message.includes('{file}');
  const isPollMessage = hasPollParam(message.messageParameters);

  const textBeforeFile = isFileMessage ? message.message.split('{file}')[0].trim() : null;

  const reactions = reactionsOverride?.reactions ?? message.reactions ?? {};
  const reactionsSelf = reactionsOverride?.reactionsSelf ?? message.reactionsSelf ?? [];

  /* Vertical toolbar with reply + add-reaction */
  const toolbar = (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        gap: 0.25,
        opacity: hovered ? 0.7 : 0,
        visibility: hovered ? 'visible' : 'hidden',
        transition: 'opacity 0.15s, visibility 0.15s',
        alignSelf: 'center',
        flexShrink: 0,
      }}
    >
      {onReplyClick && (
        <Tooltip title="Antworten">
          <IconButton
            size="small"
            onClick={() => onReplyClick(message)}
            sx={{ width: 24, height: 24 }}
          >
            <ReplyIcon sx={{ fontSize: '0.9rem', transform: isOwnMessage ? 'scaleX(-1)' : undefined }} />
          </IconButton>
        </Tooltip>
      )}
      {onReactionToggled && (
        <AddReactionButton
          token={message.token}
          messageId={message.id}
          reactionsSelf={reactionsSelf}
          onReactionToggled={() => onReactionToggled(message.id)}
        />
      )}
    </Box>
  );

  return (
    <Box
      sx={{
        display: 'flex',
        justifyContent: isOwnMessage ? 'flex-end' : 'flex-start',
        my: 0.5,
        px: 1,
        alignItems: 'flex-start',
        gap: 0.5,
      }}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      onTouchStart={handleTouchStart}
      onTouchEnd={handleTouchEnd}
      onTouchMove={handleTouchMove}
    >
      {/* Own messages: toolbar on LEFT */}
      {isOwnMessage && toolbar}

      <Box sx={{ maxWidth: '80%' }}>
        <Paper
          elevation={0}
          sx={{
            px: 1.5,
            py: 0.75,
            bgcolor: isOwnMessage ? 'primary.main' : (theme) => theme.palette.mode === 'dark' ? 'grey.800' : 'grey.200',
            color: isOwnMessage ? 'primary.contrastText' : 'text.primary',
            borderRadius: 2,
          }}
        >
          {!isOwnMessage && !isOneToOne && (
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, mb: 0.25 }}>
              <Avatar sx={{ width: 20, height: 20, fontSize: '0.7rem', bgcolor: getSenderColor(message.actorId) }}>
                {message.actorDisplayName.charAt(0).toUpperCase()}
              </Avatar>
              <Typography variant="body2" sx={{ fontWeight: 700, fontSize: '0.8rem', color: getSenderColor(message.actorId) }}>
                {message.actorDisplayName}
              </Typography>
            </Box>
          )}

          {/* Quoted parent message */}
          {message.parent && (
            <Box sx={{
              borderLeft: '3px solid',
              borderColor: isOwnMessage ? 'rgba(255,255,255,0.4)' : 'divider',
              pl: 1,
              mb: 0.75,
              opacity: 0.75,
              borderRadius: '0 4px 4px 0',
              py: 0.25,
              bgcolor: isOwnMessage ? 'rgba(0,0,0,0.1)' : 'rgba(0,0,0,0.04)',
            }}>
              <Typography variant="caption" sx={{ display: 'block', fontWeight: 600, lineHeight: 1.4, color: !isOwnMessage ? getSenderColor(message.parent.actorId) : undefined }}>
                {message.parent.actorDisplayName}
              </Typography>
              <Typography variant="caption" noWrap sx={{ display: 'block', lineHeight: 1.4 }}>
                {message.parent.message}
              </Typography>
            </Box>
          )}

          {isPollMessage ? (
            <PollMessageContent
              roomToken={message.token}
              pollId={message.messageParameters!.object.id}
              pollName={message.messageParameters!.object.name ?? ''}
              isOwnMessage={isOwnMessage}
            />
          ) : isFileMessage ? (
            <>
              {textBeforeFile && (
                <RichMessageText
                  message={textBeforeFile}
                  messageParameters={message.messageParameters}
                  isOwnMessage={isOwnMessage}
                />
              )}
              <FileMessageContent
                messageParameters={message.messageParameters!}
                isOwnMessage={isOwnMessage}
              />
            </>
          ) : (
            <RichMessageText
              message={message.message}
              messageParameters={message.messageParameters}
              isOwnMessage={isOwnMessage}
            />
          )}

          <Typography
            variant="caption"
            sx={{
              display: 'block',
              textAlign: 'right',
              mt: 0.25,
              opacity: 0.7,
            }}
          >
            {time}
          </Typography>
        </Paper>

        {/* Reaction chips below the bubble */}
        <ReactionChips
          token={message.token}
          messageId={message.id}
          reactions={reactions}
          reactionsSelf={reactionsSelf}
          onReactionToggled={() => onReactionToggled?.(message.id)}
        />
      </Box>

      {/* Partner messages: toolbar on RIGHT */}
      {!isOwnMessage && toolbar}
    </Box>
  );
};

export default ChatMessage;
