import { vi, afterEach, expect } from 'vitest'
import React from 'react'
import { cleanup } from '@testing-library/react-native'

// Mock __DEV__
vi.stubGlobal('__DEV__', true)

// Quieter test output
vi.stubGlobal('console', {
  ...console,
  log: vi.fn(),
  info: vi.fn(),
  warn: vi.fn(),
  error: vi.fn(),
})

afterEach(() => {
  cleanup()
  vi.clearAllMocks()
})

vi.mock('expo-blur', () => ({
  BlurView: ({ intensity, tint, children, style }: any) => {
    return React.createElement('BlurView', { intensity, tint, style, testID: 'blur-view' }, children)
  },
}))

vi.mock('expo-linear-gradient', () => ({
  LinearGradient: ({ colors, start, end, style, children }: any) => {
    return React.createElement(
      'LinearGradient',
      { colors, start, end, style, testID: 'linear-gradient' },
      children
    )
  },
}))

vi.mock('expo-video', () => ({
  useVideoPlayer: vi.fn(() => ({
    play: vi.fn(),
    pause: vi.fn(),
    replace: vi.fn(),
    currentTime: 0,
    duration: 100,
    playing: false,
    muted: false,
    volume: 1,
  })),
  VideoView: ({ player, style, contentFit, nativeControls }: any) => {
    return React.createElement('VideoView', { player, style, contentFit, nativeControls, testID: 'video-view' })
  },
}))

vi.mock('@expo/vector-icons', () => ({
  Ionicons: ({ name, size, color, style }: any) => {
    return React.createElement('Ionicons', { name, size, color, style, testID: `icon-${name}` })
  },
  FontAwesome: ({ name, size, color, style }: any) => {
    return React.createElement('FontAwesome', { name, size, color, style, testID: `icon-${name}` })
  },
  MaterialIcons: ({ name, size, color, style }: any) => {
    return React.createElement('MaterialIcons', { name, size, color, style, testID: `icon-${name}` })
  },
}))

vi.mock('react-native-safe-area-context', () => ({
  useSafeAreaInsets: () => ({ top: 47, bottom: 34, left: 0, right: 0 }),
  SafeAreaProvider: ({ children }: any) => children,
}))

vi.mock('expo-constants', () => ({
  default: {
    expoConfig: { version: '1.0.0' },
    systemFonts: [],
  },
}))

vi.mock('expo-haptics', () => ({
  impactAsync: vi.fn(),
  ImpactFeedbackStyle: { Light: 'light', Medium: 'medium', Heavy: 'heavy' },
  notificationAsync: vi.fn(),
  NotificationFeedbackType: { Success: 'success', Warning: 'warning', Error: 'error' },
}))

vi.mock('expo-linking', () => ({
  default: {
    openURL: vi.fn(),
    createURL: vi.fn(),
  },
}))

const mockThemeColors = {
  bg: {
    base: '#000000',
    surface: '#1C1C1E',
    elevated: '#2C2C2E',
  },
  text: {
    primary: '#FFFFFF',
    secondary: '#8E8E93',
    tertiary: '#636366',
  },
  glass: {
    base: {
      backgroundColor: 'rgba(255, 255, 255, 0.05)',
      borderColor: 'rgba(255, 255, 255, 0.1)',
      borderWidth: 1,
    },
    elevated: {
      backgroundColor: 'rgba(255, 255, 255, 0.08)',
      borderColor: 'rgba(255, 255, 255, 0.12)',
      borderWidth: 1,
    },
    inset: {
      backgroundColor: 'rgba(0, 0, 0, 0.2)',
      borderColor: 'rgba(255, 255, 255, 0.05)',
      borderWidth: 1,
    },
    tinted: {
      backgroundColor: 'rgba(255, 107, 53, 0.1)',
      borderColor: 'rgba(255, 107, 53, 0.2)',
      borderWidth: 1,
    },
    blurTint: 'dark',
    blurMedium: 40,
  },
  shadow: {
    sm: { shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.2, shadowRadius: 2 },
    md: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4 },
    lg: { shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 8 },
  },
}

vi.mock('@/src/shared/theme', () => ({
  useThemeColors: () => mockThemeColors,
  ThemeProvider: ({ children }: any) => children,
  BRAND: {
    PRIMARY: '#FF6B35',
    PRIMARY_DARK: '#E55A2B',
  },
  GRADIENTS: {
    VIDEO_OVERLAY: ['transparent', 'rgba(0,0,0,0.8)'],
  },
}))

