import * as ImagePicker from "expo-image-picker";
import { useEffect, useState } from "react";
import {
  ActivityIndicator,
  Image,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";
import { colors, shared } from "../styles";

const BASE_URL =
  "https://shsf-api.reversed.dev/api/exec/15/1c44d8b5-4065-4a54-b259-748561021329";

// ─── Settings page ────────────────────────────────────────────────────────────

export function SettingsPage() {
  const [currentBgUrl, setCurrentBgUrl] = useState<string>("");
  const [pendingUri, setPendingUri] = useState<string | null>(null);
  const [pendingBase64, setPendingBase64] = useState<string | null>(null);
  const [pendingExt, setPendingExt] = useState<string>("jpg");
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [clearing, setClearing] = useState(false);
  const [status, setStatus] = useState<string | null>(null);

  // ── Load current settings on mount
  useEffect(() => {
    setLoading(true);
    fetch(`${BASE_URL}/pull_full`, { method: "POST" })
      .then((r) => r.json())
      .then((data) => {
        const bg = data.state?.settings?.background_url ?? "";
        setCurrentBgUrl(bg);
      })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, []);

  // ── Pick a landscape image from the gallery
  const handlePickBackground = async () => {
    const { granted } = await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (!granted) {
      setStatus("Media library permission is required.");
      return;
    }

    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: "images",
      quality: 1,
      base64: true,
    });

    if (result.canceled) return;

    const asset = result.assets[0];

    // Enforce landscape orientation (width must exceed height)
    if (asset.width <= asset.height) {
      setStatus("Please pick a landscape image (width must be greater than height).");
      return;
    }

    if (!asset.base64) {
      setStatus("Could not read image data. Please try again.");
      return;
    }
    const ext = (asset.mimeType?.split("/")[1] ?? asset.uri.split(".").pop() ?? "jpg").toLowerCase();
    setPendingUri(asset.uri);
    setPendingBase64(asset.base64);
    setPendingExt(ext);
    setStatus(null);
  };

  // ── Upload pending image and save as background
  const handleSave = async () => {
    if (!pendingBase64) { setStatus("No image selected."); return; }
    setSaving(true);
    setStatus(null);
    try {
      // Upload to MinIO via push_upload_images
      const uploadRes = await fetch(`${BASE_URL}/push_upload_images`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ images: [{ image_b64: pendingBase64, ext: pendingExt }] }),
      });
      const uploadData = await uploadRes.json();
      if (uploadData.status !== "success" || !uploadData.urls?.[0]) {
        throw new Error(uploadData.message ?? "Upload failed");
      }
      const url: string = uploadData.urls[0];

      // Persist as background URL
      const settingsRes = await fetch(`${BASE_URL}/push_settings`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ background_url: url }),
      });
      const settingsData = await settingsRes.json();
      if (settingsData.status !== "success") {
        throw new Error(settingsData.message ?? "Save failed");
      }

      setCurrentBgUrl(url);
      setPendingUri(null);
      setPendingBase64(null);
      setStatus("Background saved!");
    } catch (err) {
      setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`);
    } finally {
      setSaving(false);
    }
  };

  // ── Clear the TV background
  const handleClear = async () => {
    setClearing(true);
    setStatus(null);
    try {
      const res = await fetch(`${BASE_URL}/push_settings`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ background_url: "" }),
      });
      const data = await res.json();
      if (data.status !== "success") throw new Error(data.message ?? "Clear failed");
      setCurrentBgUrl("");
      setPendingUri(null);
      setPendingBase64(null);
      setStatus("Background cleared.");
    } catch (err) {
      setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`);
    } finally {
      setClearing(false);
    }
  };

  const previewUri = pendingUri ?? (currentBgUrl || null);
  const hasPending = !!pendingUri;
  const hasCurrent = !!currentBgUrl;

  return (
    <ScrollView
      style={shared.screen}
      contentContainerStyle={styles.container}
      keyboardShouldPersistTaps="handled"
    >
      <Text style={shared.pageTitle}>Settings</Text>
      <Text style={shared.subtitle}>Configure global TV display options.</Text>

      {/* ── Background Image ── */}
      <View style={styles.section}>
        <Text style={shared.sectionLabel}>TV Background</Text>
        <Text style={shared.hint}>
          Displayed behind all content on the TV. Must be a landscape image (wider than tall).
        </Text>

        {loading ? (
          <ActivityIndicator color={colors.accent} style={{ marginTop: 12 }} />
        ) : (
          <>
            {/* Preview */}
            {previewUri && (
              <View style={styles.previewWrap}>
                <Image source={{ uri: previewUri }} style={styles.preview} resizeMode="cover" />
                {hasPending && (
                  <View style={styles.pendingBadge}>
                    <Text style={styles.pendingBadgeText}>Unsaved</Text>
                  </View>
                )}
              </View>
            )}

            {!previewUri && (
              <View style={styles.emptyPreview}>
                <Text style={styles.emptyPreviewText}>No background set</Text>
              </View>
            )}

            {/* Actions */}
            <View style={shared.actionsRow}>
              <TouchableOpacity
                style={[shared.btnSecondary, shared.actionFlex]}
                onPress={handlePickBackground}
                activeOpacity={0.8}
              >
                <Text style={shared.btnSecondaryText}>
                  {hasCurrent || hasPending ? "Replace" : "Pick Image"}
                </Text>
              </TouchableOpacity>

              {hasPending && (
                <TouchableOpacity
                  style={[shared.btnPrimary, shared.actionFlex, saving && shared.btnDisabled]}
                  onPress={handleSave}
                  activeOpacity={0.8}
                  disabled={saving}
                >
                  {saving ? (
                    <ActivityIndicator color="#fff" />
                  ) : (
                    <Text style={shared.btnPrimaryText}>Save</Text>
                  )}
                </TouchableOpacity>
              )}
            </View>

            {(hasCurrent || hasPending) && (
              <TouchableOpacity
                style={[shared.btnDanger, clearing && shared.btnDisabled]}
                onPress={handleClear}
                activeOpacity={0.8}
                disabled={clearing}
              >
                {clearing ? (
                  <ActivityIndicator color="#fff" />
                ) : (
                  <Text style={shared.btnDangerText}>Clear Background</Text>
                )}
              </TouchableOpacity>
            )}

            {status && (
              <Text style={[shared.hint, styles.statusText]}>{status}</Text>
            )}
          </>
        )}
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 24,
    gap: 20,
    paddingBottom: 40,
  },
  section: {
    gap: 12,
  },
  previewWrap: {
    borderRadius: 14,
    overflow: "hidden",
    borderWidth: 1,
    borderColor: colors.border,
    position: "relative",
  },
  preview: {
    width: "100%",
    aspectRatio: 16 / 9,
  },
  pendingBadge: {
    position: "absolute",
    top: 10,
    right: 10,
    backgroundColor: colors.accent,
    borderRadius: 8,
    paddingHorizontal: 10,
    paddingVertical: 4,
  },
  pendingBadgeText: {
    color: "#fff",
    fontSize: 11,
    fontWeight: "700",
    textTransform: "uppercase",
    letterSpacing: 0.5,
  },
  emptyPreview: {
    width: "100%",
    aspectRatio: 16 / 9,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: colors.border,
    borderStyle: "dashed",
    alignItems: "center",
    justifyContent: "center",
    backgroundColor: colors.surface,
  },
  emptyPreviewText: {
    color: colors.textMuted,
    fontSize: 14,
  },
  statusText: {
    marginTop: 4,
    color: colors.textSecondary,
  },
});
