import React, { useState, useRef, useEffect, useCallback } from 'react';
import {
  Typography,
  Box,
  Chip,
  Divider,
  Skeleton,
  Button,
  CircularProgress,
  IconButton,
  Tooltip,
} from '@mui/material';
import { Forum, Cloud, LinkOff } from '@mui/icons-material';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { formatDistanceToNow } from 'date-fns';
import { de } from 'date-fns/locale';
import { nextcloudApi } from '../../services/nextcloud';
import type { NextcloudConversation } from '../../types/nextcloud.types';
import { safeOpenUrl } from '../../utils/safeOpenUrl';
import { useCountUp } from '../../hooks/useCountUp';
import { WidgetCard } from '../templates/WidgetCard';

const POLL_INTERVAL = 2000;
const POLL_TIMEOUT = 5 * 60 * 1000;

const ConversationRow: React.FC<{ conversation: NextcloudConversation; showDivider: boolean }> = ({
  conversation,
  showDivider,
}) => {
  const handleClick = () => {
    safeOpenUrl(conversation.url);
  };

  const relativeTime = conversation.lastMessage
    ? formatDistanceToNow(new Date(conversation.lastMessage.timestamp * 1000), {
        addSuffix: true,
        locale: de,
      })
    : null;

  return (
    <>
      <Box
        onClick={handleClick}
        sx={{
          display: 'flex',
          alignItems: 'flex-start',
          justifyContent: 'space-between',
          py: 1.5,
          px: 1,
          cursor: 'pointer',
          borderRadius: 1,
          transition: 'background-color 0.15s ease',
          '&:hover': {
            bgcolor: 'action.hover',
          },
        }}
      >
        <Box sx={{ flex: 1, minWidth: 0 }}>
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
            <Typography variant="subtitle2" noWrap>
              {conversation.displayName}
            </Typography>
            {conversation.unreadMessages > 0 && (
              <Chip
                label={conversation.unreadMessages}
                size="small"
                color="primary"
                sx={{ height: 20, fontSize: '0.7rem', minWidth: 24 }}
              />
            )}
          </Box>
          {conversation.lastMessage && (
            <Typography
              variant="body2"
              color="text.secondary"
              noWrap
              sx={{ mt: 0.25 }}
            >
              {conversation.lastMessage.author}: {conversation.lastMessage.text}
            </Typography>
          )}
        </Box>
        {relativeTime && (
          <Typography
            variant="caption"
            color="text.secondary"
            sx={{ ml: 1, whiteSpace: 'nowrap', mt: 0.25 }}
          >
            {relativeTime}
          </Typography>
        )}
      </Box>
      {showDivider && <Divider />}
    </>
  );
};

const NextcloudTalkWidget: React.FC = () => {
  const queryClient = useQueryClient();
  const [isConnecting, setIsConnecting] = useState(false);
  const pollIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const popupRef = useRef<Window | null>(null);

  const { data, isLoading, isError } = useQuery({
    queryKey: ['nextcloud-talk'],
    queryFn: () => nextcloudApi.getConversations(),
    refetchInterval: 30000,
    retry: 1,
  });

  const connected = data?.connected ?? false;
  const conversations = data?.conversations?.slice(0, 5) ?? [];
  const totalUnread = data?.totalUnread ?? 0;
  const animatedUnread = useCountUp(totalUnread);

  const stopPolling = useCallback(() => {
    if (pollIntervalRef.current) {
      clearInterval(pollIntervalRef.current);
      pollIntervalRef.current = null;
    }
    if (popupRef.current && !popupRef.current.closed) {
      popupRef.current.close();
    }
    popupRef.current = null;
    setIsConnecting(false);
  }, []);

  useEffect(() => {
    return () => {
      if (pollIntervalRef.current) {
        clearInterval(pollIntervalRef.current);
      }
      if (popupRef.current && !popupRef.current.closed) {
        popupRef.current.close();
      }
    };
  }, []);

  const handleConnect = async () => {
    try {
      setIsConnecting(true);
      const { loginUrl, pollToken, pollEndpoint } = await nextcloudApi.connect();

      const popup = window.open(loginUrl, '_blank', 'width=600,height=700');
      popupRef.current = popup;

      const startTime = Date.now();

      pollIntervalRef.current = setInterval(async () => {
        if (Date.now() - startTime > POLL_TIMEOUT) {
          stopPolling();
          return;
        }

        if (popup && popup.closed) {
          stopPolling();
          return;
        }

        try {
          const result = await nextcloudApi.poll(pollToken, pollEndpoint);
          if (result.completed) {
            stopPolling();
            queryClient.invalidateQueries({ queryKey: ['nextcloud-talk'] });
          }
        } catch {
          // Polling error — keep trying until timeout
        }
      }, POLL_INTERVAL);
    } catch {
      setIsConnecting(false);
    }
  };

  const handleDisconnect = async () => {
    try {
      await nextcloudApi.disconnect();
      queryClient.invalidateQueries({ queryKey: ['nextcloud-talk'] });
    } catch {
      // Disconnect failed silently
    }
  };

  const headerAction = (
    <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
      {connected && totalUnread > 0 && (
        <Chip
          label={`${animatedUnread} ungelesen`}
          size="small"
          color="primary"
          variant="outlined"
        />
      )}
      {connected && (
        <Tooltip title="Verbindung trennen">
          <IconButton size="small" onClick={handleDisconnect}>
            <LinkOff fontSize="small" />
          </IconButton>
        </Tooltip>
      )}
    </Box>
  );

  return (
    <WidgetCard
      title="Nextcloud Talk"
      icon={<Forum />}
      action={headerAction}
      noPadding
    >
      <Box sx={{ px: 2.5, pb: 2.5 }}>
        {isLoading && (
          <Box>
            {[1, 2, 3].map((n) => (
              <Box key={n} sx={{ mb: 1.5 }}>
                <Skeleton variant="text" width="60%" height={22} />
                <Skeleton variant="text" width="90%" height={18} />
              </Box>
            ))}
          </Box>
        )}

        {isError && (
          <Typography variant="body2" color="text.secondary" sx={{ py: 2, textAlign: 'center' }}>
            Nextcloud nicht erreichbar
          </Typography>
        )}

        {!isLoading && !isError && !connected && (
          <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', py: 3, gap: 2 }}>
            {isConnecting ? (
              <>
                <CircularProgress size={32} />
                <Typography variant="body2" color="text.secondary">
                  Warte auf Bestätigung...
                </Typography>
              </>
            ) : (
              <>
                <Typography variant="body2" color="text.secondary" sx={{ textAlign: 'center' }}>
                  Verbinde dein Nextcloud-Konto, um Chats zu sehen.
                </Typography>
                <Button
                  variant="outlined"
                  startIcon={<Cloud />}
                  onClick={handleConnect}
                >
                  Mit Nextcloud verbinden
                </Button>
              </>
            )}
          </Box>
        )}

        {!isLoading && !isError && connected && conversations.length === 0 && (
          <Typography variant="body2" color="text.secondary" sx={{ py: 2, textAlign: 'center' }}>
            Keine aktiven Chats
          </Typography>
        )}

        {!isLoading && !isError && connected && conversations.length > 0 && (
          <Box>
            {conversations.map((conversation, index) => (
              <ConversationRow
                key={conversation.token}
                conversation={conversation}
                showDivider={index < conversations.length - 1}
              />
            ))}
          </Box>
        )}
      </Box>
    </WidgetCard>
  );
};

export default NextcloudTalkWidget;
