import { View, ScrollView, Alert } from "react-native";
import React, {
  useMemo,
  useState,
  useCallback,
  useEffect,
  useRef,
} from "react";
import Page from "../../layouts/Page";
import MusicLandHeader from "../../components/MusicLandHeader";
import { navigate } from "../../navigation/NavigationService";
import { gutters } from "../../styles";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
import CustomInput from "./components/CustomInput";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
import firebase, { projectsRef } from "../../config/firebase";
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
import { useUser } from "../../providers/UserDataProvider";

const Lyrics = ({ navigation }) => {
  const scrollRef = useRef(null);
  const [containerLayout, setContainerLayout] = useState(null);
  const { setIsLoading } = useMinuit();
  const { selectedProjectId, selectedProject } = useUser();
  const [isFocus, setIsFocus] = useState(null);
  const [itemsContainerLayout, setItemsContainerLayout] = useState([]);

  // Effective sources from provider only
  const projectTitle = selectedProject?.title || "";
  const projectLyrics = Array.isArray(selectedProject?.lyrics)
    ? selectedProject.lyrics
    : [];
  const projectConfig = selectedProject?.config || null;
  const projectSelections = selectedProject?.selections || null;
  const projectHasLyrics = !!selectedProject?.hasLyrics;

  const initial = useMemo(() => {
    const title = projectTitle || "";
    const aiSections = Array.isArray(projectLyrics) ? projectLyrics : [];
    // Respecter l'ordre de la structure choisie si disponible
    const targetStructure = Array.isArray(projectConfig?.structure)
      ? projectConfig.structure.map((t) => (t || "").toLowerCase())
      : null;

    // 1) Si des paroles existent déjà, les utiliser en priorité
    if (aiSections.length) {
      // Optionnel: si une structure cible de même longueur existe, garder l'ordre courant
      // et harmoniser les types en minuscule.
      return {
        title,
        sections: aiSections.map((s) => ({
          type: (s?.type || "").toLowerCase(),
          lyrics: s?.lyrics || "",
        })),
      };
    }

    // 2) Sinon, créer à partir de la structure si fournie
    if (targetStructure && targetStructure.length) {
      return {
        title,
        sections: targetStructure.map((t) => ({ type: t, lyrics: "" })),
      };
    }

    // 3) Fallback vide
    return { title, sections: [] };
  }, [projectTitle, projectLyrics, projectConfig]);

  const [titleValue, setTitleValue] = useState(initial.title || "");
  const [sections, setSections] = useState(initial.sections || []);
  const setSectionAt = (index, value) => {
    setSections((prev) => {
      const next = [...prev];
      if (next[index]) next[index] = { ...next[index], lyrics: value };
      return next;
    });
  };

  // Plus d'appel direct à la cloud function ici: on retourne à l'étape précédente
  const regenerate = useCallback(() => {
    navigate(Routes.CreateLyricsWithAi);
  }, []);

  const sanitize = (obj) => {
    if (obj === undefined) return null;
    if (obj === null) return null;
    if (Array.isArray(obj)) return obj.map((v) => sanitize(v));
    if (typeof obj === "object") {
      const out = {};
      Object.keys(obj).forEach((k) => {
        const v = obj[k];
        if (v === undefined) return; // omit undefined
        out[k] = sanitize(v);
      });
      return out;
    }
    return obj;
  };

  const onValidate = useCallback(async () => {
    try {
      await setIsLoading(true);
      const titleTrimmed = (titleValue || "").trim();
      if (!titleTrimmed) {
        Alert.alert("Titre manquant", "Veuillez renseigner un titre.");
        return;
      }
      const invalid = (sections || []).some((s) => !(s?.lyrics || "").trim());
      if (invalid) {
        Alert.alert(
          "Champs incomplets",
          "Chaque couplet et refrain doit contenir du texte."
        );
        return;
      }
      const normalizedNewLyrics = (sections || []).map((s) => ({
        type: (s?.type || "").toLowerCase(),
        lyrics: (s?.lyrics || "").trim(),
      }));
      const normalizedOldLyrics = Array.isArray(projectLyrics)
        ? projectLyrics.map((s) => ({
            type: (s?.type || "").toLowerCase(),
            lyrics: (s?.lyrics || "").trim(),
          }))
        : [];
      const sameLength =
        normalizedOldLyrics.length === normalizedNewLyrics.length;
      const isSame =
        sameLength &&
        normalizedOldLyrics.every(
          (s, i) =>
            s.type === normalizedNewLyrics[i]?.type &&
            s.lyrics === normalizedNewLyrics[i]?.lyrics
        );

      // 1) Appel de la Cloud Function de modération avant tout enregistrement
      try {
        const callable = firebase
          .functions()
          .httpsCallable("lyrics-analyseLyricsToxicity");
        const { data } = await callable({
          title: titleTrimmed,
          lyrics: normalizedNewLyrics,
        });

        if (!data?.success) {
          // Blocage dur: afficher le message et ne pas sauvegarder
          if (data?.errorCode === "TOXIC_CONTENT_BLOCKED") {
            const quotes = Array.isArray(data?.result?.excerpts)
              ? data.result.excerpts
                  .slice(0, 3)
                  .map((e) => `• ${e.quote}`)
                  .join("\n")
              : null;
            Alert.alert(
              "Contenu interdit",
              [data?.message, quotes].filter(Boolean).join("\n\n")
            );
            return; // stop here
          }
          // Erreur d'analyse: informer et arrêter
          if (data?.errorCode === "ANALYSE_FAILED") {
            Alert.alert(
              "Analyse indisponible",
              "Impossible de vérifier la toxicité pour le moment. Réessayez plus tard."
            );
            return;
          }
        }

        // Cas signalé mais non bloquant: demander confirmation
        if (data?.errorCode === "TOXIC_CONTENT_FLAGGED") {
          const quotes = Array.isArray(data?.result?.excerpts)
            ? data.result.excerpts
                .slice(0, 3)
                .map((e) => `• ${e.quote}`)
                .join("\n")
            : null;
          const msg = [data?.message, quotes].filter(Boolean).join("\n\n");

          const proceed = await new Promise((resolve) => {
            Alert.alert("Contenu potentiellement sensible", msg, [
              {
                text: "Annuler",
                style: "cancel",
                onPress: () => resolve(false),
              },
              {
                text: "Continuer",
                style: "destructive",
                onPress: () => resolve(true),
              },
            ]);
          });
          if (!proceed) return;
        }
      } catch (moderationError) {
        console.log(
          "Moderation call failed",
          moderationError?.message || moderationError
        );
        Alert.alert(
          "Analyse indisponible",
          "Impossible de vérifier la toxicité pour le moment. Réessayez plus tard."
        );
        return;
      }

      const baseData = {
        title: titleTrimmed,
        titleLower: titleTrimmed.toLowerCase(),
        lyrics: normalizedNewLyrics,
        config: sanitize(projectConfig),
        selections: sanitize(projectSelections),
        updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
        hasLyrics: projectHasLyrics,
      };

      const updateData = { ...baseData };
      if (!isSame) {
        updateData.musicUrls = firebase.firestore.FieldValue.delete();
        updateData.musicStatus = firebase.firestore.FieldValue.delete();
        await projectsRef
          .doc(selectedProjectId)
          .set(updateData, { merge: true });
      }
      navigate(Routes.FlowSelection);
    } catch (e) {
      console.log(e);
      Alert.alert("Erreur", "Échec de l'enregistrement dans le projet.");
    } finally {
      await setIsLoading(false);
    }
  }, [
    titleValue,
    sections,
    projectConfig,
    projectSelections,
    setIsLoading,
    selectedProjectId,
    projectHasLyrics,
    projectLyrics,
  ]);

  return (
    <Page headerType="NONE">
      <MusicLandHeader
        onPressBack={() => navigate(Routes.FlowSelection)}
        progress={95}
      />
      <View
        style={{
          flex: 1,
          marginTop: 16,
          gap: 48,
        }}
        onLayout={(e) => setContainerLayout(e.nativeEvent.layout)}
      >
        <ItemContainer
          height={containerLayout?.height}
          disableKeyboardHeight={isFocus !== sections.length - 1 || !isFocus}
        >
          <ScrollView
            ref={scrollRef}
            contentContainerStyle={{
              paddingHorizontal: 14,
              paddingVertical: 10,
              gap: 10,
              flexGrow: 1,
            }}
          >
            <CustomInput
              label="Titre"
              placeholder="Titre"
              height={45}
              value={titleValue}
              setValue={setTitleValue}
              multiline={false}
              maxLength={60}
              onLayout={(e) => {
                e.persist();
                setItemsContainerLayout((prev) => [
                  ...prev,
                  e?.nativeEvent?.layout,
                ]);
              }}
            />
            {sections.map((s, idx) => {
              // Calculer l'index humain par type
              const type = (s?.type || "").toLowerCase();
              const countBefore = sections
                .slice(0, idx)
                .filter((x) => (x?.type || "").toLowerCase() === type).length;
              const labelBase = type === "refrain" ? "Refrain" : "Couplet";
              const label = `${labelBase} ${countBefore + 1}`;
              return (
                <CustomInput
                  key={idx}
                  label={label}
                  placeholder={labelBase}
                  height={type === "refrain" ? 170 : 225}
                  value={s?.lyrics || ""}
                  setValue={(val) => setSectionAt(idx, val)}
                  onFocus={() => {
                    setIsFocus(idx);
                    scrollRef?.current?.scrollTo({
                      y: itemsContainerLayout[idx + 1]?.y,
                    });
                  }}
                  onLayout={(e) => {
                    e.persist();
                    setItemsContainerLayout((prev) => [
                      ...prev,
                      e?.nativeEvent?.layout,
                    ]);
                  }}
                />
              );
            })}
          </ScrollView>
        </ItemContainer>
      </View>
      <View
        style={{
          paddingTop: gutters,
          paddingBottom: gutters * 2,
          paddingHorizontal: gutters,
          gap: 12,
        }}
      >
        {!projectHasLyrics && (
          <BorderGradientButton
            title="Générer d'autres paroles"
            onPress={regenerate}
          />
        )}
        <GradientButton title="Valider" onPress={onValidate} />
      </View>
    </Page>
  );
};

export default Lyrics;
