import React, { useEffect, useState } from 'react';
import {
  Box,
  Typography,
  Grid,
  Card,
  CardContent,
  List,
  ListItem,
  Button,
  Chip,
  Alert,
  IconButton,
  Tooltip,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
} from '@mui/material';
import {
  Cancel as CancelIcon,
  Refresh as RefreshIcon,
  PlayArrow as PlayIcon,
  Stop as StopIcon,
} from '@mui/icons-material';
import { 
  useActivePublications, 
  useCancelPublication, 
  useRetryPublication 
} from '../../hooks/usePublications';
import { useSignalR } from '../../hooks/useSignalR';
import { 
  Publication, 
  PublishingStep, 
  PublishingProgressUpdate,
  PublicationStatus,
  StepStatus 
} from '../../types';
import { ProgressBar } from '../common/ProgressBar';
import { StatusChip } from '../common/StatusChip';
import { LoadingSpinner } from '../common/LoadingSpinner';
import { ErrorDisplay } from '../common/ErrorDisplay';
import { format } from 'date-fns';

export const PublishingDashboard: React.FC = () => {
  const [selectedPublication, setSelectedPublication] = useState<Publication | null>(null);
  const [progressUpdates, setProgressUpdates] = useState<Map<number, PublishingProgressUpdate[]>>(new Map());

  const { 
    data: activePublications, 
    isLoading, 
    error, 
    refetch 
  } = useActivePublications();

  const {
    subscribeToPublishingProgress,
    subscribeToPublicationCompleted,
    subscribeToPublicationFailed,
    joinPublicationGroup,
    leavePublicationGroup,
    isConnected,
  } = useSignalR();

  const cancelMutation = useCancelPublication();
  const retryMutation = useRetryPublication();

  // Subscribe to real-time updates
  useEffect(() => {
    const unsubscribeProgress = subscribeToPublishingProgress((update) => {
      setProgressUpdates(prev => {
        const publicationUpdates = prev.get(update.publicationId) || [];
        const newUpdates = [...publicationUpdates, update];
        
        // Keep only the last 50 updates per publication
        if (newUpdates.length > 50) {
          newUpdates.splice(0, newUpdates.length - 50);
        }
        
        const newMap = new Map(prev);
        newMap.set(update.publicationId, newUpdates);
        return newMap;
      });
    });

    const unsubscribeCompleted = subscribeToPublicationCompleted((publicationId) => {
      console.log(`Publication ${publicationId} completed`);
      refetch();
    });

    const unsubscribeFailed = subscribeToPublicationFailed(({ publicationId, error }) => {
      console.error(`Publication ${publicationId} failed:`, error);
      refetch();
    });

    return () => {
      unsubscribeProgress();
      unsubscribeCompleted();
      unsubscribeFailed();
    };
  }, [subscribeToPublishingProgress, subscribeToPublicationCompleted, subscribeToPublicationFailed, refetch]);

  // Join publication groups for real-time updates
  useEffect(() => {
    if (activePublications?.data) {
      activePublications.data.forEach(publication => {
        if (publication.status === PublicationStatus.InProgress) {
          joinPublicationGroup(publication.id);
        }
      });
    }

    return () => {
      if (activePublications?.data) {
        activePublications.data.forEach(publication => {
          leavePublicationGroup(publication.id);
        });
      }
    };
  }, [activePublications?.data, joinPublicationGroup, leavePublicationGroup]);

  const handleCancel = async (publication: Publication) => {
    if (window.confirm(`Are you sure you want to cancel the publication of "${publication.package?.title}"?`)) {
      await cancelMutation.mutateAsync(publication.id);
    }
  };

  const handleRetry = async (publication: Publication) => {
    await retryMutation.mutateAsync(publication.id);
  };

  const getLatestProgressForPublication = (publicationId: number): PublishingProgressUpdate | null => {
    const updates = progressUpdates.get(publicationId);
    return updates && updates.length > 0 ? updates[updates.length - 1] : null;
  };

  const calculateOverallProgress = (publication: Publication): number => {
    const latestUpdate = getLatestProgressForPublication(publication.id);
    if (latestUpdate) {
      return latestUpdate.progressPercent;
    }

    // Fallback to calculating from steps if available
    if (publication.steps && publication.steps.length > 0) {
      const completedSteps = publication.steps.filter(step => step.status === StepStatus.Completed).length;
      return (completedSteps / publication.steps.length) * 100;
    }

    return 0;
  };

  if (isLoading) return <LoadingSpinner message="Loading active publications..." />;
  if (error) return <ErrorDisplay message="Failed to load publications" onRetry={refetch} />;

  const publications = activePublications?.data || [];

  return (
    <Box>
      {/* Header */}
      <Box display="flex" justifyContent="space-between" alignItems="center" mb={3}>
        <Typography variant="h4" component="h1">
          Publishing Dashboard
        </Typography>
        <Box display="flex" gap={1}>
          <Tooltip title={isConnected ? 'Connected' : 'Disconnected'}>
            <Box
              sx={{
                display: 'flex',
                alignItems: 'center',
                gap: 1,
                px: 2,
                py: 1,
                borderRadius: 1,
                bgcolor: isConnected ? 'success.light' : 'error.light',
                color: isConnected ? 'success.contrastText' : 'error.contrastText',
              }}
            >
              <Box
                sx={{
                  width: 8,
                  height: 8,
                  borderRadius: '50%',
                  bgcolor: isConnected ? 'success.main' : 'error.main',
                }}
              />
              <Typography variant="body2">
                {isConnected ? 'Live Updates' : 'Disconnected'}
              </Typography>
            </Box>
          </Tooltip>
          <IconButton onClick={() => refetch()} title="Refresh">
            <RefreshIcon />
          </IconButton>
        </Box>
      </Box>

      {publications.length === 0 ? (
        <Card>
          <CardContent sx={{ textAlign: 'center', py: 6 }}>
            <Typography variant="h6" color="text.secondary" gutterBottom>
              No Active Publications
            </Typography>
            <Typography variant="body2" color="text.secondary">
              All publications are completed. Start a new publication from the Packages page.
            </Typography>
          </CardContent>
        </Card>
      ) : (
        <Grid container spacing={3}>
          {publications.map((publication) => {
            const latestProgress = getLatestProgressForPublication(publication.id);
            const overallProgress = calculateOverallProgress(publication);
            
            return (
              <Grid item xs={12} key={publication.id}>
                <Card>
                  <CardContent>
                    <Box display="flex" justifyContent="space-between" alignItems="flex-start" mb={2}>
                      <Box>
                        <Typography variant="h6" gutterBottom>
                          {publication.package?.title || 'Unknown Package'}
                        </Typography>
                        <Typography variant="body2" color="text.secondary" gutterBottom>
                          Version: {publication.package?.version} | 
                          Project: {publication.package?.project?.name}
                        </Typography>
                        <Box display="flex" gap={1} alignItems="center">
                          <StatusChip status={publication.status} />
                          {publication.publishedAt && (
                            <Chip
                              label={`Started ${format(new Date(publication.publishedAt), 'HH:mm:ss')}`}
                              size="small"
                              variant="outlined"
                            />
                          )}
                        </Box>
                      </Box>
                      <Box display="flex" gap={1}>
                        {publication.status === PublicationStatus.InProgress && (
                          <Button
                            variant="outlined"
                            color="error"
                            size="small"
                            startIcon={<CancelIcon />}
                            onClick={() => handleCancel(publication)}
                            disabled={cancelMutation.isPending}
                          >
                            Cancel
                          </Button>
                        )}
                        {publication.status === PublicationStatus.Failed && (
                          <Button
                            variant="outlined"
                            color="primary"
                            size="small"
                            startIcon={<PlayIcon />}
                            onClick={() => handleRetry(publication)}
                            disabled={retryMutation.isPending}
                          >
                            Retry
                          </Button>
                        )}
                        <Button
                          variant="outlined"
                          size="small"
                          onClick={() => setSelectedPublication(publication)}
                        >
                          View Details
                        </Button>
                      </Box>
                    </Box>

                    <Box mb={2}>
                      <ProgressBar
                        progress={overallProgress}
                        status={latestProgress ? latestProgress.status : undefined}
                        stepName={latestProgress ? latestProgress.stepName : 'Initializing...'}
                        details={latestProgress ? latestProgress.details : undefined}
                      />
                    </Box>

                    {publication.status === PublicationStatus.Failed && (
                      <Alert severity="error" sx={{ mt: 1 }}>
                        Publication failed. Check the details for more information.
                      </Alert>
                    )}
                  </CardContent>
                </Card>
              </Grid>
            );
          })}
        </Grid>
      )}

      {/* Publication Details Dialog */}
      <Dialog
        open={!!selectedPublication}
        onClose={() => setSelectedPublication(null)}
        maxWidth="md"
        fullWidth
      >
        {selectedPublication && (
          <>
            <DialogTitle>
              Publication Details - {selectedPublication.package?.title}
            </DialogTitle>
            <DialogContent>
              <Box mb={3}>
                <Grid container spacing={2}>
                  <Grid item xs={6}>
                    <Typography variant="body2" color="text.secondary">
                      Status
                    </Typography>
                    <StatusChip status={selectedPublication.status} />
                  </Grid>
                  <Grid item xs={6}>
                    <Typography variant="body2" color="text.secondary">
                      Started
                    </Typography>
                    <Typography variant="body2">
                      {selectedPublication.publishedAt ? 
                        format(new Date(selectedPublication.publishedAt), 'MMM dd, yyyy HH:mm:ss') : 
                        'Not started'
                      }
                    </Typography>
                  </Grid>
                </Grid>
              </Box>

              <Typography variant="h6" gutterBottom>
                Progress Updates
              </Typography>
              <List sx={{ maxHeight: 300, overflow: 'auto' }}>
                {progressUpdates.get(selectedPublication.id)?.map((update, index) => (
                  <ListItem key={index} sx={{ px: 0 }}>
                    <ProgressBar
                      progress={update.progressPercent}
                      status={update.status}
                      stepName={update.stepName}
                      details={update.details}
                    />
                  </ListItem>
                )) || (
                  <ListItem sx={{ px: 0 }}>
                    <Typography variant="body2" color="text.secondary">
                      No progress updates available
                    </Typography>
                  </ListItem>
                )}
              </List>
            </DialogContent>
            <DialogActions>
              <Button onClick={() => setSelectedPublication(null)}>
                Close
              </Button>
            </DialogActions>
          </>
        )}
      </Dialog>
    </Box>
  );
};