import { View, Dimensions } from "react-native";
import React, { useMemo, useRef, useState } from "react";
import Page from "../../layouts/Page";
import { background } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader";
import GradientButton from "../../components/GradientButton";
import { goBack, navigate } from "../../navigation/NavigationService";
import { gutters } from "../../styles";
import SwiperFlatList from "react-native-swiper-flatlist";
import ChooseGenre from "./ChooseGenre";
import CustomizeVoice from "./CustomizeVoice";
import ChooseInstruments from "./ChooseInstruments";
import ChooseRhythm from "./ChooseRhythm";
import { useUser } from "../../providers/UserDataProvider";
import firebase from "../../config/firebase";
import { Routes } from "../../navigation";

const { width } = Dimensions.get("window");

const ComposeSong = () => {
  const scrollRef = useRef(null);
  const [selectedIndex, setSelectedIndex] = useState(0);
  const [progress, setProgress] = useState(18);
  const [containerLayout, setContainerLayout] = useState(null);
  const { selectedProjectId, selectedProject, updateProjectData } = useUser();

  // Selections state
  const [genres, setGenres] = useState([]);
  // voice: object keyed by category (e.g., { base: string|null, Sensibilité: string|null, Technique: string|null })
  const [voice, setVoice] = useState({});
  const [instruments, setInstruments] = useState([]);
  const [rhythm, setRhythm] = useState(null);

  const isStepValid = useMemo(() => {
    switch (selectedIndex) {
      case 0:
        return Array.isArray(genres) && genres.length > 0;
      case 1:
        // Must select at least one in base category
        return !!(voice && typeof voice === "object" && voice.base);
      case 2:
        return Array.isArray(instruments) && instruments.length > 0;
      case 3:
        return !!rhythm;
      default:
        return true;
    }
  }, [selectedIndex, genres, voice, instruments, rhythm]);

  const musicConfig = useMemo(() => {
    let lyricsArr = [];
    if (Array.isArray(selectedProject?.lyrics)) {
      lyricsArr = selectedProject.lyrics.map((s) => ({
        type: (s?.type || "").toLowerCase(),
        lyrics: s?.lyrics || "",
      }));
    } else {
      const c = selectedProject?.lyrics?.couplet;
      const r = selectedProject?.lyrics?.refrain;
      if (c) lyricsArr.push({ type: "couplet", lyrics: c });
      if (r) lyricsArr.push({ type: "refrain", lyrics: r });
    }
    const voiceArray = Object.entries(voice || {})
      .filter(([, v]) => typeof v === "string" && v.trim())
      .map(([category, value]) => ({ category, value }));

    return {
      title: selectedProject?.title || "",
      lyrics: lyricsArr,
      genres: Array.isArray(genres) ? genres : [],
      voice: voiceArray,
      instruments: Array.isArray(instruments) ? instruments : [],
      tempo: rhythm || undefined,
      projectId: selectedProjectId || undefined,
    };
  }, [selectedProject, genres, voice, instruments, rhythm, selectedProjectId]);

  const onPressNext = async () => {
    if (selectedIndex === 3) {
      try {
        // Persist config on the selected selectedProject so GeneratingSong can pick it up
        if (selectedProjectId) {
          await updateProjectData({
            musicConfig: {
              title: musicConfig?.title || "",
              lyrics: Array.isArray(musicConfig?.lyrics)
                ? musicConfig.lyrics
                : [],
              genres: Array.isArray(musicConfig?.genres)
                ? musicConfig.genres
                : [],
              voice: Array.isArray(musicConfig?.voice) ? musicConfig.voice : [],
              instruments: Array.isArray(musicConfig?.instruments)
                ? musicConfig.instruments
                : [],
              tempo: musicConfig?.tempo || "",
            },
            musicStatus: null,
            sunoTaskId: firebase.firestore.FieldValue.delete(),
            musicUrls: firebase.firestore.FieldValue.delete(),
          });
        }
      } catch (e) {}
      // Also pass the config to the screen to avoid any race condition
      navigate(Routes.GeneratingSong, { config: musicConfig });
      return;
    }
    setSelectedIndex(selectedIndex + 1);
    setProgress(progress + 9);
    scrollRef.current.scrollToIndex({
      index: selectedIndex + 1,
      animated: true,
    });
  };

  const onPressBack = () => {
    if (selectedIndex > 0) {
      setSelectedIndex(selectedIndex - 1);
      setProgress(progress - 9);
      scrollRef.current.scrollToIndex({
        index: selectedIndex - 1,
        animated: true,
      });
    } else {
      goBack();
    }
  };

  return (
    <Page backgroundImg={background.studioBG2} headerType="NONE">
      <MusicLandHeader onPressBack={onPressBack} progress={progress} />
      <View style={{ flex: 1, paddingBottom: gutters, gap: 48 }}>
        <View
          style={{ flex: 1 }}
          onLayout={(event) => setContainerLayout(event.nativeEvent.layout)}
        >
          <SwiperFlatList
            style={{ width, left: -gutters }}
            ref={scrollRef}
            disableGesture
          >
            <View
              style={{
                width: width,
                height: containerLayout?.height,
                paddingHorizontal: gutters,
              }}
            >
              <ChooseGenre selected={genres} setSelected={setGenres} />
            </View>
            <View
              style={{
                width: width,
                height: containerLayout?.height,
                paddingHorizontal: gutters,
              }}
            >
              <CustomizeVoice selected={voice} setSelected={setVoice} />
            </View>
            <View
              style={{
                width: width,
                height: containerLayout?.height,
                paddingHorizontal: gutters,
              }}
            >
              <ChooseInstruments
                selected={instruments}
                setSelected={setInstruments}
              />
            </View>
            <View
              style={{
                width: width,
                height: containerLayout?.height,
                paddingHorizontal: gutters,
              }}
            >
              <ChooseRhythm selected={rhythm} setSelected={setRhythm} />
            </View>
          </SwiperFlatList>
        </View>
        {selectedIndex !== 4 && (
          <GradientButton
            title={selectedIndex === 3 ? "Générer" : "Suivant"}
            onPress={onPressNext}
            disabled={!isStepValid}
          />
        )}
      </View>
    </Page>
  );
};

export default ComposeSong;
