// Zarządzanie blacklistą treści — ukryte tagi / performerzy / studia. Sceny z
// blacklisted entity wypadają z każdego /scenes (backend auto-apply, app/api/blacklist.py).
//
// Powód (user-report 86a9ec72: "remove all gay scenes from randomly popping up"): nie było
// żadnego UI do (a) ukrycia tagu, (b) podejrzenia/cofnięcia blacklisty — mimo że Alert przy
// "Hide performer" obiecywał "undo from Settings → Blacklist". Ten ekran domyka oba.
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import React, { useState } from 'react';
import {
  ActivityIndicator,
  FlatList,
  Pressable,
  StyleSheet,
  Text,
  TextInput,
  View,
} from 'react-native';

import { useClient } from '../ClientContext';
import { theme } from '../theme';
import type { BlacklistEntry, BlacklistKind, TagCount } from '../types';

export function BlacklistScreen() {
  const client = useClient();
  const queryClient = useQueryClient();
  const [tagQ, setTagQ] = useState('');

  const blacklistQuery = useQuery({
    queryKey: ['blacklist'],
    queryFn: () => client.listBlacklist(),
  });

  const tagSearch = useQuery({
    queryKey: ['blacklist-tag-search', tagQ],
    queryFn: () => client.listTags({ q: tagQ || undefined, per_page: 40 }),
    enabled: tagQ.trim().length > 0,
  });

  const afterChange = () => {
    queryClient.invalidateQueries({ queryKey: ['blacklist'] });
    // Listy scen filtrują po blackliście — odśwież leniwie (bez wymuszania refetcha).
    queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
  };

  const addTag = useMutation({
    mutationFn: (id: string) => client.addBlacklist('tag', id),
    onSuccess: afterChange,
  });
  const remove = useMutation({
    mutationFn: ({ kind, id }: { kind: BlacklistKind; id: string }) =>
      client.removeBlacklist(kind, id),
    onSuccess: afterChange,
  });

  const bl = blacklistQuery.data;
  const blacklistedTagIds = new Set((bl?.tags ?? []).map((t) => t.id));

  const renderRow = (kind: BlacklistKind, e: BlacklistEntry) => (
    <View key={`${kind}-${e.id}`} style={styles.row}>
      <Text style={styles.rowName} numberOfLines={1}>
        {e.name}
      </Text>
      <Pressable
        hitSlop={10}
        onPress={() => remove.mutate({ kind, id: e.id })}
        style={styles.removeBtn}
      >
        <Text style={styles.removeText}>Unhide</Text>
      </Pressable>
    </View>
  );

  return (
    <FlatList
      style={styles.root}
      data={[1]}
      keyExtractor={() => 'x'}
      renderItem={() => (
        <View style={{ paddingBottom: 40 }}>
          <Text style={styles.intro}>
            Scenes tagged with — or from — anything you hide here stop showing up anywhere in
            the app. Add a tag below (e.g. a category you never want to see).
          </Text>

          <Text style={styles.sectionTitle}>Hide a tag</Text>
          <TextInput
            style={styles.search}
            value={tagQ}
            onChangeText={setTagQ}
            placeholder="search tags to hide…"
            placeholderTextColor={theme.muted}
            autoCapitalize="none"
            autoCorrect={false}
          />
          {tagQ.trim().length > 0 ? (
            tagSearch.isLoading ? (
              <ActivityIndicator color={theme.fg} style={{ margin: 12 }} />
            ) : (
              <View style={styles.chips}>
                {(tagSearch.data?.items ?? []).map((tag: TagCount) => {
                  const already = blacklistedTagIds.has(tag.id);
                  return (
                    <Pressable
                      key={tag.id}
                      disabled={already || addTag.isPending}
                      style={[styles.chip, already && styles.chipDisabled]}
                      onPress={() => addTag.mutate(tag.id)}
                    >
                      <Text style={[styles.chipText, already && styles.chipTextDisabled]}>
                        {already ? '✓ ' : '+ '}
                        {tag.name}
                      </Text>
                    </Pressable>
                  );
                })}
              </View>
            )
          ) : null}

          {blacklistQuery.isLoading ? (
            <ActivityIndicator color={theme.fg} style={{ marginTop: 24 }} />
          ) : (
            <>
              <Section title="Hidden tags" count={bl?.tags.length ?? 0}>
                {(bl?.tags ?? []).map((e) => renderRow('tag', e))}
              </Section>
              <Section title="Hidden performers" count={bl?.performers.length ?? 0}>
                {(bl?.performers ?? []).map((e) => renderRow('performer', e))}
              </Section>
              <Section title="Hidden studios" count={bl?.studios.length ?? 0}>
                {(bl?.studios ?? []).map((e) => renderRow('studio', e))}
              </Section>
            </>
          )}
        </View>
      )}
    />
  );
}

function Section({
  title,
  count,
  children,
}: {
  title: string;
  count: number;
  children: React.ReactNode;
}) {
  return (
    <View style={styles.section}>
      <Text style={styles.sectionTitle}>
        {title} {count > 0 ? `(${count})` : ''}
      </Text>
      {count === 0 ? <Text style={styles.empty}>nothing hidden</Text> : children}
    </View>
  );
}

const styles = StyleSheet.create({
  root: { flex: 1, backgroundColor: theme.bg },
  intro: {
    color: theme.muted,
    fontSize: 13,
    lineHeight: 19,
    paddingHorizontal: 16,
    paddingTop: 16,
    paddingBottom: 4,
  },
  section: {
    paddingVertical: 12,
    borderTopColor: theme.border,
    borderTopWidth: 1,
    marginTop: 12,
  },
  sectionTitle: {
    color: theme.muted,
    fontSize: 12,
    textTransform: 'uppercase',
    letterSpacing: 0.5,
    marginBottom: 10,
    paddingHorizontal: 16,
  },
  search: {
    backgroundColor: theme.card,
    borderColor: theme.border,
    borderWidth: 1,
    borderRadius: 8,
    color: theme.fg,
    padding: 10,
    marginHorizontal: 16,
  },
  chips: { flexDirection: 'row', flexWrap: 'wrap', gap: 6, padding: 16 },
  chip: {
    backgroundColor: theme.card,
    borderColor: theme.accent,
    borderWidth: 1,
    borderRadius: 14,
    paddingHorizontal: 10,
    paddingVertical: 5,
  },
  chipDisabled: { borderColor: theme.border, opacity: 0.6 },
  chipText: { color: theme.accent, fontSize: 13 },
  chipTextDisabled: { color: theme.muted },
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingVertical: 8,
    paddingHorizontal: 16,
  },
  rowName: { color: theme.fg, fontSize: 15, flex: 1, marginRight: 12 },
  removeBtn: {
    borderColor: theme.border,
    borderWidth: 1,
    borderRadius: 8,
    paddingHorizontal: 12,
    paddingVertical: 6,
  },
  removeText: { color: theme.accent, fontSize: 13, fontWeight: '600' },
  empty: { color: theme.muted, fontSize: 13, paddingHorizontal: 16 },
});
