import { Feather } from "@expo/vector-icons";
import { Image } from "expo-image";
import React, { useCallback, useEffect, useState } from "react";
import {
  ActivityIndicator,
  FlatList,
  Modal,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useColors } from "@/hooks/useColors";

interface MediaItem {
  id: string;
  path: string;
  createdAt?: string;
}

interface Props {
  visible: boolean;
  baseUrl: string;
  apiKey: string;
  maxSelect: number;
  onClose: () => void;
  onSelect: (items: MediaItem[]) => void;
}

function resolveUrl(path: string, baseUrl: string): string {
  if (path.startsWith("http://") || path.startsWith("https://")) return path;
  const origin = baseUrl.replace(/\/api\/.*$/, "");
  return `${origin}/${path.replace(/^\//, "")}`;
}

export function MediaLibraryModal({ visible, baseUrl, apiKey, maxSelect, onClose, onSelect }: Props) {
  const colors = useColors();
  const insets = useSafeAreaInsets();
  const [items, setItems] = useState<MediaItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [selected, setSelected] = useState<Set<string>>(new Set());

  const load = useCallback(async () => {
    if (!baseUrl || !apiKey) return;
    setLoading(true);
    setError(null);
    try {
      // eslint-disable-next-line no-undef
      const res = await globalThis.fetch(`${baseUrl}/media`, {
        headers: { Authorization: apiKey },
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      const list: MediaItem[] = Array.isArray(data)
        ? data
        : (data?.media ?? data?.items ?? data?.files ?? []);
      setItems(list);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : "Failed to load media");
    } finally {
      setLoading(false);
    }
  }, [baseUrl, apiKey]);

  useEffect(() => {
    if (visible) {
      setSelected(new Set());
      load();
    }
  }, [visible, load]);

  const toggle = (id: string) => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
      } else if (next.size < maxSelect) {
        next.add(id);
      }
      return next;
    });
  };

  const handleConfirm = () => {
    const chosen = items.filter((i) => selected.has(i.id));
    onSelect(chosen);
  };

  return (
    <Modal visible={visible} animationType="slide" onRequestClose={onClose}>
      <View style={[styles.root, { backgroundColor: colors.background, paddingTop: insets.top }]}>
        <View style={[styles.header, { borderBottomColor: colors.border }]}>
          <TouchableOpacity onPress={onClose} activeOpacity={0.7} style={styles.closeBtn}>
            <Feather name="x" size={20} color={colors.foreground} />
          </TouchableOpacity>
          <Text style={[styles.title, { color: colors.foreground }]}>Media Library</Text>
          <TouchableOpacity
            onPress={handleConfirm}
            disabled={selected.size === 0}
            activeOpacity={0.8}
            style={[
              styles.addBtn,
              { backgroundColor: selected.size > 0 ? colors.primary : colors.muted },
            ]}
          >
            <Text style={[styles.addBtnText, { color: colors.primaryForeground }]}>
              {selected.size > 0 ? `Add ${selected.size}` : "Add"}
            </Text>
          </TouchableOpacity>
        </View>

        {loading ? (
          <View style={styles.centered}>
            <ActivityIndicator color={colors.primary} size="large" />
          </View>
        ) : error ? (
          <View style={styles.centered}>
            <Feather name="alert-circle" size={28} color={colors.error} />
            <Text style={[styles.errorText, { color: colors.mutedForeground }]}>{error}</Text>
            <TouchableOpacity
              onPress={load}
              style={[styles.retryBtn, { backgroundColor: colors.primary }]}
              activeOpacity={0.8}
            >
              <Text style={[styles.retryText, { color: colors.primaryForeground }]}>Retry</Text>
            </TouchableOpacity>
          </View>
        ) : items.length === 0 ? (
          <View style={styles.centered}>
            <Feather name="image" size={36} color={colors.mutedForeground} />
            <Text style={[styles.emptyText, { color: colors.mutedForeground }]}>No media found</Text>
          </View>
        ) : (
          <FlatList
            data={items}
            keyExtractor={(item) => item.id}
            numColumns={3}
            contentContainerStyle={[styles.grid, { paddingBottom: insets.bottom + 16 }]}
            renderItem={({ item }) => {
              const isSelected = selected.has(item.id);
              const uri = resolveUrl(item.path, baseUrl);
              return (
                <TouchableOpacity
                  onPress={() => toggle(item.id)}
                  activeOpacity={0.8}
                  style={styles.cell}
                >
                  <Image
                    source={{ uri }}
                    style={styles.cellImage}
                    contentFit="cover"
                  />
                  {isSelected && (
                    <View style={[styles.selectedOverlay, { backgroundColor: colors.primary + "99" }]}>
                      <View style={[styles.checkCircle, { backgroundColor: colors.primary }]}>
                        <Feather name="check" size={14} color="#fff" />
                      </View>
                    </View>
                  )}
                </TouchableOpacity>
              );
            }}
          />
        )}
      </View>
    </Modal>
  );
}

const CELL = 120;

const styles = StyleSheet.create({
  root: { flex: 1 },
  header: {
    flexDirection: "row",
    alignItems: "center",
    paddingHorizontal: 16,
    paddingVertical: 14,
    borderBottomWidth: StyleSheet.hairlineWidth,
    gap: 12,
  },
  closeBtn: { padding: 4 },
  title: { flex: 1, fontSize: 17, fontFamily: "Inter_600SemiBold" },
  addBtn: { paddingHorizontal: 16, paddingVertical: 8, borderRadius: 20 },
  addBtnText: { fontSize: 14, fontFamily: "Inter_600SemiBold" },
  centered: { flex: 1, alignItems: "center", justifyContent: "center", gap: 12 },
  errorText: { fontSize: 14, fontFamily: "Inter_400Regular", textAlign: "center", paddingHorizontal: 32 },
  emptyText: { fontSize: 14, fontFamily: "Inter_400Regular" },
  retryBtn: { paddingHorizontal: 20, paddingVertical: 10, borderRadius: 10 },
  retryText: { fontSize: 14, fontFamily: "Inter_600SemiBold" },
  grid: { padding: 2 },
  cell: { width: CELL, height: CELL, margin: 2 },
  cellImage: { width: CELL, height: CELL, borderRadius: 4 },
  selectedOverlay: {
    ...StyleSheet.absoluteFillObject,
    borderRadius: 4,
    alignItems: "center",
    justifyContent: "center",
  },
  checkCircle: {
    width: 28,
    height: 28,
    borderRadius: 14,
    alignItems: "center",
    justifyContent: "center",
  },
});