vi.mock('@/src/shared/constants/borderRadius', () => ({
  RADIUS: {
    SM: 8,
    MD: 12,
    LG: 16,
    XL: 20,
    FULL: 9999,
    GLASS_CARD: 24,
    GLASS_BUTTON: 14,
  },
}))

vi.mock('@/src/shared/constants/spacing', () => ({
  SPACING: {
    1: 4,
    2: 8,
    3: 12,
    4: 16,
    5: 20,
    6: 24,
    8: 32,
  },
  LAYOUT: {
    SCREEN_PADDING: 24,
    BUTTON_HEIGHT: 52,
  },
}))

vi.mock('@/src/shared/constants/animations', () => ({
  DURATION: {
    FAST: 150,
    NORMAL: 250,
    SLOW: 400,
  },
  EASE: {
    EASE_OUT: { x: 0.25, y: 0.1, x2: 0.25, y2: 1 },
  },
}))

vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string) => key,
    i18n: { changeLanguage: vi.fn(), language: 'en' },
  }),
}))

// ---------------------------------------------------------------------------
// Mocks from setup.ts that are needed for render tests
// (react-native is NOT mocked here — it's provided by resolve.alias)
// ---------------------------------------------------------------------------

vi.mock('expo-av', () => ({
  Audio: {
    Sound: {
      createAsync: vi.fn().mockResolvedValue({
        sound: {
          playAsync: vi.fn(),
          pauseAsync: vi.fn(),
          stopAsync: vi.fn(),
          unloadAsync: vi.fn(),
          setPositionAsync: vi.fn(),
          setVolumeAsync: vi.fn(),
        },
        status: { isLoaded: true },
      }),
    },
    setAudioModeAsync: vi.fn(),
  },
  Video: 'Video',
}))

vi.mock('expo-image', () => ({
  Image: 'Image',
}))

vi.mock('expo-router', () => ({
  useRouter: vi.fn(() => ({
    push: vi.fn(),
    replace: vi.fn(),
    back: vi.fn(),
  })),
  useLocalSearchParams: vi.fn(() => ({})),
  Link: 'Link',
  Stack: {
    Screen: 'Screen',
  },
  Tabs: {
    Tab: 'Tab',
  },
}))

vi.mock('expo-localization', () => ({
  getLocales: vi.fn(() => [{ languageTag: 'en-US' }]),
}))

vi.mock('expo-keep-awake', () => ({
  activateKeepAwakeAsync: vi.fn(),
  deactivateKeepAwake: vi.fn(),
}))

vi.mock('expo-notifications', () => ({
  scheduleNotificationAsync: vi.fn(),
  cancelScheduledNotificationAsync: vi.fn(),
  getAllScheduledNotificationsAsync: vi.fn().mockResolvedValue([]),
  setNotificationHandler: vi.fn(),
}))

vi.mock('expo-splash-screen', () => ({
  preventAutoHideAsync: vi.fn(),
  hideAsync: vi.fn(),
}))

vi.mock('expo-font', () => ({
  loadAsync: vi.fn(),
}))

vi.mock('expo-file-system', () => ({
  documentDirectory: '/tmp/',
  cacheDirectory: '/tmp/cache/',
  readAsStringAsync: vi.fn(),
  writeAsStringAsync: vi.fn(),
  deleteAsync: vi.fn(),
  getInfoAsync: vi.fn().mockResolvedValue({ exists: false }),
}))

vi.mock('expo-device', () => ({
  isDevice: true,
  model: 'iPhone 15',
}))

vi.mock('expo-application', () => ({
  nativeApplicationVersion: '1.0.0',
  nativeBuildVersion: '1',
}))

vi.mock('@react-native-async-storage/async-storage', () => ({
  default: {
    getItem: vi.fn().mockResolvedValue(null),
    setItem: vi.fn().mockResolvedValue(undefined),
    removeItem: vi.fn().mockResolvedValue(undefined),
    clear: vi.fn().mockResolvedValue(undefined),
    getAllKeys: vi.fn().mockResolvedValue([]),
  },
}))

