'use client'; import { useState, useRef, useEffect } from 'react'; import Image from 'next/image'; import Link from 'next/link'; import AnimeRow from './AnimeRow'; import SeasonRow from './SeasonRow'; import { fetchAnimeEpisodes } from '@/lib/api'; export default function AnimeDetails({ anime }) { const [isExpanded, setIsExpanded] = useState(false); const [activeVideo, setActiveVideo] = useState(null); const [activeTab, setActiveTab] = useState('synopsis'); const [synopsisOverflows, setSynopsisOverflows] = useState(false); const [firstEpisodeId, setFirstEpisodeId] = useState(null); const [isLoadingEpisodes, setIsLoadingEpisodes] = useState(false); const synopsisRef = useRef(null); // Check if synopsis overflows when component mounts or when content changes useEffect(() => { if (synopsisRef.current) { const element = synopsisRef.current; setSynopsisOverflows(element.scrollHeight > element.clientHeight); } }, [anime?.info?.description, activeTab]); // Fetch first episode ID when component mounts useEffect(() => { const fetchFirstEpisode = async () => { if (anime?.info?.id) { setIsLoadingEpisodes(true); try { console.log(`[AnimeDetails] Fetching episodes for anime: ${anime.info.id}`); const response = await fetchAnimeEpisodes(anime.info.id); console.log('[AnimeDetails] Episodes response:', response); if (response.episodes && response.episodes.length > 0) { // Log the first episode to check its structure console.log('[AnimeDetails] First episode:', response.episodes[0]); // Get the first episode's id const firstEp = response.episodes[0]; if (firstEp.id) { setFirstEpisodeId(firstEp.id); console.log(`[AnimeDetails] First episode ID found: ${firstEp.id}`); } else if (firstEp.episodeId) { // Fallback to episodeId if id is not available setFirstEpisodeId(firstEp.episodeId); console.log(`[AnimeDetails] Falling back to episodeId: ${firstEp.episodeId}`); } else { // If no episode ID is found in the API response, create a fallback ID const fallbackId = `${anime.info.id}?ep=1`; setFirstEpisodeId(fallbackId); console.log(`[AnimeDetails] Using fallback ID: ${fallbackId}`); } } else if (anime.info.id) { // If no episodes found but anime ID is available, use fallback const fallbackId = `${anime.info.id}?ep=1`; setFirstEpisodeId(fallbackId); console.log(`[AnimeDetails] No episodes found, using fallback ID: ${fallbackId}`); } else { console.warn('[AnimeDetails] No episodes found and no anime ID available'); } } catch (error) { console.error('[AnimeDetails] Error fetching episodes:', error); // Even on error, try to use fallback if (anime.info.id) { const fallbackId = `${anime.info.id}?ep=1`; setFirstEpisodeId(fallbackId); console.log(`[AnimeDetails] Error occurred, using fallback ID: ${fallbackId}`); } } finally { setIsLoadingEpisodes(false); } } }; fetchFirstEpisode(); }, [anime?.info?.id]); // Add a useEffect to debug when and why firstEpisodeId changes useEffect(() => { console.log('[AnimeDetails] firstEpisodeId changed:', firstEpisodeId); }, [firstEpisodeId]); if (!anime?.info) { return null; } const { info, moreInfo, relatedAnime, recommendations, seasons } = anime; const hasCharacters = info.characterVoiceActor?.length > 0 || info.charactersVoiceActors?.length > 0; const hasVideos = info.promotionalVideos && info.promotionalVideos.length > 0; // Build the watch URL based on the first episode ID const watchUrl = firstEpisodeId ? `/watch/${firstEpisodeId}` : ''; // Empty string if no episodes available - this shouldn't happen with our fallback // Add debug log here console.log('[AnimeDetails] Rendered with watchUrl:', watchUrl, 'firstEpisodeId:', firstEpisodeId); // Video modal for promotional videos const VideoModal = ({ video, onClose }) => { if (!video) return null; return (
{moreInfo.synonyms}
{info.description || 'No description available for this anime.'}
{synopsisOverflows && ( )}{item.character.name}
{item.character.cast || 'Main'}
{item.voiceActor.name}
{item.voiceActor.cast || 'Japanese'}