import { useAudioPlayer } from "expo-audio";
import * as FileSystem from "expo-file-system";
import { VideoView, useVideoPlayer } from "expo-video";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { View } from "react-native";
import { background } from "../../assets";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import MusicLandHeader from "../../components/MusicLandHeader";
import Slider from "../../components/Slider";
import Page from "../../layouts/Page";
import { Routes } from "../../navigation";
import { goBack, navigate } from "../../navigation/NavigationService";
import { gutters } from "../../styles";
const RecordedPlayback = ({ route }) => {
  const { videoUri, project } = route.params || {};
  const songUrl = project?.songUrl || null;

  const audioPlayer = useAudioPlayer(songUrl ? { uri: songUrl } : undefined);
  const videoPlayer = useVideoPlayer(videoUri || null, (p) => {
    p.loop = false;
    p.muted = true; // recorded video has no audio; keep muted anyway
    p.timeUpdateEventInterval = 0.2;
  });

  const [progressInfo, setProgressInfo] = useState({ pos: 0, dur: 0 });
  const wasPlayingBeforeSeek = useRef(false);

  // Format mm:ss
  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}`;
  };

  // Start both players on mount
  useEffect(() => {
    const start = async () => {
      try {
        if (audioPlayer && songUrl) await audioPlayer.play?.();
        if (videoPlayer) videoPlayer.play();
      } catch (e) {}
    };
    start();
    return () => {
      try {
        if (audioPlayer?.playing) audioPlayer.pause?.();
        if (videoPlayer?.playing) videoPlayer.pause();
      } catch (e) {}
    };
  }, [audioPlayer, videoPlayer, songUrl]);

  // Poll from audio player for progress display; keep video in sync if drifting
  useEffect(() => {
    const id = global.setInterval(() => {
      try {
        const dur = (audioPlayer?.duration || 0) * 1000;
        const pos = (audioPlayer?.currentTime || 0) * 1000;
        setProgressInfo({ pos, dur });

        // basic drift correction: if desync > 300ms, align video
        if (videoPlayer && !Number.isNaN(videoPlayer.currentTime)) {
          const v = (videoPlayer.currentTime || 0) * 1000;
          const drift = Math.abs(v - pos);
          if (drift > 350) {
            videoPlayer.currentTime = Math.max(0, (pos || 0) / 1000);
          }
        }
      } catch (e) {}
    }, 250);
    return () => global.clearInterval(id);
  }, [audioPlayer, videoPlayer]);

  const onSeek = async (ratio) => {
    try {
      const dur = progressInfo.dur || 0;
      const pos = Math.floor(dur * ratio);
      if (audioPlayer && dur > 0)
        await audioPlayer.seekTo?.(Math.floor(pos / 1000));
      if (videoPlayer) videoPlayer.currentTime = Math.max(0, pos / 1000);
    } catch (e) {}
  };

  const onSeekStart = async () => {
    try {
      wasPlayingBeforeSeek.current = !!audioPlayer?.playing;
      if (audioPlayer?.playing) await audioPlayer.pause?.();
      if (videoPlayer?.playing) videoPlayer.pause();
    } catch (e) {}
  };
  const onSeekEnd = async () => {
    try {
      if (wasPlayingBeforeSeek.current) {
        if (audioPlayer) await audioPlayer.play?.();
        if (videoPlayer) videoPlayer.play();
      }
    } catch (e) {}
  };

  const sliderProgress = useMemo(() => {
    return progressInfo.dur
      ? Math.min(1, (progressInfo.pos || 0) / progressInfo.dur)
      : 0;
  }, [progressInfo]);

  return (
    <Page backgroundImg={background.playbackBG2} headerType="NONE">
      <MusicLandHeader progress={19} onPressBack={goBack} />
      <View
        style={{ flex: 1, paddingTop: 12, gap: 14, paddingBottom: gutters * 2 }}
      >
        <View style={{ flex: 1, gap: 22 }}>
          {!!videoUri && (
            <VideoView
              player={videoPlayer}
              nativeControls={false}
              contentFit="contain"
              style={{
                width: "80%",
                flex: 1,
                alignSelf: "center",
                borderRadius: 16,
                backgroundColor: "#00000066",
                overflow: "hidden",
              }}
            />
          )}
          <Slider
            value={fmt(progressInfo.pos)}
            maxValue={fmt(progressInfo.dur)}
            progress={sliderProgress}
            seekEnabled={!!songUrl}
            onSeek={onSeek}
            onSeekStart={onSeekStart}
            onSeekEnd={onSeekEnd}
          />
        </View>
        <View
          style={{ width: "80%", alignSelf: "center", marginTop: 4, gap: 12 }}
        >
          <GradientButton
            title="Je valide"
            onPress={() => {
              navigate(Routes.DownloadSongs, {
                action: "playback",
                uri: videoUri,
                project,
              });
            }}
          />
          <BorderGradientButton
            title="Recommencer"
            onPress={async () => {
              try {
                if (audioPlayer?.playing) await audioPlayer.pause?.();
                if (videoPlayer?.playing) videoPlayer.pause();
              } catch (e) {}
              try {
                if (videoUri) {
                  const info = await FileSystem.getInfoAsync(videoUri);
                  if (info?.exists)
                    await FileSystem.deleteAsync(videoUri, {
                      idempotent: true,
                    });
                }
              } catch (e) {}
              navigate(Routes.RecordPlayback, { project });
            }}
          />
        </View>
      </View>
    </Page>
  );
};

export default RecordedPlayback;
