import { useMemo, useState } from 'react';
import { Alert, Pressable, Text, TextInput, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import * as Linking from 'expo-linking';
import { Stack } from 'expo-router';
import * as WebBrowser from 'expo-web-browser';
import { useAuthActions } from '@convex-dev/auth/react';
import { useConvexAuth, useQuery } from 'convex/react';

import { api } from '@spoon/backend/convex/_generated/api.js';

WebBrowser.maybeCompleteAuthSession();

const Stat = ({ label, value }: { label: string; value: number }) => (
  <View className='border-border bg-card flex-1 rounded-lg border p-4'>
    <Text className='text-muted-foreground text-xs'>{label}</Text>
    <Text className='text-foreground mt-2 text-2xl font-bold'>{value}</Text>
  </View>
);

const Index = () => {
  const { isAuthenticated, isLoading } = useConvexAuth();
  const { signIn, signOut } = useAuthActions();
  const user = useQuery(api.auth.getUser, isAuthenticated ? {} : 'skip');
  const spoons =
    useQuery(api.spoons.listMine, isAuthenticated ? {} : 'skip') ?? [];
  const syncRuns =
    useQuery(
      api.syncRuns.listRecent,
      isAuthenticated ? { limit: 5 } : 'skip',
    ) ?? [];
  const agentRequests =
    useQuery(
      api.agentRequests.listRecent,
      isAuthenticated ? { limit: 5 } : 'skip',
    ) ?? [];
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const redirectTo = useMemo(() => Linking.createURL(''), []);

  const handlePasswordSignIn = async () => {
    setSubmitting(true);
    try {
      await signIn('password', { email, password, flow: 'signIn' });
    } catch (error) {
      console.error(error);
      Alert.alert('Sign in failed', 'Check your email and password.');
    } finally {
      setSubmitting(false);
    }
  };

  const handleAuthentikSignIn = async () => {
    setSubmitting(true);
    try {
      const result = await signIn('authentik', { redirectTo });
      if (!result.redirect) return;
      const authResult = await WebBrowser.openAuthSessionAsync(
        result.redirect.toString(),
        redirectTo,
      );
      if (authResult.type !== 'success') return;
      const parsed = Linking.parse(authResult.url);
      const code = parsed.queryParams?.code;
      if (typeof code !== 'string') {
        Alert.alert('Sign in failed', 'Authentik did not return a code.');
        return;
      }
      await signIn('authentik', { code });
    } catch (error) {
      console.error(error);
      Alert.alert('Sign in failed', 'Could not complete Authentik sign in.');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <SafeAreaView className='bg-background flex-1'>
      <Stack.Screen options={{ title: 'Spoon' }} />
      <View className='flex-1 gap-5 p-6'>
        <View>
          <Text className='text-foreground text-4xl font-bold'>Spoon</Text>
          <Text className='text-muted-foreground mt-2 text-base leading-6'>
            Fork freely. Stay close to upstream.
          </Text>
        </View>

        {isLoading ? (
          <Text className='text-muted-foreground'>Loading...</Text>
        ) : isAuthenticated ? (
          <View className='gap-5'>
            <View>
              <Text className='text-foreground text-xl font-semibold'>
                Welcome{user?.name ? `, ${user.name}` : ''}
              </Text>
              <Text className='text-muted-foreground mt-1'>
                Monitor your managed forks from anywhere.
              </Text>
            </View>
            <View className='flex-row gap-3'>
              <Stat label='Spoons' value={spoons.length} />
              <Stat label='Updates' value={syncRuns.length} />
              <Stat label='Agents' value={agentRequests.length} />
            </View>
            <View className='border-border bg-card rounded-lg border p-4'>
              <Text className='text-foreground font-semibold'>
                Recent Spoons
              </Text>
              {spoons.length ? (
                spoons.slice(0, 4).map((spoon) => (
                  <Text key={spoon._id} className='text-muted-foreground mt-3'>
                    {spoon.name} - {spoon.status.replaceAll('_', ' ')}
                  </Text>
                ))
              ) : (
                <Text className='text-muted-foreground mt-3'>
                  Create your first Spoon from the web dashboard.
                </Text>
              )}
            </View>
            <Pressable
              className='bg-primary items-center rounded-md p-3'
              onPress={() => void signOut()}
            >
              <Text className='text-primary-foreground font-semibold'>
                Sign out
              </Text>
            </Pressable>
          </View>
        ) : (
          <View className='gap-4'>
            <TextInput
              className='border-input text-foreground rounded-md border px-3 py-3'
              autoCapitalize='none'
              keyboardType='email-address'
              placeholder='Email'
              placeholderTextColor='#64748b'
              value={email}
              onChangeText={setEmail}
            />
            <TextInput
              className='border-input text-foreground rounded-md border px-3 py-3'
              secureTextEntry
              placeholder='Password'
              placeholderTextColor='#64748b'
              value={password}
              onChangeText={setPassword}
            />
            <Pressable
              className='bg-primary items-center rounded-md p-3 disabled:opacity-60'
              disabled={submitting}
              onPress={() => void handlePasswordSignIn()}
            >
              <Text className='text-primary-foreground font-semibold'>
                Sign in with password
              </Text>
            </Pressable>
            <Pressable
              className='border-border items-center rounded-md border p-3 disabled:opacity-60'
              disabled={submitting}
              onPress={() => void handleAuthentikSignIn()}
            >
              <Text className='text-foreground font-semibold'>
                Continue with Authentik
              </Text>
            </Pressable>
            <Text className='text-muted-foreground text-sm'>
              Register the native redirect URI based on spoon:// in Authentik.
            </Text>
          </View>
        )}
      </View>
    </SafeAreaView>
  );
};

export default Index;
