import React, { useState, useEffect, useRef } from 'react';
import {
  Box,
  Flex,
  Text,
  Progress,
  Button,
  VStack,
  HStack,
  Badge,
  useDisclosure,
  Modal,
  ModalOverlay,
  ModalContent,
  ModalHeader,
  ModalBody,
  ModalCloseButton,
  Table,
  Thead,
  Tbody,
  Tr,
  Th,
  Td,
  Spinner,
} from '@chakra-ui/react';
import { api } from '../services/api';

interface JobProgress {
  jobId: string;
  type: 'storage-sync' | 'song-matching';
  status: 'running' | 'completed' | 'failed';
  progress: number;
  current: number;
  total: number;
  message: string;
  startTime: Date;
  endTime?: Date;
  result?: any;
  error?: string;
}

interface BackgroundJobProgressProps {
  jobId?: string;
  onJobComplete?: (result: any) => void;
  onJobError?: (error: string) => void;
}

export const BackgroundJobProgress: React.FC<BackgroundJobProgressProps> = ({
  jobId,
  onJobComplete,
  onJobError,
}) => {
  const [jobs, setJobs] = useState<JobProgress[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const { isOpen, onClose } = useDisclosure();
  const intervalRef = useRef<NodeJS.Timeout | null>(null);

  // Load all jobs
  const loadJobs = async () => {
    try {
      setLoading(true);
      const jobsData = await api.getAllJobs();
      setJobs(jobsData);
      setError(null);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load jobs');
    } finally {
      setLoading(false);
    }
  };

  // Update specific job progress
  const updateJobProgress = async (jobId: string) => {
    try {
      const progress = await api.getJobProgress(jobId);
      
      setJobs(prev => prev.map(job => 
        job.jobId === jobId ? progress : job
      ));

      // Handle job completion
      if (progress.status === 'completed' && onJobComplete) {
        onJobComplete(progress.result);
      } else if (progress.status === 'failed' && onJobError) {
        onJobError(progress.error || 'Job failed');
      }
    } catch (err) {
      console.error('Error updating job progress:', err);
    }
  };

  // Start polling for jobs and update progress
  const startPolling = () => {
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }

    const tick = async () => {
      try {
        // Always reload job list to detect newly started jobs
        const jobsData = await api.getAllJobs();
        setJobs(jobsData);

        // Update progress for active jobs
        const activeJobIds = jobsData.filter((j: JobProgress) => j.status === 'running').map((j: JobProgress) => j.jobId);
        for (const id of activeJobIds) {
          await updateJobProgress(id);
        }

        if (jobId) {
          await updateJobProgress(jobId);
        }
      } catch (err) {
        // ignore transient polling errors
      }
    };

    // Adaptive interval: 2s if active jobs, else 10s
    const schedule = async () => {
      await tick();
      const hasActive = (jobs || []).some(j => j.status === 'running');
      const delay = hasActive ? 2000 : 10000;
      intervalRef.current = setTimeout(schedule, delay) as any;
    };

    schedule();
  };

  // Stop polling
  const stopPolling = () => {
    if (intervalRef.current) {
      clearTimeout(intervalRef.current as any);
      intervalRef.current = null;
    }
  };

  // Start polling on mount and stop on unmount
  useEffect(() => {
    loadJobs();
    startPolling();
    return () => stopPolling();
  }, []);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      stopPolling();
    };
  }, []);

  const getStatusColor = (status: string) => {
    switch (status) {
      case 'running': return 'blue';
      case 'completed': return 'green';
      case 'failed': return 'red';
      default: return 'gray';
    }
  };

  const getStatusIcon = (status: string) => {
    switch (status) {
      case 'running': return <Spinner size="sm" />;
      case 'completed': return <Text fontSize="sm">✅</Text>;
      case 'failed': return <Text fontSize="sm">❌</Text>;
      default: return <Text fontSize="sm">⏸️</Text>;
    }
  };

  const formatDuration = (startTime: Date, endTime?: Date) => {
    const start = new Date(startTime).getTime();
    const end = endTime ? new Date(endTime).getTime() : Date.now();
    const duration = Math.floor((end - start) / 1000);
    
    if (duration < 60) return `${duration}s`;
    if (duration < 3600) return `${Math.floor(duration / 60)}m ${duration % 60}s`;
    return `${Math.floor(duration / 3600)}h ${Math.floor((duration % 3600) / 60)}m`;
  };

  const activeJobs = jobs.filter(job => job.status === 'running');
  // const completedJobs = jobs.filter(job => job.status === 'completed' || job.status === 'failed');

  return (
    <>
      {/* Active Jobs Summary */}
      {activeJobs.length > 0 && (
        <Box
          position="fixed"
          bottom={4}
          right={4}
          bg="gray.800"
          border="1px solid"
          borderColor="gray.600"
          borderRadius="lg"
          p={4}
          boxShadow="xl"
          zIndex={1000}
          maxW="400px"
        >
          <Flex justify="space-between" align="center" mb={3}>
            <Text fontWeight="bold" fontSize="sm" color="gray.100">
              Background Jobs ({activeJobs.length})
            </Text>
          </Flex>

          <VStack spacing={3} align="stretch">
            {activeJobs.map(job => (
              <Box key={job.jobId} p={3} bg="gray.700" borderRadius="md">
                <Flex justify="space-between" align="center" mb={2}>
                  <Text fontSize="sm" fontWeight="medium" color="gray.100">
                    {job.type === 'storage-sync' ? 'Storage Sync' : 'Song Matching'}
                  </Text>
                  <Badge colorScheme={getStatusColor(job.status)} size="sm">
                    {job.status}
                  </Badge>
                </Flex>
                
                <Text fontSize="xs" color="gray.400" mb={2}>
                  {job.message}
                </Text>
                
                <Progress
                  value={job.progress}
                  size="sm"
                  colorScheme={getStatusColor(job.status)}
                  mb={2}
                />
                
                <Flex justify="space-between" fontSize="xs" color="gray.400">
                  <Text>{job.progress}%</Text>
                  <Text>{formatDuration(job.startTime)}</Text>
                </Flex>
              </Box>
            ))}
          </VStack>
        </Box>
      )}

      {/* All Jobs Modal */}
      <Modal isOpen={isOpen} onClose={onClose} size="xl">
        <ModalOverlay />
        <ModalContent bg="gray.800" color="gray.100">
          <ModalHeader color="gray.100">Background Jobs</ModalHeader>
          <ModalCloseButton color="gray.300" />
          <ModalBody pb={6}>
            <VStack spacing={4} align="stretch">
              <HStack justify="space-between">
                <Text fontWeight="bold" color="gray.100">All Jobs</Text>
                <Button size="sm" onClick={loadJobs} isLoading={loading}>
                  Refresh
                </Button>
              </HStack>

              {error && (
                <Text color="red.500" fontSize="sm">
                  {error}
                </Text>
              )}

              <Table variant="simple" size="sm">
                <Thead>
                  <Tr>
                    <Th color="gray.300">Type</Th>
                    <Th color="gray.300">Status</Th>
                    <Th color="gray.300">Progress</Th>
                    <Th color="gray.300">Duration</Th>
                    <Th color="gray.300">Message</Th>
                  </Tr>
                </Thead>
                <Tbody>
                  {jobs.map(job => (
                    <Tr key={job.jobId}>
                      <Td>
                        <Text fontSize="sm" color="gray.100">
                          {job.type === 'storage-sync' ? 'Storage Sync' : 'Song Matching'}
                        </Text>
                      </Td>
                      <Td>
                        <HStack spacing={2}>
                          {getStatusIcon(job.status)}
                          <Badge colorScheme={getStatusColor(job.status)} size="sm">
                            {job.status}
                          </Badge>
                        </HStack>
                      </Td>
                      <Td>
                        <Text fontSize="sm" color="gray.100">{job.progress}%</Text>
                      </Td>
                      <Td>
                        <Text fontSize="sm" color="gray.100">
                          {formatDuration(job.startTime, job.endTime)}
                        </Text>
                      </Td>
                      <Td>
                        <Text fontSize="sm" noOfLines={2} color="gray.100">
                          {job.message}
                        </Text>
                      </Td>
                    </Tr>
                  ))}
                </Tbody>
              </Table>

              {jobs.length === 0 && !loading && (
                <Text textAlign="center" color="gray.500" py={4}>
                  No background jobs found
                </Text>
              )}
            </VStack>
          </ModalBody>
        </ModalContent>
      </Modal>
    </>
  );
}; 