/**
 * Floating "?" button + bug report modal — wisi nad każdą stroną aplikacji.
 *
 * UX:
 *  1. Tap FAB → app robi screenshot CIEnte (przed otwarciem modal'u, więc nie
 *     zawiera samego buttonu/modal'u) przez react-native-view-shot.captureScreen.
 *  2. Modal pokazuje preview screenshota + TextInput + opcję "wyślij bez screena"
 *     + Send/Cancel.
 *  3. Send → POST /bug-reports z message + screen_name (z React Navigation focused
 *     route) + scene_id (jeśli dostarczone w nav params) + base64 screenshot.
 *
 * Screenshot omija FLAG_SECURE bo to in-process render (View.draw → bitmap),
 * nie systemowy MediaProjection.
 */
import type { NavigationContainerRef, ParamListBase } from '@react-navigation/native';
import React, { useCallback, useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  Image,
  KeyboardAvoidingView,
  Modal,
  Platform,
  Pressable,
  StyleSheet,
  Switch,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';
import { captureScreen } from 'react-native-view-shot';

import { GoonClient } from '../api';
import { theme } from '../theme';

interface Props {
  client: GoonClient | null;
  appVersion: string;
  navRef: NavigationContainerRef<ParamListBase>;
}

// Screens na których FAB jest ukryty — Player ma fullscreen controls i FAB
// nakłada się na progress bar / fullscreen button (bug #f53e50b9 screenshot
// pokazał "?" zasłaniający duration label).
const FAB_HIDDEN_SCREENS = new Set(['Player']);

export function BugReportFAB({ client, appVersion, navRef }: Props) {
  const [open, setOpen] = useState(false);
  const [screenshot, setScreenshot] = useState<string | null>(null);
  const [includeScreenshot, setIncludeScreenshot] = useState(true);
  const [message, setMessage] = useState('');
  const [submitting, setSubmitting] = useState(false);
  // Re-render na zmianę current route, żeby FAB pojawiał/znikał per-screen.
  const [currentRoute, setCurrentRoute] = useState<string | null>(null);
  React.useEffect(() => {
    if (!navRef) return;
    const unsub = navRef.addListener('state', () => {
      try {
        const r = navRef.isReady() ? navRef.getCurrentRoute() : null;
        setCurrentRoute(r?.name ?? null);
      } catch {
        setCurrentRoute(null);
      }
    });
    return unsub;
  }, [navRef]);
  const hidden = currentRoute !== null && FAB_HIDDEN_SCREENS.has(currentRoute);

  const onPress = useCallback(async () => {
    let captured: string | null = null;
    try {
      const dataUri = await captureScreen({
        format: 'jpg',
        quality: 0.6,
        result: 'data-uri',
      });
      captured = dataUri.split(',')[1] || null;
    } catch (e) {
      captured = null;
    }
    setScreenshot(captured);
    setIncludeScreenshot(captured !== null);
    setMessage('');
    setOpen(true);
  }, []);

  const submit = useCallback(async () => {
    if (!client) {
      Alert.alert('Bug report', 'Brak połączenia z backendem.');
      return;
    }
    if (!message.trim()) {
      Alert.alert('Bug report', 'Wpisz krótki opis.');
      return;
    }
    setSubmitting(true);
    let routeName: string | null = null;
    let rawSceneId: string | undefined;
    try {
      const route = navRef.isReady() ? navRef.getCurrentRoute() : null;
      routeName = route?.name ?? null;
      const params = (route?.params ?? {}) as Record<string, unknown>;
      rawSceneId =
        (params['sceneId'] as string | undefined) ??
        (params['id'] as string | undefined);
    } catch {
      // navRef nie ready — zostawiamy puste, backend i tak przyjmie nullable
    }
    const sceneId =
      rawSceneId && /^[0-9a-f-]{36}$/.test(rawSceneId) ? rawSceneId : null;
    try {
      await client.submitBugReport({
        message: message.trim(),
        screen_name: routeName,
        app_version: appVersion,
        scene_id: sceneId,
        screenshot_b64: includeScreenshot ? screenshot : null,
      });
      setOpen(false);
      setMessage('');
      setScreenshot(null);
      Alert.alert('Bug report', 'Wysłano. Dzięki!');
    } catch (e) {
      Alert.alert('Bug report', `Nie udało się wysłać: ${(e as Error).message}`);
    } finally {
      setSubmitting(false);
    }
  }, [client, message, screenshot, includeScreenshot, appVersion, navRef]);

  return (
    <>
      {!hidden ? (
        <TouchableOpacity style={styles.fab} onPress={onPress} activeOpacity={0.7}>
          <Text style={styles.fabIcon}>?</Text>
        </TouchableOpacity>
      ) : null}

      <Modal
        visible={open}
        animationType="slide"
        transparent
        onRequestClose={() => setOpen(false)}
      >
        <KeyboardAvoidingView
          style={styles.backdrop}
          behavior={Platform.OS === 'ios' ? 'padding' : undefined}
        >
          <Pressable style={styles.backdropTap} onPress={() => setOpen(false)} />
          <View style={styles.sheet}>
            <Text style={styles.title}>Zgłoś buga</Text>

            {screenshot ? (
              <View style={styles.preview}>
                <Image
                  source={{ uri: `data:image/jpeg;base64,${screenshot}` }}
                  style={styles.previewImg}
                  resizeMode="contain"
                />
                <View style={styles.toggleRow}>
                  <Text style={styles.toggleLabel}>Dołącz screenshot</Text>
                  <Switch
                    value={includeScreenshot}
                    onValueChange={setIncludeScreenshot}
                    thumbColor={includeScreenshot ? theme.accent : theme.muted}
                    trackColor={{
                      true: theme.accentDeep,
                      false: theme.border,
                    }}
                  />
                </View>
              </View>
            ) : (
              <Text style={styles.noScreenshot}>
                Screenshot niedostępny (capture fail). Wyślę sam tekst.
              </Text>
            )}

            <TextInput
              style={styles.input}
              value={message}
              onChangeText={setMessage}
              placeholder="Co jest nie tak? Tytuł sceny / co próbujesz zrobić / co zobaczyłeś"
              placeholderTextColor={theme.mutedDim}
              multiline
              autoFocus
            />

            <View style={styles.btnRow}>
              <TouchableOpacity
                style={[styles.btn, styles.btnCancel]}
                onPress={() => setOpen(false)}
                disabled={submitting}
              >
                <Text style={styles.btnText}>Anuluj</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={[styles.btn, styles.btnSend]}
                onPress={submit}
                disabled={submitting}
              >
                {submitting ? (
                  <ActivityIndicator color={theme.fg} />
                ) : (
                  <Text style={styles.btnText}>Wyślij</Text>
                )}
              </TouchableOpacity>
            </View>
          </View>
        </KeyboardAvoidingView>
      </Modal>
    </>
  );
}

const styles = StyleSheet.create({
  fab: {
    position: 'absolute',
    right: 16,
    bottom: 24,
    width: 44,
    height: 44,
    borderRadius: 22,
    backgroundColor: theme.accentDeep,
    alignItems: 'center',
    justifyContent: 'center',
    elevation: 6,
    shadowColor: '#000',
    shadowOpacity: 0.4,
    shadowRadius: 6,
    shadowOffset: { width: 0, height: 3 },
    opacity: 0.85,
  },
  fabIcon: {
    color: theme.fg,
    fontSize: 22,
    fontWeight: '700',
  },
  backdrop: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.6)',
    justifyContent: 'flex-end',
  },
  backdropTap: {
    flex: 1,
  },
  sheet: {
    backgroundColor: theme.bgElevated,
    borderTopLeftRadius: 20,
    borderTopRightRadius: 20,
    padding: 20,
    paddingBottom: 28,
    maxHeight: '90%',
  },
  title: {
    color: theme.fg,
    fontSize: 18,
    fontWeight: '600',
    marginBottom: 12,
  },
  preview: {
    marginBottom: 12,
  },
  previewImg: {
    width: '100%',
    height: 180,
    borderRadius: 8,
    backgroundColor: theme.bg,
  },
  toggleRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginTop: 8,
  },
  toggleLabel: {
    color: theme.muted,
    fontSize: 14,
  },
  noScreenshot: {
    color: theme.warn,
    fontSize: 13,
    marginBottom: 12,
    textAlign: 'center',
  },
  input: {
    backgroundColor: theme.card,
    borderColor: theme.border,
    borderWidth: 1,
    borderRadius: 8,
    color: theme.fg,
    padding: 12,
    minHeight: 100,
    textAlignVertical: 'top',
    marginBottom: 16,
  },
  btnRow: {
    flexDirection: 'row',
    gap: 12,
  },
  btn: {
    flex: 1,
    paddingVertical: 12,
    borderRadius: 8,
    alignItems: 'center',
    justifyContent: 'center',
  },
  btnCancel: {
    backgroundColor: theme.card,
    borderColor: theme.border,
    borderWidth: 1,
  },
  btnSend: {
    backgroundColor: theme.accent,
  },
  btnText: {
    color: theme.fg,
    fontSize: 15,
    fontWeight: '600',
  },
});
