/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */

import { useState, useMemo, useEffect } from 'react';
import { LayoutGroup } from 'motion/react';
import { BrowserRouter, Routes, Route, useNavigate, useSearchParams, useParams, useLocation } from 'react-router-dom';
import Header from './components/Header';
import BrowseView from './components/BrowseView';
import DetailView from './components/DetailView';
import CastView from './components/CastView';
import CastDetailView from './components/CastDetailView';
import AddMediaView from './components/AddMediaView';
import ImporterView from './components/ImporterView';
import SettingsView from './components/SettingsView';
import { MOCK_MEDIA, DETAIL_MEDIA } from './data';
import { Media, Staff, MediaCategory, UserSettings } from './types';
import { fetchAllMedia, fetchMediaById, fetchCastById, convertApiCastToStaff, fetchSettings, updateSettings } from './api';

function AppContent() {
  const navigate = useNavigate();
  const location = useLocation();
  const [searchParams, setSearchParams] = useSearchParams();
  const [activeCategory, setActiveCategory] = useState<MediaCategory>(
    (searchParams.get('category') as MediaCategory) || 'Anime'
  );
  const [selectedMedia, setSelectedMedia] = useState<Media | null>(null);
  const [selectedPerson, setSelectedPerson] = useState<Staff | null>(null);
  const [searchQuery, setSearchQuery] = useState(searchParams.get('search') || '');
  const [enabledCategories, setEnabledCategories] = useState<MediaCategory[]>(['Anime', 'Movies', 'TV Series', 'Music', 'Books', 'Consoles', 'Games', 'Adult']);
  const [settings, setSettings] = useState<UserSettings | null>(null);
  const [customMedia, setCustomMedia] = useState<Media[]>([]);
  const [adultMedia, setAdultMedia] = useState<Media[]>([]);

  // Load media from API on component mount (only when not on cast routes)
  const [apiMedia, setApiMedia] = useState<Media[]>([]);
  
  useEffect(() => {
    const loadSettingsFromApi = async () => {
      try {
        const loadedSettings = await fetchSettings();
        if (loadedSettings) {
          setSettings(loadedSettings);
          setEnabledCategories(loadedSettings.enabledCategories);
        }
      } catch (error) {
        console.error('Failed to load settings from API:', error);
      }
    };
    
    loadSettingsFromApi();
  }, []);

  const reloadSettings = async () => {
    try {
      const loadedSettings = await fetchSettings();
      if (loadedSettings) {
        setSettings(loadedSettings);
        setEnabledCategories(loadedSettings.enabledCategories);
      }
    } catch (error) {
      console.error('Failed to reload settings from API:', error);
    }
  };
  
  useEffect(() => {
    const loadMediaFromApi = async () => {
      try {
        const media = await fetchAllMedia();
        setApiMedia(media);
      } catch (error) {
        console.error('Failed to load media from API:', error);
      }
    };
    
    // Only load media if not on cast routes
    if (!location.pathname.startsWith('/cast')) {
      loadMediaFromApi();
    }
  }, [location.pathname]);

  const toggleCategory = async (category: MediaCategory) => {
    setEnabledCategories(prev => {
      const isEnabling = !prev.includes(category);
      const newList = isEnabling 
        ? [...prev, category] 
        : prev.filter(c => c !== category);
      
      // If we disable the current active category, switch to another enabled one
      if (!isEnabling && activeCategory === category) {
        const nextCategory = newList.find(c => c !== category) || 'Anime';
        setActiveCategory(nextCategory as MediaCategory);
      }
      
      // Save to API
      const baseSettings = settings || {
        enabledCategories: prev,
        itemsPerPage: 20,
        defaultView: 'grid',
        showAdultContent: false,
        autoPlayTrailers: false,
        language: 'en',
        theme: 'system',
      };
      const updatedSettings: UserSettings = {
        ...baseSettings,
        enabledCategories: newList,
      };
      updateSettings(updatedSettings).then(saved => {
        if (saved) {
          setSettings(saved);
        }
      });
      
      return newList;
    });
  };

  const handleCategoryChange = (category: MediaCategory) => {
    setActiveCategory(category);
    setSearchParams({ category });
    navigate('/');
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handleAddMediaView = () => {
    navigate('/add');
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handleImporterView = () => {
    navigate('/import');
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const allMedia = useMemo(() => {
    // Use API data if available, otherwise fall back to mock data
    let list: Media[] = [];
    
    if (apiMedia.length > 0) {
      // API has data, use it
      list = [...apiMedia];
    } else {
      // API is empty, use mock data as fallback
      list = [...MOCK_MEDIA];
    }
    
    // Add custom media and detail media
    list = [...list, ...customMedia];
    if (!list.find(m => m.id === DETAIL_MEDIA.id)) {
      list.push(DETAIL_MEDIA);
    }
    
    // Filter by active category AND ensure it's enabled
    return list.filter(m => m.category === activeCategory && enabledCategories.includes(m.category));
  }, [activeCategory, enabledCategories, customMedia, apiMedia]);

  const handleAddMedia = async () => {
    // Reload all media from API to get the newly added item
    try {
      const media = await fetchAllMedia();
      setApiMedia(media);
    } catch (error) {
      console.error('Failed to reload media from API:', error);
    }
  };

  const allStaff = useMemo(() => {
    const staff: Staff[] = [];
    // Use API data if available, otherwise fall back to mock data
    let baseList: Media[] = [];
    
    if (apiMedia.length > 0) {
      // API has data, use it
      baseList = [...apiMedia];
    } else {
      // API is empty, use mock data as fallback
      baseList = [...MOCK_MEDIA];
    }
    
    // Add custom media and detail media
    baseList = [...baseList, ...customMedia];
    if (!baseList.find(m => m.id === DETAIL_MEDIA.id)) {
      baseList.push(DETAIL_MEDIA);
    }
    
    const enabledMedia = baseList.filter(m => enabledCategories.includes(m.category));
    
    enabledMedia.forEach(media => {
      media.staff?.forEach(s => {
        staff.push({
          ...s,
          mediaId: media.id,
          mediaTitle: media.title
        });
      });
    });
    return staff;
  }, [enabledCategories, customMedia, apiMedia]);

  const filteredMedia = useMemo(() => {
    if (!searchQuery.trim()) return allMedia;
    const query = searchQuery.toLowerCase();
    return allMedia.filter(media => 
      media.title.toLowerCase().includes(query) || 
      media.year.toLowerCase().includes(query) ||
      media.genres?.some(g => g.toLowerCase().includes(query)) ||
      media.studios?.some(s => s.toLowerCase().includes(query))
    );
  }, [allMedia, searchQuery]);

  const handleMediaClick = async (media: Media) => {
    // For adult media, try to fetch detailed data by ID
    if (media.category === 'Adult') {
      try {
        const detailedMedia = await fetchMediaById(parseInt(media.id));
        if (detailedMedia) {
          setSelectedMedia(detailedMedia);
        } else {
          // Fallback to original media if detailed fetch fails
          setSelectedMedia(media);
        }
      } catch (error) {
        console.error('Failed to fetch detailed media:', error);
        setSelectedMedia(media);
      }
    } else {
      // For non-adult media, use the original media
      setSelectedMedia(media);
    }
    navigate(`/media/${media.id}`);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handleBack = () => {
    navigate('/');
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handleCastClick = () => {
    navigate('/cast');
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handlePersonClick = (person: Staff) => {
    // Enrich person with some mock data for the detail page
    const enrichedPerson: Staff = {
      ...person,
      bio: `${person.name} is a renowned ${person.role} with a career spanning over a decade. Known for their versatility and emotional depth, they have become a staple in the industry, particularly for their work in ${person.mediaTitle || 'major productions'}.`,
      birthDate: 'October 14, 1985',
      birthPlace: 'Tokyo, Japan',
      occupations: ['Voice Actor', 'Singer', 'Narrator']
    };
    setSelectedPerson(enrichedPerson);
    navigate(`/cast/${person.id}`);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handleSearch = (query: string) => {
    setSearchQuery(query);
    const params = new URLSearchParams(searchParams);
    if (query) {
      params.set('search', query);
    } else {
      params.delete('search');
    }
    setSearchParams(params);
    navigate('/');
  };

  return (
    <div className="min-h-screen bg-white font-sans selection:bg-[#6d28d9]/20 selection:text-[#6d28d9]">
      <Header
        onSearch={handleSearch}
        activeCategory={activeCategory}
        onCategoryChange={handleCategoryChange}
        enabledCategories={enabledCategories}
        onToggleCategory={toggleCategory}
        transparent={location.pathname.startsWith('/media/') || location.pathname.startsWith('/cast/')}
      />
      
      <main>
        <LayoutGroup>
          <Routes>
            <Route path="/" element={
              <BrowseView 
                mediaList={filteredMedia} 
                onMediaClick={handleMediaClick} 
                activeCategory={activeCategory}
                itemsPerPage={settings?.itemsPerPage}
              />
            } />
            <Route path="/media/:id" element={
              <MediaDetailRoute 
                selectedMedia={selectedMedia} 
                setSelectedMedia={setSelectedMedia}
                allMedia={allMedia}
                onPersonClick={handlePersonClick}
              />
            } />
            <Route path="/cast" element={
              <CastView 
                onPersonClick={handlePersonClick}
                enabledCategories={enabledCategories}
                itemsPerPage={settings?.itemsPerPage}
              />
            } />
            <Route path="/cast/:id" element={
              <CastDetailRoute 
                selectedPerson={selectedPerson}
                setSelectedPerson={setSelectedPerson}
              />
            } />
            <Route path="/add" element={
              <AddMediaView
                activeCategory={activeCategory}
                onAddComplete={handleAddMedia}
              />
            } />
            <Route path="/import" element={
              <ImporterView />
            } />
            <Route path="/settings" element={
              <SettingsView onSettingsSaved={reloadSettings} />
            } />
          </Routes>
        </LayoutGroup>
      </main>

      {/* Footer */}
      <footer className="py-12 px-6 border-t border-zinc-100 bg-zinc-50">
        <div className="max-w-[1600px] mx-auto flex flex-col md:flex-row items-center justify-between gap-6">
          <div className="flex items-center gap-2 text-xl font-black text-zinc-400">
            <div className="w-5 h-5 bg-zinc-300 rounded-full" />
            kyoo
          </div>
          <div className="flex items-center gap-8 text-sm font-bold text-zinc-400">
            <a href="#" className="hover:text-[#6d28d9] transition-colors">Terms</a>
            <a href="#" className="hover:text-[#6d28d9] transition-colors">Privacy</a>
            <a href="#" className="hover:text-[#6d28d9] transition-colors">Contact</a>
          </div>
          <p className="text-xs font-medium text-zinc-400">
            © 2026 Kyoo Media Discovery. All rights reserved.
          </p>
        </div>
      </footer>
    </div>
  );
}

// Helper component for media detail route
function MediaDetailRoute({ selectedMedia, setSelectedMedia, allMedia, onPersonClick }: any) {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();

  useEffect(() => {
    const loadMedia = async () => {
      if (id) {
        // First check if media is in allMedia
        const media = allMedia.find(m => m.id === id);
        if (media) {
          setSelectedMedia(media);
        } else {
          // If not found, fetch from API
          try {
            const fetchedMedia = await fetchMediaById(id);
            if (fetchedMedia) {
              setSelectedMedia(fetchedMedia);
            } else {
              navigate('/');
            }
          } catch (error) {
            console.error('Failed to fetch media:', error);
            navigate('/');
          }
        }
      }
    };
    loadMedia();
  }, [id, allMedia]);

  if (!selectedMedia) return null;

  return (
    <DetailView 
      media={selectedMedia} 
      onPersonClick={onPersonClick}
    />
  );
}

// Helper component for cast detail route
function CastDetailRoute({ selectedPerson, setSelectedPerson }: any) {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();

  useEffect(() => {
    const loadCast = async () => {
      if (id) {
        try {
          const castData = await fetchCastById(id);
          if (castData) {
            const person = convertApiCastToStaff(castData);
            setSelectedPerson(person);
          } else {
            navigate('/cast');
          }
        } catch (error) {
          console.error('Failed to load cast:', error);
          navigate('/cast');
        }
      }
    };
    loadCast();
  }, [id]);

  if (!selectedPerson) return null;

  return (
    <CastDetailView 
      person={selectedPerson} 
      relatedMedia={[]}
    />
  );
}

export default function App() {
  return (
    <BrowserRouter>
      <AppContent />
    </BrowserRouter>
  );
}
