import { useState, useEffect, ReactElement } from 'react';
import {
  Card,
  CardContent,
  Stack,
  Typography,
  LinearProgress,
  Box,
  Grid,
  Alert,
} from '@mui/material';

import { axiosInstance } from '../../../../../axiosApi';
import { VideoProgressAPI } from 'types';

interface CategoryProgress {
  categoryName: string;
  totalProgress: number;
  videoCount: number;
  averageProgress: number;
}

interface EducationInfoCardProps {
  category: string;
  progress: number;
  totalVideos: number;
  completedVideos: number;
}

const EducationInfoCard = ({
  category,
  progress,
  totalVideos,
  completedVideos,
}: EducationInfoCardCardProps): ReactElement => {
  return (
    <Card sx={{ boxShadow: 4, width: '100%' }}>
      <CardContent>
        <Stack spacing={1}>
          <Typography variant="h6" component="h2">
            {category}
          </Typography>
          <LinearProgress
            variant="determinate"
            value={progress}
            sx={{ height: 8, borderRadius: 5 }}
          />
          <Typography variant="body2" color="text.secondary">
            {completedVideos} of {totalVideos} videos complete
          </Typography>
        </Stack>
      </CardContent>
    </Card>
  );
};

export const EducationInfoCards = () => {
  const [videoProgressData, setVideoProgressData] = useState<VideoProgressAPI[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    // This is a mock function. Replace with your actual API call.
    const fetchVideoProgress = async (): Promise<VideoProgressAPI[]> => {
      try {
        const { data } = await axiosInstance.get(`/videos/progress/`);

        return data;
      } catch (error) {
        return [];
      }
    };

    const loadData = async () => {
      try {
        setLoading(true);
        const data = await fetchVideoProgress();
        setVideoProgressData(data);
      } catch (err) {
        setError('Failed to fetch video progress data.');
        console.error(err);
      } finally {
        setLoading(false);
      }
    };

    loadData();
  }, []);

  const getCategoryProgress = () => {
    if (!videoProgressData) return {};

    const categories: { [key: string]: CategoryProgress } = {};

    videoProgressData.forEach((item) => {
      // Access the category name from the nested object
      const categoryName = item.video.category?.name;
      if (!categoryName) return; // Skip items without a category name

      if (!categories[categoryName]) {
        categories[categoryName] = {
          categoryName: categoryName,
          totalProgress: 0,
          videoCount: 0,
          averageProgress: 0,
        };
      }
      categories[categoryName].totalProgress += item.progress;
      categories[categoryName].videoCount++;
    });

    // Calculate average progress for each category
    for (const key in categories) {
      const categoryInfo = categories[key];
      categoryInfo.averageProgress = Math.round(
        categoryInfo.totalProgress / categoryInfo.videoCount,
      );
    }

    return categories;
  };

  const categoryProgressData = getCategoryProgress();

  if (loading) {
    return <Typography>Loading progress...</Typography>;
  }

  if (error) {
    return <Alert severity="error">{error}</Alert>;
  }
  if (videoProgressData.length === 0) {
    return <Typography>There are no videos yet</Typography>;
  } else {
    return (
      <Stack
        direction={{ sm: 'row' }}
        justifyContent={{ sm: 'space-between' }}
        gap={3.75}
        flexWrap="wrap"
      >
        {Object.values(categoryProgressData).map((data, index) => (
          <Grid size={{ xs: 12, sm: 6, md: 4 }} key={index}>
            <EducationInfoCard
              category={data.categoryName}
              progress={data.averageProgress}
              totalVideos={data.videoCount}
              completedVideos={
                videoProgressData.filter(
                  (item) =>
                    item.video.category?.name === data.categoryName && item.progress === 100,
                ).length
              }
            />
          </Grid>
        ))}
      </Stack>
    );
  }
};
