/**
 * Tutorial przy pierwszym odpaleniu — paged carousel po stronach, funkcjach,
 * longpressach i gestach playera. Pokazuje się raz (flaga goon.onboarding_seen_v1
 * w SecureStore); replay z ustawień przez onboardingBus. Montowany raz nad
 * nawigacją (App.tsx), niezależny od ekranów — slajdy opisują UI ilustracyjnie,
 * bez spotlightowania realnych elementów (odporne na zmiany layoutu).
 *
 * Treść trzymać ZGODNĄ z realnymi gestami/akcjami (patrz SceneActionsContext,
 * PlayerScreen gesty, SceneDetail performer long-press, navigation TopTabs).
 */
import React from 'react';
import {
  Modal,
  NativeScrollEvent,
  NativeSyntheticEvent,
  Pressable,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from 'react-native';

import { NEWEST_CHANGELOG_ID } from '../changelog';
import { onReplay } from '../lib/onboardingBus';
import { getOnboardingSeen, setLastSeenChangelog, setOnboardingSeen } from '../storage';
import { theme } from '../theme';

type Slide = { icon: string; title: string; lines: string[] };

const SLIDES: Slide[] = [
  {
    icon: '👋',
    title: 'Welcome to Goon',
    lines: [
      'Scenes and movies pulled together from 30+ sites — browse and play in one place.',
      'Quick tour, about 30 seconds. Swipe or tap Next.',
    ],
  },
  {
    icon: '🗂️',
    title: 'Three tabs up top',
    lines: [
      'Scenes — individual clips.',
      'Movies — full-length, often multi-part.',
      'Sites — browse by source, each rated 0–5★.',
    ],
  },
  {
    icon: '🔎',
    title: 'Find what you want',
    lines: [
      'Search, then Filter by length, tags, studio, performer or sort.',
      'Tap ☆ Save next to the search box to reuse a query as a chip.',
      'From Scenes you can jump to Performers, Tags and Favorites.',
    ],
  },
  {
    icon: '👆',
    title: 'Long-press for more',
    lines: [
      'Hold a scene tile → Hide it, or mark it as a duplicate.',
      'Hold a performer on a scene → remove a wrong tag.',
      'Hold a play link → open in browser (diagnostics) or mark it broken.',
    ],
  },
  {
    icon: '▶️',
    title: 'Player gestures',
    lines: [
      'Tap once → show or hide the controls.',
      'Double-tap left / right → skip back / forward 15s.',
      'Swipe across the video → scrub to any point.',
      'It starts muted — tap the speaker for sound.',
    ],
  },
  {
    icon: '⭐',
    title: 'Make it yours',
    lines: [
      'Heart scenes, movies and performers — they collect in Favorites.',
      'Settings ⚙ → Hidden content hides tags, performers or studios. Grid columns and a PIN lock live there too.',
      'Hit a problem? The ? button sends a report — and you can read replies.',
    ],
  },
  {
    icon: '✅',
    title: "You're set",
    lines: [
      'On Sites, the ★ rating tells you what’s fresh and what actually plays — tap the stars for the breakdown.',
      'Replay this tour anytime: Settings ⚙ → Replay tutorial.',
    ],
  },
];

export function OnboardingModal() {
  const [visible, setVisible] = React.useState(false);
  const [index, setIndex] = React.useState(0);
  const scrollRef = React.useRef<ScrollView>(null);
  // Szerokość STRONY = realna szerokość viewportu ScrollView (mierzona onLayout),
  // NIE szerokość ekranu — karta ma marginesy + padding, więc ekran ≠ strona.
  // Użycie szerokości ekranu rozjeżdżało paging vs scrollTo vs index (ostatni
  // slajd pokazywał "Next" zamiast "Start browsing").
  const [pageW, setPageW] = React.useState(0);

  // Pierwsze odpalenie: pokaż jeśli jeszcze nie widziany.
  React.useEffect(() => {
    let cancelled = false;
    getOnboardingSeen().then((seen) => {
      if (!cancelled && !seen) setVisible(true);
    });
    return () => {
      cancelled = true;
    };
  }, []);

  // Replay z ustawień.
  React.useEffect(
    () =>
      onReplay(() => {
        setIndex(0);
        setVisible(true);
        // reset pozycji scrolla po otwarciu
        requestAnimationFrame(() => scrollRef.current?.scrollTo({ x: 0, animated: false }));
      }),
    [],
  );

  const finish = React.useCallback(() => {
    setVisible(false);
    setOnboardingSeen(true).catch(() => {});
    // Nowy user nie powinien po tutorialu dostać od razu "What's new" — oznacz
    // changelog jako widziany do najnowszego wpisu.
    if (NEWEST_CHANGELOG_ID) setLastSeenChangelog(NEWEST_CHANGELOG_ID).catch(() => {});
  }, []);

  const goTo = React.useCallback(
    (i: number) => {
      const clamped = Math.max(0, Math.min(SLIDES.length - 1, i));
      setIndex(clamped);
      if (pageW > 0) scrollRef.current?.scrollTo({ x: clamped * pageW, animated: true });
    },
    [pageW],
  );

  const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
    if (pageW <= 0) return;
    const i = Math.round(e.nativeEvent.contentOffset.x / pageW);
    if (i !== index) setIndex(i);
  };

  if (!visible) return null;
  const isLast = index === SLIDES.length - 1;

  return (
    <Modal visible transparent animationType="fade" onRequestClose={finish}>
      <View style={styles.backdrop}>
        <View style={styles.card}>
          <View style={styles.topRow}>
            <Text style={styles.brand}>GOON</Text>
            <Pressable onPress={finish} hitSlop={10}>
              <Text style={styles.skip}>{isLast ? '' : 'Skip'}</Text>
            </Pressable>
          </View>

          <ScrollView
            ref={scrollRef}
            horizontal
            pagingEnabled
            showsHorizontalScrollIndicator={false}
            onMomentumScrollEnd={onScroll}
            onLayout={(e) => setPageW(e.nativeEvent.layout.width)}
            style={styles.pager}
          >
            {SLIDES.map((s, i) => (
              <View key={i} style={[styles.slide, pageW > 0 && { width: pageW }]}>
                <Text style={styles.icon}>{s.icon}</Text>
                <Text style={styles.title}>{s.title}</Text>
                <View style={styles.lines}>
                  {s.lines.map((ln, j) => (
                    <View key={j} style={styles.lineRow}>
                      <Text style={styles.bullet}>•</Text>
                      <Text style={styles.lineText}>{ln}</Text>
                    </View>
                  ))}
                </View>
              </View>
            ))}
          </ScrollView>

          <View style={styles.dots}>
            {SLIDES.map((_, i) => (
              <View key={i} style={[styles.dot, i === index && styles.dotActive]} />
            ))}
          </View>

          <View style={styles.btnRow}>
            <Pressable
              onPress={() => goTo(index - 1)}
              disabled={index === 0}
              style={[styles.btnGhost, index === 0 && styles.btnHidden]}
            >
              <Text style={styles.btnGhostText}>Back</Text>
            </Pressable>
            <Pressable onPress={() => (isLast ? finish() : goTo(index + 1))} style={styles.btnPrimary}>
              <Text style={styles.btnPrimaryText}>{isLast ? 'Start browsing' : 'Next'}</Text>
            </Pressable>
          </View>
        </View>
      </View>
    </Modal>
  );
}

