import { Link, router } from "expo-router";
import * as Linking from "expo-linking";
import { useEffect, useState } from "react";
import {
  KeyboardAvoidingView,
  Platform,
  Pressable,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from "react-native";
import { AuthBackground } from "@/components/AppBackground";
import { AuthServerPicker } from "@/components/AuthServerPicker";
import { HeadingText, Logo } from "@/components/Logo";
import { FullScreen } from "@/components/Screen";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { Input } from "@/components/ui/Input";
import { fonts, spacing } from "@/constants/theme";
import { useAccounts } from "@/contexts/AccountsContext";
import { useAuthClient } from "@/contexts/AuthContext";
import { useAppTheme } from "@/contexts/ThemeContext";
import { fetchAuthCapabilities } from "@/lib/auth-capabilities";
import { signInWithAuthentik } from "@/lib/auth-oauth";
import { completeSignInAfterAuth } from "@/lib/complete-sign-in";
import { isRequiredString, isValidEmail, useFieldVisibility } from "@/lib/form-validation";

export default function SignInScreen() {
  const authClient = useAuthClient();
  const { apiUrl, activeAccountId, registerAccount } = useAccounts();
  const { colors } = useAppTheme();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [serverReady, setServerReady] = useState(true);
  const [authentikEnabled, setAuthentikEnabled] = useState(false);
  const [signupsDisabled, setSignupsDisabled] = useState(false);
  const { touch, visible, markSubmitted } = useFieldVisibility();

  useEffect(() => {
    let cancelled = false;

    void fetchAuthCapabilities(apiUrl).then((capabilities) => {
      if (cancelled) return;
      setAuthentikEnabled(capabilities.authentik);
      setSignupsDisabled(capabilities.signupsDisabled);
    });

    return () => {
      cancelled = true;
    };
  }, [apiUrl]);

  const emailValidationError = !email.trim()
    ? "Email is required"
    : isValidEmail(email)
      ? undefined
      : "Enter a valid email";
  const passwordValidationError = password.trim() ? undefined : "Password is required";
  const canSignIn = isValidEmail(email) && isRequiredString(password) && serverReady;

  async function finishSignIn() {
    const completed = await completeSignInAfterAuth(authClient, {
      apiUrl,
      activeAccountId,
      registerAccount,
    });

    if (!completed) {
      setError("Signed in but session was not available. Try again.");
    }
  }

  async function handleSignIn() {
    markSubmitted();
    if (!canSignIn) return;
    setError(null);
    setLoading(true);

    try {
      const { error: signInError } = await authClient.signIn.email({
        email: email.trim(),
        password,
      });

      if (signInError) {
        const message = signInError.message ?? "";
        if (message.toLowerCase().includes("internal") || message.includes("500")) {
          setError("Server error — is the API running with Postgres? Check beenvoice dev + docker.");
        } else {
          setError(message || "Invalid email or password");
        }
        return;
      }

      await finishSignIn();
    } finally {
      setLoading(false);
    }
  }

  async function handleAuthentikSignIn() {
    if (!serverReady) return;
    setError(null);
    setLoading(true);

    try {
      const { error: oauthError } = await signInWithAuthentik(
        authClient,
        Linking.createURL("/"),
      );

      if (oauthError) {
        setError(oauthError.message ?? "Could not sign in with Authentik");
        return;
      }

      await finishSignIn();
    } finally {
      setLoading(false);
    }
  }

  return (
    <AuthBackground>
      <FullScreen style={styles.safe}>
        <KeyboardAvoidingView
          behavior={Platform.OS === "ios" ? "padding" : undefined}
          style={styles.flex}
        >
          <ScrollView
            contentContainerStyle={styles.container}
            keyboardShouldPersistTaps="handled"
          >
            <View style={styles.content}>
              <Card style={styles.card}>
                <View style={styles.header}>
                  <Logo size="lg" />
                  <HeadingText style={styles.title}>Welcome back</HeadingText>
                  <Text style={[styles.subtitle, { color: colors.mutedForeground }]}>
                    Sign in to manage invoices on the go
                  </Text>
                </View>

                <AuthServerPicker onReadyChange={setServerReady} embedded />

                {signupsDisabled ? (
                  <Text style={[styles.notice, { color: colors.mutedForeground }]}>
                    New account registration is currently disabled on this server.
                  </Text>
                ) : null}

                {authentikEnabled ? (
                  <View style={styles.ssoSection}>
                    <Button
                      title="Sign in with Authentik"
                      variant="secondary"
                      loading={loading}
                      disabled={!serverReady}
                      onPress={() => void handleAuthentikSignIn()}
                    />
                    <View style={styles.dividerRow}>
                      <View style={[styles.dividerLine, { backgroundColor: colors.border }]} />
                      <Text style={[styles.dividerLabel, { color: colors.mutedForeground }]}>
                        or
                      </Text>
                      <View style={[styles.dividerLine, { backgroundColor: colors.border }]} />
                    </View>
                  </View>
                ) : null}

                <View style={styles.form}>
                  <Input
                    label="Email"
                    autoCapitalize="none"
                    autoComplete="email"
                    keyboardType="email-address"
                    value={email}
                    onChangeText={setEmail}
                    onBlur={() => touch("email")}
                    placeholder="you@example.com"
                    required
                    error={visible("email") ? emailValidationError : undefined}
                  />
                  <Input
                    label="Password"
                    secureTextEntry
                    autoComplete="password"
                    value={password}
                    onChangeText={setPassword}
                    onBlur={() => touch("password")}
                    placeholder="••••••••"
                    required
                    error={visible("password") ? passwordValidationError : undefined}
                  />

                  <Pressable onPress={() => router.push("/(auth)/forgot-password")}>
                    <Text style={[styles.forgot, { color: colors.mutedForeground }]}>
                      Forgot password?
                    </Text>
                  </Pressable>

                  {error ? (
                    <Text style={[styles.error, { color: colors.destructive }]}>{error}</Text>
                  ) : null}

                  <Button
                    title="Sign In"
                    loading={loading}
                    disabled={!canSignIn}
                    onPress={handleSignIn}
                  />
                </View>

                {!signupsDisabled ? (
                  <Text style={[styles.footer, { color: colors.mutedForeground }]}>
                    Don&apos;t have an account?{" "}
                    <Link href="/(auth)/register" style={[styles.link, { color: colors.foreground }]}>
                      Create one
                    </Link>
                  </Text>
                ) : null}
              </Card>
            </View>
          </ScrollView>
        </KeyboardAvoidingView>
      </FullScreen>
    </AuthBackground>
  );
}

const styles = StyleSheet.create({
  safe: {
    flex: 1,
  },
  flex: {
    flex: 1,
  },
  container: {
    flexGrow: 1,
    justifyContent: "center",
    alignItems: "center",
    padding: spacing.lg,
    paddingVertical: spacing.xl,
  },
  content: {
    width: "100%",
    maxWidth: 420,
  },
  card: {
    gap: spacing.lg,
  },
  header: {
    alignItems: "center",
    gap: spacing.sm,
  },
  title: {
    fontSize: 24,
    marginTop: spacing.sm,
    textAlign: "center",
  },
  subtitle: {
    fontSize: 14,
    fontFamily: fonts.body,
    textAlign: "center",
  },
  notice: {
    fontSize: 13,
    fontFamily: fonts.body,
    textAlign: "center",
    lineHeight: 18,
  },
  ssoSection: {
    gap: spacing.md,
  },
  dividerRow: {
    flexDirection: "row",
    alignItems: "center",
    gap: spacing.sm,
  },
  dividerLine: {
    flex: 1,
    height: StyleSheet.hairlineWidth,
  },
  dividerLabel: {
    fontSize: 12,
    fontFamily: fonts.bodyMedium,
    textTransform: "uppercase",
    letterSpacing: 0.6,
  },
  form: {
    gap: spacing.md,
  },
  forgot: {
    alignSelf: "flex-end",
    fontFamily: fonts.bodyMedium,
    fontSize: 12,
  },
  error: {
    fontSize: 14,
    fontFamily: fonts.body,
  },
  footer: {
    textAlign: "center",
    fontSize: 14,
    fontFamily: fonts.body,
  },
  link: {
    fontFamily: fonts.bodySemiBold,
  },
});
