import { useRoute } from "@react-navigation/core";
import { useAudioPlayer } from "expo-audio";
import { Image as ExpoImage } from "expo-image";
import React, { useEffect, useMemo, useState } from "react";
import {
  Pressable,
  Image as RNImage,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from "react-native";
import { SheetManager } from "react-native-actions-sheet";
import {
  responsiveHeight,
  responsiveWidth,
} from "react-native-responsive-dimensions";
import { useGlobal } from "reactn";
import { background, icons } from "../../assets";
import Slider from "../../components/Slider";
import {
  arrayRemove,
  arrayUnion,
  increment,
  projectsRef,
  usersRef,
} from "../../config/firebase";
import useDataFromRef from "../../hooks/useDataFromRef";
import Page from "../../layouts/Page";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import Style, { gutters, size } from "../../styles/Style";

// 20 secondes
const timeBeforeIncrement = 20000;

const MusicDetails = () => {
  const params = useRoute().params || {};
  const action = params?.action;
  const projectId = params?.projectId || null;
  const [fav, setFav] = useState(false);
  const [currentUID] = useGlobal("currentUID");
  const [isPlaying, setIsPlaying] = useState(false);
  const [progressInfo, setProgressInfo] = useState({ pos: 0, dur: 0 });
  const wasPlayingBeforeSeek = React.useRef(false);
  const listenedMsRef = React.useRef(0);
  const incrementDoneRef = React.useRef(false);
  const timerRef = React.useRef(null);

  const { data: project } = useDataFromRef({
    ref: projectId ? projectsRef.doc(projectId) : null,
    simpleRef: true,
    listener: true,
    condition: !!projectId,
  });

  const { data: owner } = useDataFromRef({
    ref: project?.userId ? usersRef.doc(project.userId) : null,
    simpleRef: true,
    listener: true,
    condition: !!project?.userId,
  });

  useEffect(() => {
    if (project && currentUID) {
      const liked = Array.isArray(project?.likedBy)
        ? project.likedBy.includes(currentUID)
        : false;
      setFav(liked);
    }
  }, [project?.likedBy, currentUID]);

  const title = project?.title || "Sans titre";
  const artist = owner?.userName || "MusicLand";
  const coverUrl = project?.coverUrl || null;
  const songUrl = project?.songUrl || null;

  const player = useAudioPlayer(songUrl ? { uri: songUrl } : undefined);

  // Reset counters when the track changes
  useEffect(() => {
    listenedMsRef.current = 0;
    incrementDoneRef.current = false;
  }, [songUrl]);

  // Poll player state to update progress and play state
  useEffect(() => {
    const id = setInterval(() => {
      const dur = (player?.duration || 0) * 1000;
      const pos = (player?.currentTime || 0) * 1000;
      setProgressInfo({ pos, dur });
      setIsPlaying(!!player?.playing);
    }, 300);
    return () => clearInterval(id);
  }, [player]);

  // Start/stop a timer to accumulate listened milliseconds while playing
  useEffect(() => {
    const clearTimer = () => {
      if (timerRef.current) {
        global.clearInterval(timerRef.current);
        timerRef.current = null;
      }
    };
    if (isPlaying && projectId) {
      if (!timerRef.current) {
        timerRef.current = global.setInterval(async () => {
          try {
            listenedMsRef.current += 500;
            if (
              !incrementDoneRef.current &&
              listenedMsRef.current >= timeBeforeIncrement &&
              projectId
            ) {
              incrementDoneRef.current = true;
              await projectsRef
                .doc(projectId)
                .set({ views: increment(1) }, { merge: true });
            }
          } catch (e) {
            // Silent fail for counter
          }
        }, 500);
      }
    } else {
      clearTimer();
    }
    return clearTimer;
  }, [isPlaying, projectId]);

  const fmt = (ms) => {
    const total = Math.max(0, Math.floor((ms || 0) / 1000));
    const m = Math.floor(total / 60)
      .toString()
      .padStart(1, "0");
    const s = (total % 60).toString().padStart(2, "0");
    return `${m}:${s}`;
  };

  const togglePlay = async () => {
    if (!player || !songUrl) return;
    try {
      if (player.playing) {
        await player.pause?.();
        setIsPlaying(false);
      } else {
        await player.play?.();
        setIsPlaying(true);
      }
    } catch (e) {
      console.log("MusicDetails audio error", e?.message);
    }
  };

  const onSeek = async (ratio) => {
    try {
      const dur = progressInfo.dur || 0;
      const pos = Math.floor(dur * ratio);
      if (player && dur > 0) {
        await player.seekTo?.(Math.floor((pos || 0) / 1000));
      }
    } catch (e) {
      console.log("MusicDetails seek error", e?.message);
    }
  };

  const seekBy = async (deltaSeconds) => {
    try {
      const cur = Math.floor((progressInfo.pos || 0) / 1000);
      const next = Math.max(0, cur + deltaSeconds);
      if (player) await player.seekTo?.(next);
    } catch (e) {
      console.log("MusicDetails seekBy error", e?.message);
    }
  };
  const description = useMemo(() => {
    // Build a readable text from lyrics with section labels
    if (Array.isArray(project?.lyrics)) {
      return project.lyrics
        .map((s) => {
          const body = (s?.lyrics || "").trim();
          if (!body) return null;
          const t = (s?.type || "").toLowerCase();
          const label = t === "refrain" ? "Refrain" : "Couplet";
          return `[${label}]\n${body}`;
        })
        .filter(Boolean)
        .join("\n\n");
    }
    const c = project?.lyrics?.couplet;
    const r = project?.lyrics?.refrain;
    const parts = [c ? `[Couplet]\n${c}` : null, r ? `[Refrain]\n${r}` : null].filter(Boolean);
    return parts.length ? parts.join("\n\n") : "";
  }, [project]);

  return (
    <Page
      headerType="NAVIGATION"
      title={action === "userProfile" ? "Mon profil" : "Détail musique"}
      backgroundImg={
        action === "userProfile" ? background.profileBG : background.libraryBG2
      }
      {...(action === "userProfile" && {
        containerStyle: {
          backgroundColor: "#0000004D",
        },
        rightComponent: () => (
          <Pressable onPress={() => SheetManager.show("DeleteAudio")}>
            <RNImage source={icons.trash} />
          </Pressable>
        ),
      })}
    >
      <ScrollView
        contentContainerStyle={{
          flexGrow: 1,
          paddingTop: 20,
          paddingBottom: gutters * 2,
        }}
      >
        <View style={{ gap: 28 }}>
          {coverUrl && (
            <ExpoImage
              source={{ uri: coverUrl }}
              cachePolicy="memory-disk"
              priority="high"
              contentFit="cover"
              transition={150}
              style={styles.img}
            />
          )}
          <View style={{ ...Style.containerSpaceBetween }}>
            <View>
              <Text style={styles.title}>{title}</Text>
              <Text style={styles.name}>{artist}</Text>
            </View>
            <View style={{ ...Style.containerRow, gap: 12 }}>
              <Pressable
                onPress={async () => {
                  if (!projectId || !currentUID) return;
                  const next = !fav;
                  setFav(next);
                  try {
                    await projectsRef.doc(projectId).update({
                      likedBy: next
                        ? arrayUnion(currentUID)
                        : arrayRemove(currentUID),
                    });
                  } catch (e) {
                    setFav(!next);
                  }
                }}
              >
                <RNImage
                  source={fav ? icons.heart : icons.heartOutline}
                  style={{ ...size({ size: 24 }) }}
                  resizeMode="contain"
                />
              </Pressable>
              <Pressable
                onPress={() =>
                  SheetManager.show("Playlist", { payload: { projectId } })
                }
              >
                <RNImage
                  source={icons.more}
                  style={{ ...size({ size: 24 }) }}
                  resizeMode="contain"
                />
              </Pressable>
            </View>
          </View>
        </View>
        {songUrl && (
          <View style={{ paddingTop: 22 }}>
            <Slider
              value={fmt(progressInfo.pos)}
              maxValue={fmt(progressInfo.dur)}
              progress={
                progressInfo.dur
                  ? (progressInfo.pos || 0) / progressInfo.dur
                  : 0
              }
              seekEnabled={!!songUrl}
              onSeekStart={async () => {
                try {
                  wasPlayingBeforeSeek.current = !!player?.playing;
                  if (player?.playing) {
                    await player.pause?.();
                    setIsPlaying(false);
                  }
                } catch (e) {
                  console.log("Pause on seek start error", e?.message);
                }
              }}
              onSeek={onSeek}
              onSeekEnd={async () => {
                try {
                  if (player && wasPlayingBeforeSeek.current) {
                    await player.play?.();
                    setIsPlaying(true);
                  }
                  wasPlayingBeforeSeek.current = false;
                } catch (e) {
                  console.log("Resume after seek error", e?.message);
                }
              }}
            />
            <View
              style={{ ...Style.containerRow, gap: 24, alignSelf: "center" }}
            >
              {/* Previous (rewind 10s) */}
              <Pressable onPress={() => seekBy(-10)}>
                <RNImage
                  source={icons.forward}
                  style={{
                    ...size({ size: 30 }),
                  }}
                />
              </Pressable>
              {/* Play / Pause */}
              <Pressable
                style={{
                  ...size({ size: 40 }),
                  alignItems: "center",
                  justifyContent: "center",
                }}
                onPress={togglePlay}
              >
                <RNImage
                  resizeMode={"contain"}
                  source={isPlaying ? icons.pause : icons.play}
                  style={size({ size: 34 })}
                />
              </Pressable>
              {/* Next (forward 10s) */}
              <Pressable onPress={() => seekBy(10)}>
                <RNImage
                  source={icons.forward}
                  style={{
                    ...size({ size: 30 }),
                    transform: [{ rotate: "180deg" }],
                  }}
                />
              </Pressable>
            </View>
          </View>
        )}
        {description?.length > 0 && (
          <View style={{ marginTop: 30, gap: 20 }}>
            <Text
              style={{
                fontSize: 16,
                color: Palette.white,
                fontFamily: FONT_FAMILY.InterRegular,
              }}
            >
              {description}
            </Text>
          </View>
        )}
      </ScrollView>
    </Page>
  );
};

export default MusicDetails;

const styles = StyleSheet.create({
  img: {
    width: 292,
    height: 290,
    borderRadius: 24,
    alignSelf: "center",
  },
  title: {
    fontSize: 20,
    color: Palette.white,
    fontFamily: FONT_FAMILY.HelveticaNeueMedium,
    width: responsiveWidth(70),
    marginBottom: responsiveHeight(1),
  },
  name: {
    fontSize: 16,
    color: Palette.white,
    fontFamily: FONT_FAMILY.HelveticaNeueRegular,
  },
});
