import { Ionicons } from "@expo/vector-icons";
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { Image } from "expo-image";
import { useRouter } from "expo-router";
import { useAtom } from "jotai";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import {
  Dimensions,
  FlatList,
  Platform,
  ScrollView,
  TouchableOpacity,
  View,
} from "react-native";
import { Slider } from "react-native-awesome-slider";
import { useSharedValue } from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Text } from "@/components/common/Text";
import { apiAtom } from "@/providers/JellyfinProvider";
import {
  type RepeatMode,
  useMusicPlayer,
} from "@/providers/MusicPlayerProvider";
import { formatDuration } from "@/utils/time";

const { width: SCREEN_WIDTH } = Dimensions.get("window");
const ARTWORK_SIZE = SCREEN_WIDTH - 80;

type ViewMode = "player" | "queue";

export default function NowPlayingScreen() {
  const [api] = useAtom(apiAtom);
  const router = useRouter();
  const insets = useSafeAreaInsets();
  const [viewMode, setViewMode] = useState<ViewMode>("player");

  const {
    currentTrack,
    queue,
    queueIndex,
    isPlaying,
    progress,
    duration,
    repeatMode,
    shuffleEnabled,
    togglePlayPause,
    next,
    previous,
    seek,
    setRepeatMode,
    toggleShuffle,
    jumpToIndex,
    removeFromQueue,
    stop,
  } = useMusicPlayer();

  const sliderProgress = useSharedValue(0);
  const sliderMin = useSharedValue(0);
  const sliderMax = useSharedValue(1);

  useEffect(() => {
    sliderProgress.value = progress;
  }, [progress, sliderProgress]);

  useEffect(() => {
    sliderMax.value = duration > 0 ? duration : 1;
  }, [duration, sliderMax]);

  const imageUrl = useMemo(() => {
    if (!api || !currentTrack) return null;
    const albumId = currentTrack.AlbumId || currentTrack.ParentId;
    if (albumId) {
      return `${api.basePath}/Items/${albumId}/Images/Primary?maxHeight=600&maxWidth=600`;
    }
    return `${api.basePath}/Items/${currentTrack.Id}/Images/Primary?maxHeight=600&maxWidth=600`;
  }, [api, currentTrack]);

  const progressText = useMemo(() => {
    const progressTicks = progress * 10000000;
    return formatDuration(progressTicks);
  }, [progress]);

  const durationText = useMemo(() => {
    const durationTicks = duration * 10000000;
    return formatDuration(durationTicks);
  }, [duration]);

  const handleSliderComplete = useCallback(
    (value: number) => {
      seek(value);
    },
    [seek],
  );

  const handleClose = useCallback(() => {
    router.back();
  }, [router]);

  const handleStop = useCallback(() => {
    stop();
    router.back();
  }, [stop, router]);

  const cycleRepeatMode = useCallback(() => {
    const modes: RepeatMode[] = ["off", "all", "one"];
    const currentIndex = modes.indexOf(repeatMode);
    const nextMode = modes[(currentIndex + 1) % modes.length];
    setRepeatMode(nextMode);
  }, [repeatMode, setRepeatMode]);

  const getRepeatIcon = (): string => {
    switch (repeatMode) {
      case "one":
        return "repeat";
      case "all":
        return "repeat";
      default:
        return "repeat";
    }
  };

  const canGoNext = queueIndex < queue.length - 1 || repeatMode === "all";
  const canGoPrevious = queueIndex > 0 || progress > 3 || repeatMode === "all";

  if (!currentTrack) {
    return (
      <View
        className='flex-1 bg-[#121212] items-center justify-center'
        style={{
          paddingTop: Platform.OS === "android" ? insets.top : 0,
          paddingBottom: Platform.OS === "android" ? insets.bottom : 0,
        }}
      >
        <Text className='text-neutral-500'>No track playing</Text>
      </View>
    );
  }

  return (
    <View
      className='flex-1 bg-[#121212]'
      style={{
        paddingTop: Platform.OS === "android" ? insets.top : 0,
        paddingBottom: Platform.OS === "android" ? insets.bottom : 0,
      }}
    >
      {/* Header */}
      <View className='flex-row items-center justify-between px-4 pt-3 pb-2'>
        <TouchableOpacity
          onPress={handleClose}
          hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
          className='p-2'
        >
          <Ionicons name='chevron-down' size={28} color='white' />
        </TouchableOpacity>

        <View className='flex-row'>
          <TouchableOpacity
            onPress={() => setViewMode("player")}
            className='px-3 py-1'
          >
            <Text
              className={
                viewMode === "player"
                  ? "text-white font-semibold"
                  : "text-neutral-500"
              }
            >
              Now Playing
            </Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => setViewMode("queue")}
            className='px-3 py-1'
          >
            <Text
              className={
                viewMode === "queue"
                  ? "text-white font-semibold"
                  : "text-neutral-500"
              }
            >
              Queue ({queue.length})
            </Text>
          </TouchableOpacity>
        </View>

        <TouchableOpacity
          onPress={handleStop}
          hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
          className='p-2'
        >
          <Ionicons name='close' size={24} color='#666' />
        </TouchableOpacity>
      </View>

      {viewMode === "player" ? (
        <PlayerView
          api={api}
          currentTrack={currentTrack}
          imageUrl={imageUrl}
          sliderProgress={sliderProgress}
          sliderMin={sliderMin}
          sliderMax={sliderMax}
          progressText={progressText}
          durationText={durationText}
          isPlaying={isPlaying}
          repeatMode={repeatMode}
          shuffleEnabled={shuffleEnabled}
          canGoNext={canGoNext}
          canGoPrevious={canGoPrevious}
          onSliderComplete={handleSliderComplete}
          onTogglePlayPause={togglePlayPause}
          onNext={next}
          onPrevious={previous}
          onCycleRepeat={cycleRepeatMode}
          onToggleShuffle={toggleShuffle}
          getRepeatIcon={getRepeatIcon}
          queue={queue}
          queueIndex={queueIndex}
        />
      ) : (
        <QueueView
          api={api}
          queue={queue}
          queueIndex={queueIndex}
          onJumpToIndex={jumpToIndex}
          onRemoveFromQueue={removeFromQueue}
        />
      )}
    </View>
  );
}

