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

// ─── Preset background colours ────────────────────────────────────────────────

const COLOR_PRESETS = [
  { label: "Black",       value: "#000000" },
  { label: "Dark Navy",   value: "#0a0a1a" },
  { label: "Dark Blue",   value: "#0d1b2a" },
  { label: "Dark Green",  value: "#0a1a0a" },
  { label: "Dark Purple", value: "#1a0a2e" },
  { label: "Dark Red",    value: "#1a0505" },
  { label: "Charcoal",    value: "#1a1a1a" },
  { label: "Slate",       value: "#1e2530" },
];

// ─── Helpers ───────────────────────────────────────────────────────────────────

function isValidTime(t: string) {
  return /^\d{2}:\d{2}$/.test(t);
}

function isValidHex(c: string) {
  return /^#[0-9a-fA-F]{6}$/.test(c);
}

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

export function SettingsPage() {
  const { baseUrl: BASE_URL, resetUrl } = useBaseUrl();
  // ── Background image
  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");

  // ── Background colour
  const [bgColor, setBgColor] = useState<string>("#000000");
  const [bgColorInput, setBgColorInput] = useState<string>("#000000");
  const [savingColor, setSavingColor] = useState(false);

  // ── Night mode
  const [nightEnabled, setNightEnabled] = useState(false);
  const [nightStart, setNightStart] = useState("22:00");
  const [nightEnd, setNightEnd] = useState("07:00");
  const [nightMessage, setNightMessage] = useState("Good Night");
  const [nightDim, setNightDim] = useState(true);
  const [savingNight, setSavingNight] = useState(false);

  // ── Shared
  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 s = data.state?.settings ?? {};
        setCurrentBgUrl(s.background_url ?? "");

        const col = s.background_color ?? "#000000";
        setBgColor(col);
        setBgColorInput(col);

        const nm = s.night_mode ?? {};
        setNightEnabled(nm.enabled ?? false);
        setNightStart(nm.start_time ?? "22:00");
        setNightEnd(nm.end_time ?? "07:00");
        setNightMessage(nm.message ?? "Good Night");
        setNightDim(nm.dim_background ?? true);
      })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, []);

  // ──────────────────────────────────────────────────────────────────────────────
  // Background image handlers
  // ──────────────────────────────────────────────────────────────────────────────

  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 handleSaveBgImage = async () => {
    if (!pendingBase64) { setStatus("No image selected."); return; }
    setSaving(true);
    setStatus(null);
    try {
      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];

      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 image saved!");
    } catch (err) {
      setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`);
    } finally {
      setSaving(false);
    }
  };

  // ── Clear the TV background image
  const handleClearBgImage = 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 image cleared.");
    } catch (err) {
      setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`);
    } finally {
      setClearing(false);
    }
  };

  // ──────────────────────────────────────────────────────────────────────────────
  // Background colour handlers
  // ──────────────────────────────────────────────────────────────────────────────

  const handleSaveBgColor = async (colorValue?: string) => {
    const col = colorValue ?? bgColorInput.trim();
    if (!isValidHex(col)) {
      setStatus("Enter a valid hex colour, e.g. #1a2b3c");
      return;
    }
    setSavingColor(true);
    setStatus(null);
    try {
      const res = await fetch(`${BASE_URL}/push_settings`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ background_color: col }),
      });
      const data = await res.json();
      if (data.status !== "success") throw new Error(data.message ?? "Save failed");
      setBgColor(col);
      setBgColorInput(col);
      setStatus("Background colour saved!");
    } catch (err) {
      setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`);
    } finally {
      setSavingColor(false);
    }
  };

  // ──────────────────────────────────────────────────────────────────────────────
  // Night mode handler
  // ──────────────────────────────────────────────────────────────────────────────

  const handleSaveNightMode = async () => {
    if (!isValidTime(nightStart) || !isValidTime(nightEnd)) {
      setStatus("Night mode times must be in HH:MM format.");
      return;
    }
    setSavingNight(true);
    setStatus(null);
    try {
      const res = await fetch(`${BASE_URL}/push_settings`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          night_mode: {
            enabled: nightEnabled,
            start_time: nightStart,
            end_time: nightEnd,
            message: nightMessage,
            dim_background: nightDim,
          },
        }),
      });
      const data = await res.json();
      if (data.status !== "success") throw new Error(data.message ?? "Save failed");
      setStatus("Night mode saved!");
    } catch (err) {
      setStatus(`Error: ${err instanceof Error ? err.message : String(err)}`);
    } finally {
      setSavingNight(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>

      {loading ? (
        <ActivityIndicator color={colors.accent} style={{ marginTop: 24 }} />
      ) : (
        <>
          {/* ── Background Image ───────────────────────────────────────────── */}
          <View style={styles.section}>
            <Text style={shared.sectionLabel}>TV Background Image</Text>
            <Text style={shared.hint}>
              Displayed behind all content. Must be landscape (wider than tall).
            </Text>

            {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>
            ) : (
              <View style={styles.emptyPreview}>
                <Text style={styles.emptyPreviewText}>No background image set</Text>
              </View>
            )}

            <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={handleSaveBgImage}
                  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={handleClearBgImage}
                activeOpacity={0.8}
                disabled={clearing}
              >
                {clearing ? <ActivityIndicator color="#fff" /> : <Text style={shared.btnDangerText}>Clear Image</Text>}
              </TouchableOpacity>
            )}
          </View>

          {/* ── Background Colour ──────────────────────────────────────────── */}
          <View style={styles.section}>
            <Text style={shared.sectionLabel}>Background Colour</Text>
            <Text style={shared.hint}>
              Solid colour shown when no background image is set (or when night mode dims the display).
            </Text>

            <View style={styles.colorRow}>
              <View style={[styles.colorSwatch, { backgroundColor: isValidHex(bgColorInput) ? bgColorInput : bgColor }]} />
              <TextInput
                style={[shared.input, { flex: 1 }]}
                value={bgColorInput}
                onChangeText={setBgColorInput}
                placeholder="#000000"
                placeholderTextColor={colors.placeholderColor}
                autoCapitalize="none"
                autoCorrect={false}
                maxLength={7}
              />
              <TouchableOpacity
                style={[shared.btnPrimary, styles.colorSaveBtn, savingColor && shared.btnDisabled]}
                onPress={() => handleSaveBgColor()}
                activeOpacity={0.8}
                disabled={savingColor}
              >
                {savingColor ? <ActivityIndicator color="#fff" size="small" /> : <Text style={shared.btnPrimaryText}>Apply</Text>}
              </TouchableOpacity>
            </View>

            <View style={styles.swatchRow}>
              {COLOR_PRESETS.map((p) => (
                <TouchableOpacity
                  key={p.value}
                  onPress={() => { setBgColorInput(p.value); handleSaveBgColor(p.value); }}
                  activeOpacity={0.75}
                  style={[
                    styles.swatchBtn,
                    { backgroundColor: p.value },
                    bgColor === p.value && styles.swatchSelected,
                  ]}
                />
              ))}
            </View>
            <View style={styles.swatchLabelsRow}>
              {COLOR_PRESETS.map((p) => (
                <Text key={p.value} style={styles.swatchLabel} numberOfLines={1}>{p.label}</Text>
              ))}
            </View>
          </View>

          {/* ── Night Mode ─────────────────────────────────────────────────── */}
          <View style={styles.section}>
            <Text style={shared.sectionLabel}>Night Mode</Text>
            <Text style={shared.hint}>
              Automatically switch the TV to a quiet night display between set hours.
            </Text>

            <View style={styles.toggleRow}>
              <Text style={styles.toggleLabel}>Enable Night Mode</Text>
              <Switch
                value={nightEnabled}
                onValueChange={setNightEnabled}
                trackColor={{ false: colors.border, true: colors.accent }}
                thumbColor="#fff"
              />
            </View>

            <View style={[styles.nightFields, !nightEnabled && styles.nightFieldsDisabled]}>
              <View style={styles.timeRow}>
                <View style={styles.timeField}>
                  <Text style={styles.fieldLabel}>Start (24h)</Text>
                  <TextInput
                    style={shared.input}
                    value={nightStart}
                    onChangeText={setNightStart}
                    placeholder="22:00"
                    placeholderTextColor={colors.placeholderColor}
                    keyboardType="numbers-and-punctuation"
                    maxLength={5}
                    editable={nightEnabled}
                  />
                </View>
                <Text style={styles.timeArrow}>→</Text>
                <View style={styles.timeField}>
                  <Text style={styles.fieldLabel}>End (24h)</Text>
                  <TextInput
                    style={shared.input}
                    value={nightEnd}
                    onChangeText={setNightEnd}
                    placeholder="07:00"
                    placeholderTextColor={colors.placeholderColor}
                    keyboardType="numbers-and-punctuation"
                    maxLength={5}
                    editable={nightEnabled}
                  />
                </View>
              </View>

              <View>
                <Text style={styles.fieldLabel}>Night Message</Text>
                <Text style={shared.hint}>
                  Shown on image rotator cards and the idle screen during night mode.
                </Text>
                <TextInput
                  style={shared.input}
                  value={nightMessage}
                  onChangeText={setNightMessage}
                  placeholder="Good Night"
                  placeholderTextColor={colors.placeholderColor}
                  editable={nightEnabled}
                />
              </View>

              <View style={styles.toggleRow}>
                <View style={{ flex: 1 }}>
                  <Text style={styles.toggleLabel}>Dim Background</Text>
                  <Text style={[shared.hint, { marginTop: 0 }]}>
                    Hide background image/colour and darken the display.
                  </Text>
                </View>
                <Switch
                  value={nightDim}
                  onValueChange={setNightDim}
                  trackColor={{ false: colors.border, true: colors.accent }}
                  thumbColor="#fff"
                  disabled={!nightEnabled}
                />
              </View>
            </View>

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

          {/* ── Status message ─────────────────────────────────────────────── */}
          {status && (
            <Text style={[shared.hint, styles.statusText]}>{status}</Text>
          )}

          {/* ── Server ─────────────────────────────────────────────────────── */}
          <View style={styles.section}>
            <Text style={shared.sectionLabel}>Server</Text>
            <Text style={shared.hint} numberOfLines={2}>{BASE_URL}</Text>
            <TouchableOpacity
              style={shared.btnSecondary}
              onPress={resetUrl}
              activeOpacity={0.8}
            >
              <Text style={shared.btnSecondaryText}>Change Server URL</Text>
            </TouchableOpacity>
          </View>
        </>
      )}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 24,
    gap: 28,
    paddingBottom: 48,
  },
  section: {
    gap: 12,
  },

  // ── Background image preview
  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,
  },

  // ── Background colour
  colorRow: {
    flexDirection: "row",
    alignItems: "center",
    gap: 10,
  },
  colorSwatch: {
    width: 44,
    height: 44,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: colors.border,
  },
  colorSaveBtn: {
    paddingHorizontal: 16,
    height: 44,
  },
  swatchRow: {
    flexDirection: "row",
    gap: 8,
  },
  swatchBtn: {
    flex: 1,
    aspectRatio: 1,
    borderRadius: 8,
    borderWidth: 1,
    borderColor: colors.border,
  },
  swatchSelected: {
    borderWidth: 2,
    borderColor: colors.accent,
  },
  swatchLabelsRow: {
    flexDirection: "row",
    gap: 8,
  },
  swatchLabel: {
    flex: 1,
    fontSize: 9,
    color: colors.textMuted,
    textAlign: "center",
  },

  // ── Night mode
  toggleRow: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    gap: 12,
  },
  toggleLabel: {
    fontSize: 15,
    fontWeight: "600",
    color: colors.textPrimary,
    flex: 1,
  },
  nightFields: {
    gap: 16,
    borderLeftWidth: 2,
    borderLeftColor: colors.accentDim,
    paddingLeft: 14,
  },
  nightFieldsDisabled: {
    opacity: 0.45,
  },
  timeRow: {
    flexDirection: "row",
    alignItems: "flex-end",
    gap: 8,
  },
  timeField: {
    flex: 1,
    gap: 6,
  },
  timeArrow: {
    color: colors.textMuted,
    fontSize: 18,
    paddingBottom: 10,
  },
  fieldLabel: {
    fontSize: 12,
    fontWeight: "600",
    color: colors.textMuted,
    textTransform: "uppercase",
    letterSpacing: 0.4,
    marginBottom: 2,
  },

  // ── Status
  statusText: {
    color: colors.textSecondary,
    textAlign: "center",
  },
});