const styles = StyleSheet.create({
  backdrop: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.82)',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 24,
  },
  card: {
    width: '100%',
    backgroundColor: theme.bgElevated,
    borderRadius: 18,
    borderColor: theme.border,
    borderWidth: 1,
    paddingVertical: 18,
    paddingHorizontal: 24,
  },
  topRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: 6,
  },
  brand: { color: theme.accent, fontWeight: '900', letterSpacing: 2, fontSize: 13 },
  skip: { color: theme.muted, fontSize: 14, fontWeight: '600', minWidth: 36, textAlign: 'right' },

  pager: { flexGrow: 0 },
  slide: { paddingTop: 14, paddingBottom: 8, minHeight: 250 },
  icon: { fontSize: 44, marginBottom: 12 },
  title: { color: theme.fg, fontSize: 22, fontWeight: '800', marginBottom: 16 },
  lines: { gap: 12 },
  lineRow: { flexDirection: 'row', gap: 10 },
  bullet: { color: theme.accent, fontSize: 16, lineHeight: 22 },
  lineText: { color: theme.fg, fontSize: 15, lineHeight: 22, flex: 1 },

  dots: { flexDirection: 'row', justifyContent: 'center', gap: 6, marginVertical: 16 },
  dot: { width: 7, height: 7, borderRadius: 4, backgroundColor: theme.border },
  dotActive: { backgroundColor: theme.accent, width: 18 },

  btnRow: { flexDirection: 'row', alignItems: 'center', gap: 12 },
  btnGhost: { paddingVertical: 12, paddingHorizontal: 18, borderRadius: 12 },
  btnHidden: { opacity: 0 },
  btnGhostText: { color: theme.muted, fontSize: 15, fontWeight: '700' },
  btnPrimary: {
    flex: 1,
    backgroundColor: theme.accent,
    borderRadius: 12,
    paddingVertical: 13,
    alignItems: 'center',
  },
  btnPrimaryText: { color: theme.fg, fontSize: 15, fontWeight: '800' },
});
