/**
 * @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 AppSidebar from './components/sidebar/AppSidebar';
import { SidebarProvider } from '@/components/ui/sidebar';
import BrowseView from './components/BrowseView';
import DashboardView from './components/DashboardView';
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 Loading from './components/ui/loading';
import MediaDetailRoute from './components/routes/MediaDetailRoute';
import CastDetailRoute from './components/routes/CastDetailRoute';
import CategoryBrowseRoute from './components/routes/CategoryBrowseRoute';
import { MOCK_MEDIA, DETAIL_MEDIA } from './data';
import { Media, Staff, MediaCategory, UserSettings } from './types';
import { fetchAllMedia, fetchMediaById, fetchCastById, convertApiCastToStaff, fetchSettings, updateSettings } from './api';
import { ThemeProvider, useTheme } from './contexts/ThemeContext';
import { Search, Plus, LayoutGrid, List, Filter } from 'lucide-react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { CATEGORY_PATHS, PATH_TO_CATEGORY, DEFAULT_ENABLED_CATEGORIES, DEFAULT_SETTINGS } from './constants';
import { useAppStore } from './store/appStore';

function AppContent() {
  const navigate = useNavigate();
  const location = useLocation();
  const [searchParams, setSearchParams] = useSearchParams();
  const { setTheme } = useTheme();
  
  // Zustand store
  const {
    apiMedia,
    customMedia,
    adultMedia,
    mediaLoading,
    selectedMedia,
    selectedPerson,
    activeCategory,
    enabledCategories,
    searchQuery,
    settings,
    setApiMedia,
    setCustomMedia,
    setAdultMedia,
    setMediaLoading,
    setSelectedMedia,
    setSelectedPerson,
    setActiveCategory,
    setEnabledCategories,
    setSearchQuery,
    setSettings,
  } = useAppStore();


  // Set category from URL path on mount or location change
  useEffect(() => {
    const pathParts = location.pathname.split('/').filter(Boolean);
    if (pathParts.length === 1 && PATH_TO_CATEGORY[pathParts[0]]) {
      const category = PATH_TO_CATEGORY[pathParts[0]];
      if (enabledCategories.includes(category)) {
        setActiveCategory(category);
      }
    }
  }, [location.pathname, enabledCategories, setActiveCategory]);

  useEffect(() => {
    const loadSettingsFromApi = async () => {
      try {
        const loadedSettings = await fetchSettings();
        if (loadedSettings) {
          setSettings(loadedSettings);
          setEnabledCategories(loadedSettings.enabledCategories);
          // Sync theme with theme context
          setTheme(loadedSettings.theme);
          
          // Set custom page title
          if (loadedSettings.pageTitle) {
            document.title = loadedSettings.pageTitle;
          }
          
          // Set custom favicon
          if (loadedSettings.favicon) {
            let faviconLink = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
            if (!faviconLink) {
              faviconLink = document.createElement('link');
              faviconLink.rel = 'icon';
              document.head.appendChild(faviconLink);
            }
            faviconLink.href = loadedSettings.favicon;
          }
        }
      } catch (error) {
        console.error('Failed to load settings from API:', error);
      }
    };

    loadSettingsFromApi();
  }, [setTheme]);

  // Apply custom colors when settings change
  useEffect(() => {
    if (settings?.customColors) {
      const root = document.documentElement;
      const colors = settings.customColors;
      
      if (colors.primary) root.style.setProperty('--color-primary', colors.primary);
      if (colors.secondary) root.style.setProperty('--color-secondary', colors.secondary);
      if (colors.background) root.style.setProperty('--color-background', colors.background);
      if (colors.surface) root.style.setProperty('--color-surface', colors.surface);
      if (colors.text) root.style.setProperty('--color-text', colors.text);
      if (colors.muted) root.style.setProperty('--color-muted', colors.muted);
      if (colors.border) root.style.setProperty('--color-border', colors.border);
    }
  }, [settings?.customColors]);

  const reloadSettings = async () => {
    try {
      const loadedSettings = await fetchSettings();
      if (loadedSettings) {
        setSettings(loadedSettings);
        setEnabledCategories(loadedSettings.enabledCategories);
        // Sync theme with theme context
        setTheme(loadedSettings.theme);
        
        // Set custom page title
        if (loadedSettings.pageTitle) {
          document.title = loadedSettings.pageTitle;
        }
        
        // Set custom favicon
        if (loadedSettings.favicon) {
          let faviconLink = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
          if (!faviconLink) {
            faviconLink = document.createElement('link');
            faviconLink.rel = 'icon';
            document.head.appendChild(faviconLink);
          }
          faviconLink.href = loadedSettings.favicon;
        }
      }
    } catch (error) {
      console.error('Failed to reload settings from API:', error);
    }
  };
  
  useEffect(() => {
    const loadMediaFromApi = async () => {
      setMediaLoading(true);
      try {
        const media = await fetchAllMedia();
        setApiMedia(media);
      } catch (error) {
        console.error('Failed to load media from API:', error);
      } finally {
        setMediaLoading(false);
      }
    };
    
    // Only load media if not on cast routes
    if (!location.pathname.startsWith('/cast')) {
      loadMediaFromApi();
    }
  }, [location.pathname]);

  const toggleCategory = async (category: MediaCategory) => {
    const isEnabling = !enabledCategories.includes(category);
    const newList = isEnabling 
      ? [...enabledCategories, category] 
      : enabledCategories.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);
    }
    
    setEnabledCategories(newList);
    
    // Save to API
    const baseSettings = settings || DEFAULT_SETTINGS;
    const updatedSettings: UserSettings = {
      ...baseSettings,
      enabledCategories: newList,
    };
    updateSettings(updatedSettings).then(saved => {
      if (saved) {
        setSettings(saved);
      }
    });
  };

  const handleCategoryChange = (category: MediaCategory) => {
    setActiveCategory(category);
    navigate(`/${CATEGORY_PATHS[category]}`);
    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' });
  };

  // All media from enabled categories (for cross-category search)
  const allEnabledMedia = 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 enabled categories only (all enabled categories, not just active)
    return list.filter(m => enabledCategories.includes(m.category));
  }, [enabledCategories, customMedia, apiMedia]);

  const allMedia = useMemo(() => {
    // Filter by active category AND ensure it's enabled
    return allEnabledMedia.filter(m => m.category === activeCategory);
  }, [activeCategory, allEnabledMedia]);

  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 handleGridItemSizeChange = async (size: number) => {
    const baseSettings = settings || { ...DEFAULT_SETTINGS, enabledCategories };
    const updatedSettings: UserSettings = {
      ...baseSettings,
      gridItemSize: size,
    };
    updateSettings(updatedSettings).then(saved => {
      if (saved) {
        setSettings(saved);
      }
    });
  };

  const allStaff = useMemo(() => {
    const staff: Staff[] = [];
    const staffIds = new Set<string>(); // Track unique staff to avoid duplicates
    
    // Use allEnabledMedia which already has enabled categories filtered
    allEnabledMedia.forEach(media => {
      media.staff?.forEach(s => {
        // Avoid duplicate staff entries
        if (!staffIds.has(s.id)) {
          staffIds.add(s.id);
          staff.push({
            ...s,
            mediaId: media.id,
            mediaTitle: media.title
          });
        }
      });
    });
    return staff;
  }, [allEnabledMedia]);

  // Search across all enabled media (all categories)
  const searchResultsMedia = useMemo(() => {
    if (!searchQuery.trim()) return [];
    const query = searchQuery.toLowerCase();
    return allEnabledMedia.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)) ||
      media.description?.toLowerCase().includes(query) ||
      media.tags?.some(t => t.toLowerCase().includes(query)) ||
      media.developers?.some(d => d.toLowerCase().includes(query)) ||
      media.platforms?.some(p => p.toLowerCase().includes(query))
    );
  }, [allEnabledMedia, searchQuery]);

  // Search cast members
  const searchResultsCast = useMemo(() => {
    if (!searchQuery.trim()) return [];
    const query = searchQuery.toLowerCase();
    return allStaff.filter(staff => 
      staff.name.toLowerCase().includes(query) || 
      staff.role.toLowerCase().includes(query) ||
      staff.bio?.toLowerCase().includes(query) ||
      staff.occupations?.some(o => o.toLowerCase().includes(query)) ||
      staff.characterName?.toLowerCase().includes(query)
    );
  }, [allStaff, searchQuery]);

  // Legacy filteredMedia for backward compatibility (searches within current category)
  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('/browse');
  };

  // Calculate media counts for sidebar (all categories)
  const mediaCounts = useMemo(() => {
    const counts: Record<string, number> = {};
    // Count all enabled categories using allEnabledMedia
    enabledCategories.forEach(cat => {
      counts[cat] = allEnabledMedia.filter(m => m.category === cat).length;
    });
    // Add favorites count
    counts['favorites'] = allEnabledMedia.filter(m => m.rating && m.rating >= 8).length;
    // Add total count
    counts['all'] = allEnabledMedia.length;
    return counts;
  }, [allEnabledMedia, enabledCategories]);

  // Calculate active filter based on current URL
  const activeFilter = useMemo(() => {
    const path = location.pathname;
    // Map routes to filter IDs
    const routeMap: Record<string, string> = {
      '/anime': 'anime',
      '/movies': 'movies',
      '/tv-series': 'tv-series',
      '/music': 'music',
      '/books': 'books',
      '/adult': 'adult',
      '/consoles': 'consoles',
      '/games': 'games',
    };
    if (routeMap[path]) return routeMap[path];
    if (searchParams.get('favorites') === 'true') return 'favorites';
    return undefined;
  }, [location.pathname, searchParams]);

  return (
    <div className="min-h-screen bg-[#0a0c10] font-sans selection:bg-[#e8466c]/20 selection:text-[#e8466c] flex">
      <SidebarProvider defaultOpen={true}>
        <AppSidebar
          enabledCategories={enabledCategories}
          onToggleCategory={toggleCategory}
          pageTitle={settings?.pageTitle || 'MediaVault'}
          mediaCounts={mediaCounts}
          activeFilter={activeFilter}
        />
        
      <main className="flex-1 flex flex-col relative">
        {/* Header with Search and Add Media */}
        <header className="sticky top-0 z-30 bg-[#0a0c10]/80 backdrop-blur-xl border-b border-white/5 px-6 py-4">
          <div className="flex items-center justify-between gap-4 max-w-[1920px] mx-auto">
            {/* Search Bar */}
            <div className="flex-1 max-w-xl">
              <div className="relative">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500" />
                <Input
                  type="text"
                  placeholder="Search library..."
                  value={searchQuery}
                  onChange={(e) => handleSearch(e.target.value)}
                  className="w-full pl-10 pr-4 py-2 bg-[#1a1d26] border-white/10 rounded-lg text-white placeholder:text-gray-500 focus:border-[#e8466c]/50 focus:ring-[#e8466c]/20"
                />
              </div>
            </div>

            {/* View Toggle and Add Button */}
            <div className="flex items-center gap-3">
              <div className="flex items-center bg-[#1a1d26] rounded-lg p-1 border border-white/10">
                <Button 
                  variant="ghost" 
                  size="icon"
                  className="h-8 w-8 rounded bg-white/10 text-white"
                >
                  <LayoutGrid className="w-4 h-4" />
                </Button>
                <Button 
                  variant="ghost" 
                  size="icon"
                  className="h-8 w-8 rounded text-gray-400 hover:text-white hover:bg-white/5"
                >
                  <List className="w-4 h-4" />
                </Button>
              </div>

              <Button
                onClick={handleAddMediaView}
                className="bg-[#e8466c] hover:bg-[#d13d60] text-white font-medium px-4 py-2 rounded-lg flex items-center gap-2 transition-colors"
              >
                <Plus className="w-4 h-4" />
                Add Media
              </Button>
            </div>
          </div>
        </header>

        <LayoutGroup>
          <Routes>
            <Route path="/" element={
              <DashboardView 
                mediaList={apiMedia.length > 0 ? apiMedia : [...MOCK_MEDIA, ...customMedia, DETAIL_MEDIA].filter(m => enabledCategories.includes(m.category))} 
                onMediaClick={handleMediaClick}
                loading={mediaLoading}
              />
            } />
            <Route path="/browse" element={
              <BrowseView 
                mediaList={searchQuery.trim() ? searchResultsMedia : allMedia} 
                onMediaClick={handleMediaClick} 
                activeCategory={activeCategory}
                itemsPerPage={settings?.itemsPerPage}
                gridItemSize={settings?.gridItemSize}
                onGridItemSizeChange={handleGridItemSizeChange}
                loading={mediaLoading}
                searchResultsCast={searchQuery.trim() ? searchResultsCast : []}
                onCastClick={handlePersonClick}
                searchQuery={searchQuery}
              />
            } />
            <Route path="/:category" element={
              <CategoryBrowseRoute
                mediaList={filteredMedia}
                onMediaClick={handleMediaClick}
                itemsPerPage={settings?.itemsPerPage}
                gridItemSize={settings?.gridItemSize}
                onGridItemSizeChange={handleGridItemSizeChange}
                loading={mediaLoading}
              />
            } />
            <Route path="/media/:id" element={
              <MediaDetailRoute 
                allMedia={allMedia}
                onPersonClick={handlePersonClick}
              />
            } />
            <Route path="/cast" element={
              <CastView 
                onPersonClick={handlePersonClick}
                enabledCategories={enabledCategories}
                itemsPerPage={settings?.itemsPerPage}
              />
            } />
            <Route path="/cast/:id" element={
              <CastDetailRoute />
            } />
            <Route path="/add" element={
              <AddMediaView
                activeCategory={activeCategory}
                enabledCategories={enabledCategories}
                onAddComplete={handleAddMedia}
              />
            } />
            <Route path="/import" element={
              <ImporterView />
            } />
            <Route path="/settings" element={
              <SettingsView onSettingsSaved={reloadSettings} />
            } />
          </Routes>
        </LayoutGroup>

        {/* Footer */}
        <footer className="py-6 px-6 border-t border-white/5 bg-[#0a0c10] mt-auto">
          <div className="max-w-[1920px] mx-auto flex flex-col md:flex-row items-center justify-between gap-4">
            <div className="flex items-center gap-2 text-sm font-medium text-gray-500">
              <span>{mediaCounts.all} total</span>
              <span className="text-gray-700">•</span>
              <span className="text-blue-400">{mediaCounts.movies} Movies</span>
              <span className="text-green-400">{mediaCounts.series} Series</span>
              <span className="text-purple-400">{mediaCounts.games} Games</span>
              <span className="text-red-400">{mediaCounts.adult} Adult</span>
              <span className="text-gray-700">•</span>
              <span className="text-[#e8466c]">{mediaCounts.favorites} Favorites</span>
            </div>
            <p className="text-xs text-gray-600">
              © 2026 MediaVault v1.0.0
            </p>
          </div>
        </footer>
      </main>
      </SidebarProvider>
    </div>
  );
}

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