import { ReactElement, useEffect, useState } from 'react';
import { axiosInstance } from '../../axiosApi';
import DashboardTemplate from 'components/DasboardTemplate';
import CategoryGridTemplate from 'components/CategoryGridTemplate';
import ItemListDetailTemplate from 'components/ItemListDetailTemplate';
import VideoPlayer from 'components/sections/dashboard/Home/Education/VideoPlayer';
import {
  GenericCategory,
  GenericItem,
  VideoAPI,
  VideoCategory,
  VideoItem,
  VideoProgressAPI,
} from 'types';
import VideoCategoryCard from 'components/sections/dashboard/Home/Education/VideoCategoryCard';
import VideoListItem from 'components/sections/dashboard/Home/Education/VideoListItem';
import { AxiosResponse } from 'axios';

const Education = (): ReactElement => {
  const [allVideos, setAllVideos] = useState<VideoItem[]>([]);
  const [videoCategories, setVideoCategories] = useState<VideoCategory[]>([]);

  const updateVideoCategories = (videos: VideoItem[]) => {
    const categoryMap = new Map<
      string,
      { name: string; total: number; completed: number; description: string; imageUrl: string }
    >();
    // Populate category details (you might hardcode descriptions/images or fetch them)
    // For demonstration, let's assume a default image and generate a description
    const defaultCategoryImages: { [key: string]: string } = {
      'Frontend Development': 'https://via.placeholder.com/150/FF5733/FFFFFF?text=Frontend',
      'Backend Development': 'https://via.placeholder.com/150/3366FF/FFFFFF?text=Backend',
      'Database Management': 'https://via.placeholder.com/150/33FF57/FFFFFF?text=Database',
      // Add more as needed
    };
    videos.forEach((video) => {
      const categoryId = video.categoryId;
      if (!categoryMap.has(categoryId)) {
        let categoryName = video.category;
        categoryMap.set(categoryId, {
          name: categoryName,
          total: 0,
          completed: 0,
          description: `Explore ${video.category} concepts and build your skills.`,
          imageUrl:
            defaultCategoryImages[video.category] ||
            'https://via.placeholder.com/150/CCCCCC/000000?text=Category',
        });
      }
      const categoryData = categoryMap.get(categoryId)!;
      categoryData.total += 1;
      if (video.status === 'completed') {
        categoryData.completed += 1;
      }
    });

    const processedCategories: VideoCategory[] = Array.from(categoryMap.entries()).map(
      ([id, data]) => ({
        id, // id is the category name here
        name: data.name,
        description: data.description,
        imageUrl: data.imageUrl,
        totalVideos: data.total,
        completedVideos: data.completed,
        categoryProgress: data.total > 0 ? (data.completed / data.total) * 100 : 0,
      }),
    );
    setVideoCategories(processedCategories);
  };

  // Simulate fetching data from backend
  let fetchedVideos: VideoItem[] = [];

  useEffect(() => {
    // In a real app, you'd make an API call here
    const fetchVideos = async () => {
      // Replace with your actual API call
      try {
        const { data }: AxiosResponse<VideoProgressAPI[]> =
          await axiosInstance.get('/videos/progress/');
        if (data.length > 0) {
          fetchedVideos = data.map((item) => {
            return {
              id: String(item.video.id),
              progress_id: item.id,
              name: item.video.title,
              description: item.video.description,
              category: item.video.category.name,
              categoryId: item.video.category.id,
              status: item.status,
              progress: item.progress,
              videoUrl: item.video.link,
              duration: item.video.duration,
            };
          });
          setAllVideos(fetchedVideos);
        }
      } catch (error) {
        console.log('there was an error', error);
      }

      updateVideoCategories(fetchedVideos);
    };

    fetchVideos();
  }, []);

  const updateVideoItem = async (
    time: number,
    completed: boolean,
    progress: number,
    videoId: number,
  ) => {
    const newPossibleStatus: string = completed ? 'complete' : 'in-progress';
    // we already saved the data to the backend, so just update it on the Frontend
    const updatedVideoItems: VideoItem[] = allVideos.map((item) => {
      if (item.id === videoId) {
        return {
          ...item,
          progress: progress,
          // if the video is already completed, we don't want to reset it
          status: item.status === 'completed' ? item.status : newPossibleStatus,
        };
      }
      return item;
    });
    updateVideoCategories(updatedVideoItems);
    setAllVideos(updatedVideoItems);
  };

  return (
    <DashboardTemplate<VideoCategory, VideoItem>
      pageTitle="Educational Videos"
      data={{ categories: videoCategories, items: allVideos }}
      renderCategoryGrid={(categories, onSelectCategory) => (
        <CategoryGridTemplate
          categories={categories}
          onSelectCategory={(id) => onSelectCategory(id)}
          renderCategoryCard={(category, onSelect) => (
            <VideoCategoryCard category={category as VideoCategory} onSelectCategory={onSelect} />
          )}
        />
      )}
      renderItemListDetail={(selectedCategory, itemsInSelectedCategory, onBack) => (
        <ItemListDetailTemplate
          category={selectedCategory}
          items={itemsInSelectedCategory}
          onBack={onBack}
          renderListItem={(item, isSelected, onSelect) => (
            <VideoListItem
              video={item as VideoItem}
              isSelected={isSelected}
              onSelect={() => {
                console.log('selecting');
                onSelect(item.id);
              }}
            />
          )}
          renderItemDetail={(item) => (
            <VideoPlayer video={item as VideoItem} updateVideoItem={updateVideoItem} />
          )}
        />
      )}
    />
  );
};

export default Education;