vi.mock('react-native-purchases', () => ({
  default: {
    configure: vi.fn().mockResolvedValue(undefined),
    getOfferings: vi.fn().mockResolvedValue({
      current: {
        monthly: {
          identifier: 'monthly',
          product: {
            identifier: 'tabatafit.premium.monthly',
            priceString: '$9.99',
          },
        },
        annual: {
          identifier: 'annual',
          product: {
            identifier: 'tabatafit.premium.yearly',
            priceString: '$79.99',
          },
        },
      },
    }),
    getCustomerInfo: vi.fn().mockResolvedValue({
      entitlements: { active: {}, all: {} },
      activeSubscriptions: [],
      allPurchasedProductIdentifiers: [],
    }),
    purchasePackage: vi.fn().mockResolvedValue({
      customerInfo: {
        entitlements: { active: {}, all: {} },
        activeSubscriptions: [],
      },
    }),
    restorePurchases: vi.fn().mockResolvedValue({
      entitlements: { active: {}, all: {} },
      activeSubscriptions: [],
    }),
    addCustomerInfoUpdateListener: vi.fn(),
    removeCustomerInfoUpdateListener: vi.fn(),
    setLogLevel: vi.fn(),
    LOG_LEVEL: {
      VERBOSE: 'verbose',
      DEBUG: 'debug',
      INFO: 'info',
      WARN: 'warn',
      ERROR: 'error',
    },
  },
  LOG_LEVEL: {
    VERBOSE: 'verbose',
    DEBUG: 'debug',
    INFO: 'info',
    WARN: 'warn',
    ERROR: 'error',
  },
}))

vi.mock('react-native-reanimated', () => ({
  default: {
    createAnimatedComponent: (comp: any) => comp,
    View: 'View',
    Text: 'Text',
    Image: 'Image',
    ScrollView: 'ScrollView',
  },
  useAnimatedStyle: vi.fn(() => ({})),
  useSharedValue: vi.fn(() => ({ value: 0 })),
  withSpring: vi.fn((v) => v),
  withTiming: vi.fn((v) => v),
  withRepeat: vi.fn((v) => v),
  withSequence: vi.fn((...v) => v[0]),
  withDelay: vi.fn((_, v) => v),
  Easing: {
    linear: vi.fn(),
    ease: vi.fn(),
    bezier: vi.fn(),
  },
  runOnJS: vi.fn((fn) => fn),
}))

vi.mock('react-native-gesture-handler', () => ({
  Gesture: {
    Pan: vi.fn(() => ({ onStart: vi.fn(), onUpdate: vi.fn(), onEnd: vi.fn() })),
    Tap: vi.fn(() => ({ onStart: vi.fn(), onEnd: vi.fn() })),
  },
  GestureDetector: 'GestureDetector',
  PanGestureHandler: 'PanGestureHandler',
  TapGestureHandler: 'TapGestureHandler',
  State: {},
}))

vi.mock('react-native-screens', () => ({
  enableScreens: vi.fn(),
}))

vi.mock('react-native-svg', () => ({
  Svg: 'Svg',
  Path: 'Path',
  Circle: 'Circle',
  Rect: 'Rect',
  G: 'G',
  Defs: 'Defs',
  Use: 'Use',
}))

vi.mock('@/src/shared/supabase', () => ({
  supabase: {
    auth: {
      signInAnonymously: vi.fn().mockResolvedValue({
        data: { user: { id: 'test-user-id' } },
        error: null,
      }),
      getUser: vi.fn().mockResolvedValue({
        data: { user: { id: 'test-user-id' } },
      }),
      getSession: vi.fn().mockResolvedValue({
        data: { session: { user: { id: 'test-user-id' } } },
      }),
      signOut: vi.fn().mockResolvedValue({ error: null }),
    },
    from: vi.fn(() => ({
      insert: vi.fn().mockResolvedValue({ error: null }),
      select: vi.fn().mockReturnThis(),
      eq: vi.fn().mockReturnThis(),
      order: vi.fn().mockReturnThis(),
      limit: vi.fn().mockResolvedValue({ data: [], error: null }),
      delete: vi.fn().mockReturnThis(),
      update: vi.fn().mockReturnThis(),
    })),
  },
}))

vi.mock('posthog-react-native', () => ({
  PostHogProvider: ({ children }: { children: React.ReactNode }) => children,
  usePostHog: vi.fn(() => ({
    capture: vi.fn(),
    identify: vi.fn(),
    screen: vi.fn(),
    reset: vi.fn(),
  })),
}))

vi.mock('@/src/shared/i18n', () => ({
  default: {
    t: vi.fn((key: string) => key),
    changeLanguage: vi.fn(),
    language: 'en',
  },
}))
