import type { PostWithRelations } from "~/utils/prisma.server";
import type {
  ActionFunction,
  ActionFunctionArgs,
  LoaderFunction,
  LoaderFunctionArgs,
} from "@remix-run/node";
import { json, redirect } from "@remix-run/node";
import {
  Form,
  useActionData,
  useLoaderData,
  useRouteLoaderData,
} from "@remix-run/react";
import { Button } from "~/components/Button";
import { Card } from "~/components/Card";
import { FormLabel, TextArea } from "~/components/Form";
import { Post } from "~/components/Post";
import { SubTitle, Text, Title } from "~/components/Typography";
import { likePost, unLikePost } from "~/models/like.server";
import { createPost, getAllPosts, getFeed } from "~/models/post.server";
import { commitSession, getSession } from "~/utils/session.server";
import type { RootLoaderTypes } from "~/root";

export async function action({ request }: ActionFunctionArgs) {
  const session = await getSession(request.headers.get("Cookie"));
  if (!session.has("userId")) {
    return redirect("/");
  }

  const userId = session.get("userId");

  const formData = await request
    .formData()
    .then((data) => Object.fromEntries(data));

  switch (formData.intent) {
    case "newpost":
      const postErrors = await createPost(String(formData.post), userId);

      if (Object.values(postErrors).some(Boolean)) {
        return postErrors;
      }

      session.flash("globalMessage", "Post created!");

      break;
    case "like":
      const likeErrors = await likePost(Number(formData.postId), userId);

      if (Object.values(likeErrors).some(Boolean)) {
        return likeErrors;
      }

      session.flash("globalMessage", "Post liked!");

      break;
    case "unlike":
      const unLikeErrors = await unLikePost(Number(formData.postId), userId);

      if (Object.values(unLikeErrors).some(Boolean)) {
        return unLikeErrors;
      }

      session.flash("globalMessage", "Post unliked!");

      break;
    default:
      return;
  }

  return json(
    {},
    {
      headers: {
        "Set-Cookie": await commitSession(session),
      },
    }
  );
}

export async function loader({ request }: LoaderFunctionArgs) {
  const session = await getSession(request.headers.get("Cookie"));
  if (!session.has("userId")) {
    return redirect("/");
  }

  return await getFeed(session.get("userId"));
}

export default function Index() {
  const rootData = useRouteLoaderData<RootLoaderTypes>("root");
  const data: PostWithRelations[] = useLoaderData<LoaderFunction>();
  const errors = useActionData<ActionFunction>();

  console.log(data);

  return (
    <div className="flex flex-col gap-5">
      <Title>Home</Title>
      <Card>
        {rootData?.id ? (
          <>
            <Title>New post</Title>
            <Form className="flex flex-col gap-3" method="POST">
              <input type="hidden" name="intent" value={"newpost"} />
              <FormLabel>
                <Text>Post body</Text>
                <TextArea name="post" />
                <Text type="error">{errors?.body ? errors.body : ""}</Text>
              </FormLabel>
              <Button type="submit">Post</Button>
            </Form>
          </>
        ) : (
          <>
            <Title>Twitter clone</Title>
            <SubTitle>Made with Remix</SubTitle>
          </>
        )}
      </Card>
      <SubTitle>Feed</SubTitle>
      {data.length > 0 ? (
        <Card className="!p-0 !gap-0 divide-y">
          {data.map((post: PostWithRelations) => (
            <Post userId={rootData?.id} key={post.id} post={post} />
          ))}
        </Card>
      ) : (
        <Text type="error">
          Feed is empty, follow someone so their recent posts will show up here!
        </Text>
      )}
    </div>
  );
}