interface PlayerViewProps {
  api: any;
  currentTrack: BaseItemDto;
  imageUrl: string | null;
  sliderProgress: any;
  sliderMin: any;
  sliderMax: any;
  progressText: string;
  durationText: string;
  isPlaying: boolean;
  repeatMode: RepeatMode;
  shuffleEnabled: boolean;
  canGoNext: boolean;
  canGoPrevious: boolean;
  onSliderComplete: (value: number) => void;
  onTogglePlayPause: () => void;
  onNext: () => void;
  onPrevious: () => void;
  onCycleRepeat: () => void;
  onToggleShuffle: () => void;
  getRepeatIcon: () => string;
  queue: BaseItemDto[];
  queueIndex: number;
}

const PlayerView: React.FC<PlayerViewProps> = ({
  currentTrack,
  imageUrl,
  sliderProgress,
  sliderMin,
  sliderMax,
  progressText,
  durationText,
  isPlaying,
  repeatMode,
  shuffleEnabled,
  canGoNext,
  canGoPrevious,
  onSliderComplete,
  onTogglePlayPause,
  onNext,
  onPrevious,
  onCycleRepeat,
  onToggleShuffle,
  getRepeatIcon,
  queue,
  queueIndex,
}) => {
  return (
    <ScrollView className='flex-1 px-6' showsVerticalScrollIndicator={false}>
      {/* Album artwork */}
      <View
        className='self-center mb-8 mt-4'
        style={{
          width: ARTWORK_SIZE,
          height: ARTWORK_SIZE,
          borderRadius: 12,
          overflow: "hidden",
          backgroundColor: "#1a1a1a",
          shadowColor: "#000",
          shadowOffset: { width: 0, height: 8 },
          shadowOpacity: 0.4,
          shadowRadius: 16,
          elevation: 10,
        }}
      >
        {imageUrl ? (
          <Image
            source={{ uri: imageUrl }}
            style={{ width: "100%", height: "100%" }}
            contentFit='cover'
            cachePolicy='memory-disk'
          />
        ) : (
          <View className='flex-1 items-center justify-center bg-neutral-800'>
            <Ionicons name='musical-note' size={80} color='#666' />
          </View>
        )}
      </View>

      {/* Track info */}
      <View className='mb-6'>
        <Text numberOfLines={1} className='text-white text-2xl font-bold'>
          {currentTrack.Name}
        </Text>
        <Text numberOfLines={1} className='text-purple-400 text-lg mt-1'>
          {currentTrack.Artists?.join(", ") || currentTrack.AlbumArtist}
        </Text>
        {currentTrack.Album && (
          <Text numberOfLines={1} className='text-neutral-500 text-sm mt-1'>
            {currentTrack.Album}
          </Text>
        )}
      </View>

      {/* Progress slider */}
      <View className='mb-4'>
        <Slider
          theme={{
            maximumTrackTintColor: "#333",
            minimumTrackTintColor: "#9334E9",
            bubbleBackgroundColor: "#9334E9",
            bubbleTextColor: "#fff",
          }}
          progress={sliderProgress}
          minimumValue={sliderMin}
          maximumValue={sliderMax}
          onSlidingComplete={onSliderComplete}
          thumbWidth={16}
          sliderHeight={6}
          containerStyle={{ borderRadius: 10 }}
          renderBubble={() => null}
        />
        <View className='flex flex-row justify-between px-1 mt-2'>
          <Text className='text-neutral-500 text-xs'>{progressText}</Text>
          <Text className='text-neutral-500 text-xs'>{durationText}</Text>
        </View>
      </View>

      {/* Main Controls */}
      <View className='flex flex-row items-center justify-center mb-4'>
        <TouchableOpacity
          onPress={onPrevious}
          disabled={!canGoPrevious}
          className='p-4'
          style={{ opacity: canGoPrevious ? 1 : 0.3 }}
        >
          <Ionicons name='play-skip-back' size={32} color='white' />
        </TouchableOpacity>

        <TouchableOpacity
          onPress={onTogglePlayPause}
          className='mx-8 bg-white rounded-full p-4'
        >
          <Ionicons
            name={isPlaying ? "pause" : "play"}
            size={36}
            color='#121212'
            style={isPlaying ? {} : { marginLeft: 4 }}
          />
        </TouchableOpacity>

        <TouchableOpacity
          onPress={onNext}
          disabled={!canGoNext}
          className='p-4'
          style={{ opacity: canGoNext ? 1 : 0.3 }}
        >
          <Ionicons name='play-skip-forward' size={32} color='white' />
        </TouchableOpacity>
      </View>

      {/* Shuffle & Repeat Controls */}
      <View className='flex flex-row items-center justify-center mb-6'>
        <TouchableOpacity onPress={onToggleShuffle} className='p-3 mx-4'>
          <Ionicons
            name='shuffle'
            size={24}
            color={shuffleEnabled ? "#9334E9" : "#666"}
          />
        </TouchableOpacity>

        <TouchableOpacity onPress={onCycleRepeat} className='p-3 mx-4 relative'>
          <Ionicons
            name={getRepeatIcon() as any}
            size={24}
            color={repeatMode !== "off" ? "#9334E9" : "#666"}
          />
          {repeatMode === "one" && (
            <View className='absolute -top-1 -right-1 bg-purple-600 rounded-full w-4 h-4 items-center justify-center'>
              <Text className='text-white text-[10px] font-bold'>1</Text>
            </View>
          )}
        </TouchableOpacity>
      </View>

      {/* Queue info */}
      {queue.length > 1 && (
        <View className='items-center mb-8'>
          <Text className='text-neutral-500 text-sm'>
            {queueIndex + 1} of {queue.length}
          </Text>
        </View>
      )}
    </ScrollView>
  );
};

