import React, { useState, useCallback } from 'react';
import { View, Text, Pressable, StyleSheet, BackHandler, Platform } from 'react-native';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { StatusBar } from 'expo-status-bar';
import type { PostSummary } from '@ai-radar/shared';
import { ThemeProvider, useTheme } from './src/theme/ThemeProvider';
import { SavedProvider } from './src/lib/saved';
import { AuthProvider } from './src/lib/auth';
import { textStyle, space } from './src/theme';
import { getDict } from './src/lib/dictionary';
import { TabBar, type TabKey } from './src/components/TabBar';
import { TodayScreen } from './src/screens/TodayScreen';
import { SectionsScreen } from './src/screens/SectionsScreen';
import { SavedScreen } from './src/screens/SavedScreen';
import { SettingsScreen } from './src/screens/SettingsScreen';
import { StoryScreen } from './src/screens/StoryScreen';
import * as Notifications from 'expo-notifications';
import { notificationSlug } from './src/lib/push';

/** What the story stack needs: enough to render a header and fetch. */
interface StackEntry {
  slug: string;
  companyName: string | null;
}

/**
 * AI Radar.
 *
 * Four tabs and a story view. Navigation is a small piece of local state
 * rather than React Navigation: the whole app is "tabs, plus a stack of
 * stories", and hand-rolling that is less code than configuring a
 * navigator — with no library upgrade to track for a shape this simple.
 *
 * If deep links or push-to-story arrive in 7c and this stops being
 * enough, swapping in a navigator is contained to this file.
 */
function Shell() {
  const { palette, locale, scheme } = useTheme();
  const dict = getDict(locale);

  const [tab, setTab] = useState<TabKey>('today');

  // A stack, so Related → Related → back walks back correctly.
  //
  // Holds only what this component needs to render the header and hand
  // StoryScreen a slug — not a full PostSummary, because a notification
  // arrives carrying nothing but the slug and casting it to a summary
  // would be a lie about what is there.
  const [stack, setStack] = useState<StackEntry[]>([]);

  const open = useCallback((post: PostSummary) => {
    setStack((s) => [...s, { slug: post.slug, companyName: post.companyName }]);
  }, []);

  const back = useCallback(() => {
    setStack((s) => s.slice(0, -1));
  }, []);

  // A tapped notification opens straight to its story.
  //
  // Only the slug travels in the payload, so the story is fetched like
  // any other — a notification cannot inject content into the app.
  React.useEffect(() => {
    if (Platform.OS === 'web') return;

    const sub = Notifications.addNotificationResponseReceivedListener((response) => {
      const slug = notificationSlug(response);
      if (!slug) return;

      // StoryScreen fetches by slug, so this is all it needs; the
      // header falls back to the brand until that lands.
      setStack((s) => [...s, { slug, companyName: null }]);
    });
    return () => sub.remove();
  }, []);

  // Android's system back closes the story before leaving the app.
  // Web has no hardware back button and BackHandler warns loudly there.
  React.useEffect(() => {
    if (Platform.OS !== 'android') return;

    const sub = BackHandler.addEventListener('hardwareBackPress', () => {
      if (stack.length > 0) {
        back();
        return true;
      }
      return false;
    });
    return () => sub.remove();
  }, [stack.length, back]);

  const current = stack[stack.length - 1];

  return (
    <View style={{ flex: 1, backgroundColor: palette.bg }}>
      <StatusBar style={scheme === 'dark' ? 'light' : 'dark'} />

      <SafeAreaView style={styles.safe} edges={['top']}>
        {current ? (
          <>
            <Header title={current.companyName ?? dict.brand} onBack={back} />
            <StoryScreen
              // Remount per story so scroll position and state reset.
              key={`${current.slug}:${stack.length}`}
              slug={current.slug}
              onOpen={open}
            />
          </>
        ) : (
          <>
            {tab === 'today' && <TodayScreen onOpen={open} />}
            {tab === 'sections' && <SectionsScreen onOpen={open} />}
            {tab === 'saved' && <SavedScreen onOpen={open} />}
            {tab === 'settings' && <SettingsScreen />}
          </>
        )}
      </SafeAreaView>

      {/* The tab bar stays hidden inside a story: the reader is reading,
          and the way out is Back. */}
      {!current && (
        <TabBar
          active={tab}
          onChange={setTab}
          labels={{
            today: dict.today,
            sections: dict.sections,
            saved: dict.saved,
            settings: dict.settings,
          }}
        />
      )}
    </View>
  );
}

function Header({ title, onBack }: { title: string; onBack: () => void }) {
  const { palette, locale, rtl } = useTheme();

  return (
    <View
      style={[
        styles.header,
        {
          flexDirection: rtl ? 'row-reverse' : 'row',
          borderBottomColor: palette.border,
        },
      ]}
    >
      <Pressable
        onPress={onBack}
        accessibilityRole="button"
        accessibilityLabel={locale === 'ar' ? 'رجوع' : 'Back'}
        hitSlop={12}
        style={({ pressed }) => [{ opacity: pressed ? 0.6 : 1 }]}
      >
        <Text style={[textStyle('card', locale), { color: palette.accent }]}>
          {rtl ? '→' : '←'}
        </Text>
      </Pressable>
      <Text
        style={[textStyle('meta', locale), { color: palette.text3, flex: 1 }]}
        numberOfLines={1}
      >
        {title}
      </Text>
    </View>
  );
}

export default function App() {
  return (
    <SafeAreaProvider>
      <ThemeProvider>
        <AuthProvider>
          <SavedProvider>
            <Shell />
          </SavedProvider>
        </AuthProvider>
      </ThemeProvider>
    </SafeAreaProvider>
  );
}

const styles = StyleSheet.create({
  safe: {
    flex: 1,
  },
  header: {
    alignItems: 'center',
    gap: space.s4,
    paddingHorizontal: space.s4,
    paddingVertical: space.s3,
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
});
