import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
  Box,
  Button,
  Card,
  CardContent,
  Typography,
  LinearProgress,
  Alert,
  Chip,
  List,
  ListItem,
  ListItemText,
  ListItemSecondaryAction,
  IconButton,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  CircularProgress,
  Accordion,
  AccordionSummary,
  AccordionDetails,
} from '@mui/material';
import {
  PlayArrow,
  Stop,
  Refresh,
  CheckCircle,
  Error as ErrorIcon,
  Schedule,
  ExpandMore,
  Analytics,
  DataUsage,
} from '@mui/icons-material';
import { apiClient } from '../../api/client';

interface Job {
  job_id: string;
  job_type: string;
  user_id: string;
  status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
  progress: number;
  message: string;
  created_at: string;
  started_at?: string;
  completed_at?: string;
  result?: any;
  error?: string;
}

interface BackgroundJobManagerProps {
  siteUrl?: string;
  days?: number;
  onJobCompleted?: (job: Job) => void;
}

const BackgroundJobManager: React.FC<BackgroundJobManagerProps> = ({
  siteUrl = 'https://www.alwrity.com/',
  days = 30,
  onJobCompleted,
}) => {
  const [jobs, setJobs] = useState<Job[]>([]);
  const [loading, setLoading] = useState(false);
  const [selectedJob, setSelectedJob] = useState<Job | null>(null);
  const [jobDialogOpen, setJobDialogOpen] = useState(false);
  const [hasRunningJobs, setHasRunningJobs] = useState(false);

  // Fetch user jobs
  const fetchJobs = useCallback(async () => {
    try {
      const response = await apiClient.get('/api/background-jobs/user-jobs?limit=10');
      if (response.data.success) {
        const newJobs = response.data.data.jobs || [];
        setJobs(newJobs);
        
        // Update running jobs state
        const runningJobs = newJobs.some((job: Job) => job.status === 'running' || job.status === 'pending');
        setHasRunningJobs(runningJobs);
      }
    } catch (error) {
      console.error('Error fetching jobs:', error);
    }
  }, []);

  // Create Bing comprehensive insights job
  const createComprehensiveInsightsJob = async () => {
    setLoading(true);
    try {
      const response = await apiClient.post(
        `/api/background-jobs/bing/comprehensive-insights?site_url=${encodeURIComponent(siteUrl)}&days=${days}`
      );
      
      if (response.data.success) {
        const jobId = response.data.data.job_id;
        console.log('✅ Comprehensive insights job created:', jobId);
        
        // Refresh jobs list
        await fetchJobs();
        
        // Show success message
        alert(`Background job created successfully! Job ID: ${jobId}\n\nThis will generate comprehensive Bing insights in the background. Check the job status below for progress.`);
      }
    } catch (error) {
      console.error('Error creating comprehensive insights job:', error);
      alert('Failed to create background job. Please try again.');
    } finally {
      setLoading(false);
    }
  };

  // Create Bing data collection job
  const createDataCollectionJob = async () => {
    setLoading(true);
    try {
      const response = await apiClient.post(
        `/api/background-jobs/bing/data-collection?site_url=${encodeURIComponent(siteUrl)}&days_back=${days}`
      );
      
      if (response.data.success) {
        const jobId = response.data.data.job_id;
        console.log('✅ Data collection job created:', jobId);
        
        // Refresh jobs list
        await fetchJobs();
        
        alert(`Background data collection job created successfully! Job ID: ${jobId}\n\nThis will collect fresh data from Bing API in the background.`);
      }
    } catch (error) {
      console.error('Error creating data collection job:', error);
      alert('Failed to create data collection job. Please try again.');
    } finally {
      setLoading(false);
    }
  };

  // Cancel job
  const cancelJob = async (jobId: string) => {
    try {
      const response = await apiClient.post(`/api/background-jobs/cancel/${jobId}`);
      
      if (response.data.success) {
        console.log('✅ Job cancelled:', jobId);
        await fetchJobs();
        alert('Job cancelled successfully');
      } else {
        alert(response.data.message || 'Failed to cancel job');
      }
    } catch (error) {
      console.error('Error cancelling job:', error);
      alert('Failed to cancel job. Please try again.');
    }
  };

  // View job details
  const viewJobDetails = async (jobId: string) => {
    try {
      const response = await apiClient.get(`/api/background-jobs/status/${jobId}`);
      
      if (response.data.success) {
        setSelectedJob(response.data.data);
        setJobDialogOpen(true);
        
        // Call onJobCompleted if job is completed
        if (response.data.data.status === 'completed' && onJobCompleted) {
          onJobCompleted(response.data.data);
        }
      }
    } catch (error) {
      console.error('Error fetching job details:', error);
      alert('Failed to fetch job details');
    }
  };

  // Get status color
  const getStatusColor = (status: string) => {
    switch (status) {
      case 'completed': return 'success';
      case 'failed': return 'error';
      case 'running': return 'primary';
      case 'pending': return 'warning';
      case 'cancelled': return 'default';
      default: return 'default';
    }
  };

  // Get status icon
  const getStatusIcon = (status: string) => {
    switch (status) {
      case 'completed': return <CheckCircle />;
      case 'failed': return <ErrorIcon />;
      case 'running': return <CircularProgress size={16} />;
      case 'pending': return <Schedule />;
      case 'cancelled': return <Stop />;
      default: return <Schedule />;
    }
  };

  // Format job type
  const formatJobType = (jobType: string) => {
    switch (jobType) {
      case 'bing_comprehensive_insights': return 'Bing Comprehensive Insights';
      case 'bing_data_collection': return 'Bing Data Collection';
      case 'analytics_refresh': return 'Analytics Refresh';
      default: return jobType;
    }
  };

  // One-run guard to prevent duplicate calls in StrictMode
  const jobsFetchedRef = useRef(false);

  // Poll for job updates
  useEffect(() => {
    if (jobsFetchedRef.current) return;
    jobsFetchedRef.current = true;
    
    fetchJobs();
    
    // Only start polling if there are running jobs
    let interval: NodeJS.Timeout | null = null;
    
    if (hasRunningJobs) {
      interval = setInterval(() => {
        fetchJobs().catch(console.error);
      }, 5000);
    }

    return () => {
      if (interval) {
        clearInterval(interval);
      }
    };
  }, [fetchJobs, hasRunningJobs]); // Only depend on hasRunningJobs state

  return (
    <Box>
      {/* Action Buttons */}
      <Card sx={{ mb: 3 }}>
        <CardContent>
          <Typography variant="h6" gutterBottom>
            Background Job Actions
          </Typography>
          <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
            Run expensive operations in the background to avoid timeouts and improve user experience.
          </Typography>
          
          <Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap' }}>
            <Button
              variant="contained"
              startIcon={<Analytics />}
              onClick={createComprehensiveInsightsJob}
              disabled={loading}
              color="primary"
            >
              {loading ? 'Creating...' : 'Generate Comprehensive Bing Insights'}
            </Button>
            
            <Button
              variant="outlined"
              startIcon={<DataUsage />}
              onClick={createDataCollectionJob}
              disabled={loading}
              color="secondary"
            >
              {loading ? 'Creating...' : 'Collect Fresh Bing Data'}
            </Button>
            
            <Button
              variant="outlined"
              startIcon={<Refresh />}
              onClick={fetchJobs}
              disabled={loading}
            >
              Refresh Jobs
            </Button>
          </Box>
        </CardContent>
      </Card>

      {/* Jobs List */}
      <Card>
        <CardContent>
          <Typography variant="h6" gutterBottom>
            Background Jobs
          </Typography>
          
          {jobs.length === 0 ? (
            <Alert severity="info">
              No background jobs found. Create a job using the buttons above.
            </Alert>
          ) : (
            <List>
              {jobs.map((job) => (
                <Accordion key={job.job_id} sx={{ mb: 1 }}>
                  <AccordionSummary expandIcon={<ExpandMore />}>
                    <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, width: '100%' }}>
                      <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                        {getStatusIcon(job.status)}
                        <Chip
                          label={job.status.toUpperCase()}
                          color={getStatusColor(job.status) as any}
                          size="small"
                        />
                      </Box>
                      
                      <Typography variant="body2" sx={{ flexGrow: 1 }}>
                        {formatJobType(job.job_type)}
                      </Typography>
                      
                      <Typography variant="caption" color="text.secondary">
                        {new Date(job.created_at).toLocaleString()}
                      </Typography>
                    </Box>
                  </AccordionSummary>
                  
                  <AccordionDetails>
                    <Box sx={{ width: '100%' }}>
                      {/* Progress Bar */}
                      {(job.status === 'running' || job.status === 'pending') && (
                        <Box sx={{ mb: 2 }}>
                          <Typography variant="body2" gutterBottom>
                            Progress: {job.progress}%
                          </Typography>
                          <LinearProgress variant="determinate" value={job.progress} />
                        </Box>
                      )}
                      
                      {/* Job Message */}
                      <Typography variant="body2" gutterBottom>
                        <strong>Status:</strong> {job.message}
                      </Typography>
                      
                      {/* Job Details */}
                      <Typography variant="body2" gutterBottom>
                        <strong>Job ID:</strong> {job.job_id}
                      </Typography>
                      
                      {job.started_at && (
                        <Typography variant="body2" gutterBottom>
                          <strong>Started:</strong> {new Date(job.started_at).toLocaleString()}
                        </Typography>
                      )}
                      
                      {job.completed_at && (
                        <Typography variant="body2" gutterBottom>
                          <strong>Completed:</strong> {new Date(job.completed_at).toLocaleString()}
                        </Typography>
                      )}
                      
                      {job.error && (
                        <Alert severity="error" sx={{ mt: 1 }}>
                          <strong>Error:</strong> {job.error}
                        </Alert>
                      )}
                      
                      {/* Action Buttons */}
                      <Box sx={{ display: 'flex', gap: 1, mt: 2 }}>
                        <Button
                          size="small"
                          variant="outlined"
                          onClick={() => viewJobDetails(job.job_id)}
                        >
                          View Details
                        </Button>
                        
                        {(job.status === 'pending' || job.status === 'running') && (
                          <Button
                            size="small"
                            variant="outlined"
                            color="error"
                            onClick={() => cancelJob(job.job_id)}
                          >
                            Cancel
                          </Button>
                        )}
                      </Box>
                    </Box>
                  </AccordionDetails>
                </Accordion>
              ))}
            </List>
          )}
        </CardContent>
      </Card>

      {/* Job Details Dialog */}
      <Dialog
        open={jobDialogOpen}
        onClose={() => setJobDialogOpen(false)}
        maxWidth="md"
        fullWidth
      >
        <DialogTitle>
          Job Details - {selectedJob?.job_id}
        </DialogTitle>
        <DialogContent>
          {selectedJob && (
            <Box>
              <Typography variant="body1" gutterBottom>
                <strong>Type:</strong> {formatJobType(selectedJob.job_type)}
              </Typography>
              <Typography variant="body1" gutterBottom>
                <strong>Status:</strong> {selectedJob.status.toUpperCase()}
              </Typography>
              <Typography variant="body1" gutterBottom>
                <strong>Message:</strong> {selectedJob.message}
              </Typography>
              <Typography variant="body1" gutterBottom>
                <strong>Progress:</strong> {selectedJob.progress}%
              </Typography>
              <Typography variant="body1" gutterBottom>
                <strong>Created:</strong> {new Date(selectedJob.created_at).toLocaleString()}
              </Typography>
              
              {selectedJob.started_at && (
                <Typography variant="body1" gutterBottom>
                  <strong>Started:</strong> {new Date(selectedJob.started_at).toLocaleString()}
                </Typography>
              )}
              
              {selectedJob.completed_at && (
                <Typography variant="body1" gutterBottom>
                  <strong>Completed:</strong> {new Date(selectedJob.completed_at).toLocaleString()}
                </Typography>
              )}
              
              {selectedJob.result && (
                <Box sx={{ mt: 2 }}>
                  <Typography variant="h6" gutterBottom>
                    Results:
                  </Typography>
                  <pre style={{ 
                    backgroundColor: '#f5f5f5', 
                    padding: '16px', 
                    borderRadius: '4px',
                    overflow: 'auto',
                    maxHeight: '400px'
                  }}>
                    {JSON.stringify(selectedJob.result, null, 2)}
                  </pre>
                </Box>
              )}
              
              {selectedJob.error && (
                <Alert severity="error" sx={{ mt: 2 }}>
                  <strong>Error:</strong> {selectedJob.error}
                </Alert>
              )}
            </Box>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setJobDialogOpen(false)}>
            Close
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default BackgroundJobManager;