interface QueueViewProps {
  api: any;
  queue: BaseItemDto[];
  queueIndex: number;
  onJumpToIndex: (index: number) => void;
  onRemoveFromQueue: (index: number) => void;
}

const QueueView: React.FC<QueueViewProps> = ({
  api,
  queue,
  queueIndex,
  onJumpToIndex,
  onRemoveFromQueue,
}) => {
  const renderQueueItem = useCallback(
    ({ item, index }: { item: BaseItemDto; index: number }) => {
      const isCurrentTrack = index === queueIndex;
      const isPast = index < queueIndex;

      const albumId = item.AlbumId || item.ParentId;
      const imageUrl = api
        ? albumId
          ? `${api.basePath}/Items/${albumId}/Images/Primary?maxHeight=80&maxWidth=80`
          : `${api.basePath}/Items/${item.Id}/Images/Primary?maxHeight=80&maxWidth=80`
        : null;

      return (
        <TouchableOpacity
          onPress={() => onJumpToIndex(index)}
          className={`flex-row items-center px-4 py-3 ${isCurrentTrack ? "bg-purple-900/30" : ""}`}
          style={{ opacity: isPast ? 0.5 : 1 }}
        >
          {/* Track number / Now playing indicator */}
          <View className='w-8 items-center'>
            {isCurrentTrack ? (
              <Ionicons name='musical-note' size={16} color='#9334E9' />
            ) : (
              <Text className='text-neutral-500 text-sm'>{index + 1}</Text>
            )}
          </View>

          {/* Album art */}
          <View className='w-12 h-12 rounded overflow-hidden bg-neutral-800 mr-3'>
            {imageUrl ? (
              <Image
                source={{ uri: imageUrl }}
                style={{ width: "100%", height: "100%" }}
                contentFit='cover'
                cachePolicy='memory-disk'
              />
            ) : (
              <View className='flex-1 items-center justify-center'>
                <Ionicons name='musical-note' size={16} color='#666' />
              </View>
            )}
          </View>

          {/* Track info */}
          <View className='flex-1 mr-2'>
            <Text
              numberOfLines={1}
              className={`text-base ${isCurrentTrack ? "text-purple-400 font-semibold" : "text-white"}`}
            >
              {item.Name}
            </Text>
            <Text numberOfLines={1} className='text-neutral-500 text-sm'>
              {item.Artists?.join(", ") || item.AlbumArtist}
            </Text>
          </View>

          {/* Remove button (not for current track) */}
          {!isCurrentTrack && (
            <TouchableOpacity
              onPress={() => onRemoveFromQueue(index)}
              hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
              className='p-2'
            >
              <Ionicons name='close' size={20} color='#666' />
            </TouchableOpacity>
          )}
        </TouchableOpacity>
      );
    },
    [api, queueIndex, onJumpToIndex, onRemoveFromQueue],
  );

  const _upNext = queue.slice(queueIndex + 1);
  const history = queue.slice(0, queueIndex);

  return (
    <FlatList
      data={queue}
      keyExtractor={(item, index) => `${item.Id}-${index}`}
      renderItem={renderQueueItem}
      showsVerticalScrollIndicator={false}
      initialScrollIndex={queueIndex > 2 ? queueIndex - 2 : 0}
      getItemLayout={(_, index) => ({
        length: 72,
        offset: 72 * index,
        index,
      })}
      ListHeaderComponent={
        <View className='px-4 py-2'>
          <Text className='text-neutral-400 text-xs uppercase tracking-wider'>
            {history.length > 0 ? "Playing from queue" : "Up next"}
          </Text>
        </View>
      }
      ListEmptyComponent={
        <View className='flex-1 items-center justify-center py-20'>
          <Text className='text-neutral-500'>Queue is empty</Text>
        </View>
      }
    />
  );
};
