import { Staff, MediaCategory } from '@/types';
import { useState, useMemo, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { Search, ArrowUpDown, User, ChevronLeft, ChevronRight, X, Filter } from 'lucide-react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import Loading from '@/components/ui/loading';
import { motion, AnimatePresence } from 'motion/react';
import { cn } from '@/lib/utils';
import { fetchAllCast } from '@/api';

interface CastViewProps {
  onPersonClick: (person: Staff) => void;
  enabledCategories: MediaCategory[];
  itemsPerPage?: number;
}

export default function CastView({ onPersonClick, enabledCategories, itemsPerPage: initialItemsPerPage = 12 }: CastViewProps) {
  const navigate = useNavigate();
  const [staffList, setStaffList] = useState<Staff[]>([]);
  const [loading, setLoading] = useState(true);
  const [searchQuery, setSearchQuery] = useState(() => {
    return localStorage.getItem('castSearchQuery') || '';
  });
  const [sortBy, setSortBy] = useState<'name' | 'role' | 'birthDate' | 'height' | 'roleCount'>(() => {
    return (localStorage.getItem('castSortBy') as 'name' | 'role' | 'birthDate' | 'height' | 'roleCount') || 'roleCount';
  });
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>(() => {
    return (localStorage.getItem('castSortOrder') as 'asc' | 'desc') || 'desc';
  });
  const [filterOccupation, setFilterOccupation] = useState<string>(() => {
    return localStorage.getItem('castFilterOccupation') || '';
  });
  const [filterMediaType, setFilterMediaType] = useState<string>(() => {
    return localStorage.getItem('castFilterMediaType') || '';
  });
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(initialItemsPerPage);
  const [showFilters, setShowFilters] = useState(false);

  // Sync itemsPerPage with prop when API settings are loaded
  useEffect(() => {
    if (initialItemsPerPage) {
      setItemsPerPage(initialItemsPerPage);
    }
  }, [initialItemsPerPage]);

  // Persist filters and sorts
  useEffect(() => {
    localStorage.setItem('castSearchQuery', searchQuery);
  }, [searchQuery]);

  useEffect(() => {
    localStorage.setItem('castSortBy', sortBy);
  }, [sortBy]);

  useEffect(() => {
    localStorage.setItem('castSortOrder', sortOrder);
  }, [sortOrder]);

  useEffect(() => {
    localStorage.setItem('castFilterOccupation', filterOccupation);
  }, [filterOccupation]);

  useEffect(() => {
    localStorage.setItem('castFilterMediaType', filterMediaType);
  }, [filterMediaType]);

  const handleResetFilters = () => {
    setSearchQuery('');
    setSortBy('roleCount');
    setSortOrder('desc');
    setFilterOccupation('');
    setFilterMediaType('');
  };

  const hasActiveFilters = searchQuery || filterOccupation || filterMediaType || sortBy !== 'roleCount' || sortOrder !== 'desc';

  useEffect(() => {
    const loadCast = async () => {
      try {
        const cast = await fetchAllCast();
        setStaffList(cast);
      } catch (error) {
        console.error('Failed to load cast:', error);
      } finally {
        setLoading(false);
      }
    };
    loadCast();
  }, []);

  const filteredStaff = useMemo(() => {
    let list = staffList.filter(s => {
      // Hide actors without linked media
      if (!s.filmography || s.filmography.length === 0) {
        return false;
      }
      
      // Filter by enabled categories based on media_types
      if (s.media_types && s.media_types.length > 0) {
        const hasEnabledMediaType = s.media_types.some(type => {
          const category = type.charAt(0).toUpperCase() + type.slice(1);
          return enabledCategories.includes(category as MediaCategory);
        });
        if (!hasEnabledMediaType) {
          return false;
        }
      }
      
      // Filter by occupation
      if (filterOccupation && !s.occupations?.includes(filterOccupation)) {
        return false;
      }
      
      // Filter by media type
      if (filterMediaType && !s.media_types?.includes(filterMediaType)) {
        return false;
      }
      
      return s.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
             s.role.toLowerCase().includes(searchQuery.toLowerCase()) ||
             s.mediaTitle?.toLowerCase().includes(searchQuery.toLowerCase());
    });

    // Sort
    list.sort((a, b) => {
      let comparison = 0;
      
      if (sortBy === 'name' || sortBy === 'role') {
        comparison = a[sortBy].localeCompare(b[sortBy]);
      } else if (sortBy === 'birthDate') {
        const dateA = a.birthDate ? new Date(a.birthDate).getTime() : 0;
        const dateB = b.birthDate ? new Date(b.birthDate).getTime() : 0;
        comparison = dateA - dateB;
      } else if (sortBy === 'height') {
        const heightA = a.height || 0;
        const heightB = b.height || 0;
        comparison = heightA - heightB;
      } else if (sortBy === 'roleCount') {
        const roleCountA = a.filmography?.length || 0;
        const roleCountB = b.filmography?.length || 0;
        comparison = roleCountA - roleCountB;
      }
      
      return sortOrder === 'desc' ? -comparison : comparison;
    });

    return list;
  }, [staffList, searchQuery, sortBy, sortOrder, filterOccupation, filterMediaType, enabledCategories]);

  // Get unique occupations and media types for filters
  const uniqueOccupations = useMemo(() => {
    const occupations = new Set<string>();
    staffList.forEach(s => s.occupations?.forEach(o => occupations.add(o)));
    return Array.from(occupations).sort();
  }, [staffList]);

  const uniqueMediaTypes = useMemo(() => {
    const mediaTypes = new Set<string>();
    staffList.forEach(s => s.media_types?.forEach(m => mediaTypes.add(m)));
    return Array.from(mediaTypes).sort();
  }, [staffList]);

  // Reset to first page when filters or sorting change
  useEffect(() => {
    setCurrentPage(1);
  }, [searchQuery, sortBy, sortOrder, filterOccupation, filterMediaType, itemsPerPage]);

  const totalPages = Math.ceil(filteredStaff.length / itemsPerPage);

  const paginatedStaff = useMemo(() => {
    const startIndex = (currentPage - 1) * itemsPerPage;
    return filteredStaff.slice(startIndex, startIndex + itemsPerPage);
  }, [filteredStaff, currentPage, itemsPerPage]);

  const handlePrevPage = () => {
    setCurrentPage((prev) => Math.max(prev - 1, 1));
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handleNextPage = () => {
    setCurrentPage((prev) => Math.min(prev + 1, totalPages));
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  return (
    <div className="pt-24 pb-12 px-6 max-w-[1920px] mx-auto">
      <div className="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-12">
        <div>
          <h1 className="text-5xl font-black text-foreground mb-3 bg-clip-text text-transparent bg-gradient-to-r from-foreground to-foreground/70">
            Cast & Staff
          </h1>
          <p className="text-muted-foreground font-medium text-lg">Discover the people behind your favorite media</p>
        </div>

        <div className="flex items-center gap-3">
          <div className="relative">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground" size={18} />
            <Input 
              placeholder="Search cast..." 
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="pl-10 w-full md:w-[300px] bg-muted/50 backdrop-blur-sm border-none rounded-full h-11"
            />
          </div>
          <Button 
            variant={showFilters ? 'default' : 'outline'}
            size="icon" 
            className={`rounded-xl h-11 w-11 transition-all duration-300 ${showFilters ? 'bg-gradient-to-br from-[#6d28d9] to-[#8b5cf6] text-white border-[#6d28d9]' : 'border-border hover:border-[#6d28d9]/50'}`}
            onClick={() => setShowFilters(!showFilters)}
          >
            <Filter size={20} />
          </Button>
          <Button 
            variant="outline" 
            size="icon" 
            className="rounded-xl h-11 w-11 border-border hover:border-[#6d28d9]/50 transition-all duration-300"
            onClick={() => setSortOrder(prev => prev === 'asc' ? 'desc' : 'asc')}
          >
            <ArrowUpDown size={20} />
          </Button>
          {hasActiveFilters && (
            <Button 
              variant="ghost" 
              size="icon" 
              className="rounded-xl h-11 w-11 text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-all duration-300"
              onClick={handleResetFilters}
              title="Reset filters"
            >
              <X size={20} />
            </Button>
          )}
        </div>
      </div>

      {showFilters && (
        <motion.div 
          initial={{ opacity: 0, height: 0 }}
          animate={{ opacity: 1, height: 'auto' }}
          exit={{ opacity: 0, height: 0 }}
          className="bg-muted/50 backdrop-blur-sm rounded-2xl p-6 mb-6 border border-border/50"
        >
          <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
            <div>
              <label className="text-sm font-bold text-foreground mb-2 block">Sort By</label>
              <select 
                value={sortBy}
                onChange={(e) => setSortBy(e.target.value as any)}
                className="w-full bg-background border-border/50 rounded-xl px-4 py-3 text-sm font-bold text-foreground focus:ring-2 focus:ring-[#6d28d9]/50 outline-none"
              >
                <option value="name">Name</option>
                <option value="role">Role</option>
                <option value="birthDate">Birth Date</option>
                <option value="height">Height</option>
                <option value="roleCount">Role Count</option>
              </select>
            </div>
            <div>
              <label className="text-sm font-bold text-foreground mb-2 block">Occupation</label>
              <select 
                value={filterOccupation}
                onChange={(e) => setFilterOccupation(e.target.value)}
                className="w-full bg-background border-border/50 rounded-xl px-4 py-3 text-sm font-bold text-foreground focus:ring-2 focus:ring-[#6d28d9]/50 outline-none"
              >
                <option value="">All Occupations</option>
                {uniqueOccupations.map(occ => (
                  <option key={occ} value={occ}>{occ}</option>
                ))}
              </select>
            </div>
            <div>
              <label className="text-sm font-bold text-foreground mb-2 block">Media Type</label>
              <select 
                value={filterMediaType}
                onChange={(e) => setFilterMediaType(e.target.value)}
                className="w-full bg-background border-border/50 rounded-xl px-4 py-3 text-sm font-bold text-foreground focus:ring-2 focus:ring-[#6d28d9]/50 outline-none"
              >
                <option value="">All Media Types</option>
                {uniqueMediaTypes.map(type => (
                  <option key={type} value={type}>{type}</option>
                ))}
              </select>
            </div>
          </div>
          <div className="mt-4 flex items-center gap-2">
            {searchQuery && (
              <Badge variant="secondary" className="gap-1 bg-[#6d28d9]/10 text-[#6d28d9] border-[#6d28d9]/20">
                Search: {searchQuery}
                <button onClick={() => setSearchQuery('')} className="hover:text-foreground">
                  <X size={12} />
                </button>
              </Badge>
            )}
            {filterOccupation && (
              <Badge variant="secondary" className="gap-1 bg-[#6d28d9]/10 text-[#6d28d9] border-[#6d28d9]/20">
                Occupation: {filterOccupation}
                <button onClick={() => setFilterOccupation('')} className="hover:text-foreground">
                  <X size={12} />
                </button>
              </Badge>
            )}
            {filterMediaType && (
              <Badge variant="secondary" className="gap-1 bg-[#6d28d9]/10 text-[#6d28d9] border-[#6d28d9]/20">
                Media Type: {filterMediaType}
                <button onClick={() => setFilterMediaType('')} className="hover:text-foreground">
                  <X size={12} />
                </button>
              </Badge>
            )}
            {(sortBy !== 'name' || sortOrder !== 'asc') && (
              <Badge variant="secondary" className="gap-1 bg-[#6d28d9]/10 text-[#6d28d9] border-[#6d28d9]/20">
                Sort: {sortBy} ({sortOrder})
                <button onClick={() => { setSortBy('name'); setSortOrder('asc'); }} className="hover:text-foreground">
                  <X size={12} />
                </button>
              </Badge>
            )}
          </div>
        </motion.div>
      )}

      {loading ? (
        <Loading message="Loading cast..." />
      ) : filteredStaff.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-32 text-muted-foreground">
          <div className="w-20 h-20 bg-muted/50 rounded-2xl flex items-center justify-center mb-6 backdrop-blur-sm border border-border/50">
            <User size={40} />
          </div>
          <p className="text-xl font-bold">No cast members found</p>
        </div>
      ) : (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
          <AnimatePresence mode="popLayout">
            {paginatedStaff.map((person) => (
              <motion.div 
                key={person.id}
                layout
                initial={{ opacity: 0, scale: 0.9 }}
                animate={{ opacity: 1, scale: 1 }}
                exit={{ opacity: 0, scale: 0.9 }}
                className="group bg-card rounded-2xl p-5 shadow-sm border border-border/50 hover:shadow-xl hover:border-[#6d28d9]/30 hover:shadow-[#6d28d9]/10 transition-all duration-300 cursor-pointer"
                onClick={() => onPersonClick(person)}
              >
                <div className="flex items-center gap-4 mb-4">
                  <div className="w-16 h-16 rounded-full overflow-hidden border-2 border-border/50 group-hover:border-[#6d28d9] transition-colors duration-300">
                    <img 
                      src={person.photo} 
                      alt={person.name} 
                      className="w-full h-full object-cover"
                      referrerPolicy="no-referrer"
                    />
                  </div>
                  <div className="min-w-0 flex-1">
                    <h3 className="font-black text-foreground truncate group-hover:text-[#6d28d9] transition-colors duration-300">
                      {person.name}
                    </h3>
                    <p className="text-xs font-bold text-muted-foreground uppercase tracking-wider">
                      {person.role}
                    </p>
                  </div>
                  {person.filmography && person.filmography.length > 0 && (
                    <Badge variant="outline" className="border-[#6d28d9]/30 text-[#6d28d9] font-bold text-[10px] px-2 py-0.5 shrink-0">
                      {person.filmography.length}
                    </Badge>
                  )}
                </div>

                {person.filmography && person.filmography.length > 0 && (
                  <div className="bg-muted/50 backdrop-blur-sm rounded-xl p-3 flex items-center gap-3 border border-border/30">
                    <div className="w-10 h-12 rounded-lg overflow-hidden shrink-0 bg-background border border-border/30">
                      <img 
                        src={person.filmography[0].poster || person.photo} 
                        alt={person.filmography[0].title} 
                        className="w-full h-full object-cover"
                        referrerPolicy="no-referrer"
                      />
                    </div>
                    <div className="min-w-0">
                      <p className="text-[10px] font-black text-muted-foreground uppercase tracking-widest leading-none mb-1">Latest Role</p>
                      <p className="text-xs font-bold text-foreground truncate">{person.filmography[0].title}</p>
                      <p className="text-[10px] text-[#6d28d9] font-bold truncate mt-1">{person.filmography[0].role}</p>
                    </div>
                  </div>
                )}
              </motion.div>
            ))}
          </AnimatePresence>
        </div>
      )}

      {/* Pagination Controls */}
      {filteredStaff.length > 0 && (
        <div className="mt-12 flex flex-col sm:flex-row items-center justify-between gap-6 border-t border-border/50 pt-8">
          <div className="flex items-center gap-4">
            <span className="text-sm text-muted-foreground font-medium">Items per page:</span>
            <select 
              value={itemsPerPage}
              onChange={(e) => {
                setItemsPerPage(Number(e.target.value));
              }}
              className="bg-muted/50 backdrop-blur-sm border-none rounded-xl px-3 py-2 text-sm font-bold text-foreground focus:ring-2 focus:ring-[#6d28d9]/50 outline-none"
            >
              {[12, 20, 36, 48, 60].map(size => (
                <option key={size} value={size}>{size}</option>
              ))}
            </select>
          </div>

          <div className="flex items-center gap-6">
            <Button 
              variant="outline" 
              size="sm" 
              onClick={handlePrevPage}
              disabled={currentPage === 1}
              className="gap-2 font-bold border-border hover:border-[#6d28d9]/50 rounded-xl transition-all duration-300"
            >
              <ChevronLeft size={16} />
              Previous
            </Button>
            
            <div className="flex items-center gap-2">
              <span className="text-sm font-black text-[#6d28d9]">{currentPage}</span>
              <span className="text-sm text-muted-foreground font-medium">of</span>
              <span className="text-sm font-bold text-foreground">{totalPages || 1}</span>
            </div>

            <Button 
              variant="outline" 
              size="sm" 
              onClick={handleNextPage}
              disabled={currentPage === totalPages || totalPages === 0}
              className="gap-2 font-bold border-border hover:border-[#6d28d9]/50 rounded-xl transition-all duration-300"
            >
              Next
              <ChevronRight size={16} />
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
