import { Image } from "expo-image";
import { Alert, Button, StyleSheet, TextInput } from "react-native";
import { Agent } from "@atproto/api";
import { TID } from "@atproto/common-web";

import { HelloWave } from "@/components/HelloWave";
import ParallaxScrollView from "@/components/ParallaxScrollView";
import { ThemedText } from "@/components/ThemedText";
import { ThemedView } from "@/components/ThemedView";
import { useState } from "react";
import { ExpoOAuthClient } from "expo-atproto-auth";
import { OAuthSession } from "@atproto/oauth-client";
import { WebBrowserResultType } from "expo-web-browser";

const client = new ExpoOAuthClient({
  clientMetadata: {
    client_id: "https://hailey.at/oauth-client-metadata.json",
    client_name: "Hailey's Atproto App",
    client_uri: "https://hailey.at",
    redirect_uris: ["at.hailey:/auth/callback"],
    scope: "atproto transition:generic",
    token_endpoint_auth_method: "none",
    response_types: ["code"],
    grant_types: ["authorization_code", "refresh_token"],
    application_type: "native",
    dpop_bound_access_tokens: true,
  },
  handleResolver: "https://bsky.social",
});

export default function HomeScreen() {
  const [handle, setHandle] = useState<string>("");
  const [agent, setAgent] = useState<Agent | null>(null);
  const [isProcessing, setIsProcessing] = useState(false);
  const [postTitle, setPostTitle] = useState<string>("");
  const [postText, setPostText] = useState<string>("");
  const [name, setName] = useState<string>();

  const onSignInPress = async () => {
    let res:
      | {
          status: WebBrowserResultType;
        }
      | {
          status: "error";
          error: unknown;
        }
      | {
          status: "success";
          session: OAuthSession;
        };

    setIsProcessing(true);
    try {
      res = await client.signIn(handle);
    } catch (e) {
      console.log(e);
      return;
    } finally {
      setIsProcessing(false);
    }

    if (res.status === "error") {
      Alert.alert("Authentication Error", (res.error as any).toString());
    } else if (res.status === "success") {
      const newAgent = new Agent(res.session);
      setAgent(newAgent);

      const pres = await newAgent.getProfile({ actor: newAgent.did! });
      setName(pres.data.displayName);
    }
  };

  const onCreatePost = async () => {
    const entry: WhtwndBlogEntryRecord = {
      $type: "com.whtwnd.blog.entry",
      createdAt: new Date().toISOString(),
      title: postTitle,
      content: postText,
    };

    setIsProcessing(true);
    try {
      await agent!.com.atproto.repo.createRecord({
        repo: agent!.did!,
        collection: "com.whtwnd.blog.entry",
        record: entry,
        rkey: TID.nextStr(),
      });
    } catch (e) {
      console.log(e);
    } finally {
      setIsProcessing(false);
    }

    Alert.alert("Post Created!", "Your post has been published!!!");
  };

  return (
    <ParallaxScrollView
      headerBackgroundColor={{ light: "#A1CEDC", dark: "#1D3D47" }}
      headerImage={
        <Image
          source={require("@/assets/images/partial-react-logo.png")}
          style={styles.reactLogo}
        />
      }
    >
      <ThemedView style={styles.titleContainer}>
        <ThemedText type="title">Welcome!</ThemedText>
        <HelloWave />
      </ThemedView>
      <ThemedView style={styles.stepContainer}>
        {agent === null ? (
          <>
            <ThemedText>Sign into your account to get started!</ThemedText>
            <TextInput
              onChangeText={setHandle}
              value={handle}
              placeholder="Handle or DID"
              style={styles.textInput}
              autoCapitalize="none"
              autoCorrect={false}
              autoComplete="username"
            />
            <Button
              title="Sign In"
              onPress={onSignInPress}
              disabled={isProcessing}
            />
          </>
        ) : (
          <>
            <ThemedText>
              Welcome, {name}. Go ahead and share your thoughts.
            </ThemedText>
            <TextInput
              style={styles.textInput}
              onChangeText={setPostTitle}
              value={postTitle}
              placeholder="Post Title"
            />
            <TextInput
              onChangeText={setPostText}
              value={postText}
              placeholder="Post Content"
              multiline
              numberOfLines={10}
              style={styles.multilineTextInput}
            />
            <Button
              title="Create Post"
              onPress={onCreatePost}
              disabled={isProcessing}
            />
          </>
        )}
      </ThemedView>
    </ParallaxScrollView>
  );
}

const styles = StyleSheet.create({
  titleContainer: {
    flexDirection: "row",
    alignItems: "center",
    gap: 8,
  },
  stepContainer: {
    gap: 8,
    marginBottom: 8,
  },
  reactLogo: {
    height: 178,
    width: 290,
    bottom: 0,
    left: 0,
    position: "absolute",
  },
  textInput: {
    height: 50,
    borderWidth: 1,
    borderColor: "grey",
  },
  multilineTextInput: {
    borderWidth: 1,
    borderColor: "grey",
  },
});

interface WhtwndBlogEntryRecord {
  $type: "com.whtwnd.blog.entry";
  content?: string;
  createdAt: string;
  theme?: string;
  title: string;
  ogp?: {
    height: number | null;
    url: string | null;
    width: number | null;
  };
}
