import { faPlusCircle, faWrench } from "@fortawesome/pro-regular-svg-icons";
import { useLocation, useNavigate } from "@solidjs/router";
import { For, Show, createResource } from "solid-js";
import { getRequestEvent } from "solid-js/web";
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon";
import Layout from "~/components/Layout";
import db from "~/drizzle";
import { guilds } from "~/drizzle/schema";
import { userGuilds } from "~/lib/cachedDiscord";
import "../../styles/pages/config.scss";

if (typeof import.meta.env.VITE_DISCORD_CLIENT_ID === "undefined")
  throw new Error("No env VITE_DISCORD_CLIENT_ID found!");

if (typeof import.meta.env.VITE_DISCORD_OAUTH2_PERMISSIONS === "undefined")
  throw new Error("No env VITE_DISCORD_OAUTH2_PERMISSIONS found!");

interface Guild {
  id: string;
  name: string;
  icon: string | null | undefined;
}

const initialValue = () => ({
  success: null as boolean | null,
  joined: [] as Guild[],
  canJoin: [] as Guild[],
});

const getPayload = async (): Promise<
  | { success: false; message: string }
  | (ReturnType<typeof initialValue> & { success: true })
> => {
  "use server";

  const event = getRequestEvent();
  if (!event) return { success: false, message: "No request event!" };

  const { user } = event.nativeEvent.context;
  if (!user) return { success: false, message: "User not logged in!" };

  const configs = await db.select().from(guilds).execute();

  const guildData = await userGuilds(user.id);

  const joined: Guild[] = [];
  const canJoin: Guild[] = [];

  guildData
    ?.filter((e) => parseInt(e.permissions) & (1 << 5))
    .forEach(({ id, name, icon }) => {
      configs.map((e) => e.id.toString()).includes(id)
        ? joined.push({ id, name, icon })
        : canJoin.push({ id, name, icon });
    });

  return {
    success: true,
    joined,
    canJoin,
  };
};

function index() {
  const navigator = useNavigate();
  const location = useLocation();

  const [payload] = createResource(
    // eslint-disable-next-line solid/reactivity
    async () => {
      const payload = await getPayload().catch((e) => console.warn(e));

      if (!payload) {
        console.error(location.pathname, payload);
        return initialValue();
      }

      if (!payload.success) {
        console.log(location.pathname, payload.message, "No success");
        navigator("/", { replace: false });
        return initialValue();
      }

      return payload;
    },
    { deferStream: true, initialValue: initialValue() },
  );

  return (
    <Layout site="config">
      <div class="group">
        <h3>Configure li&apos;l Judd in</h3>
        <GuildList list={payload().joined} joined={true} />
      </div>
      <div class="group">
        <h3>Add li&apos;l Judd to</h3>
        <GuildList list={payload().canJoin} joined={false} />
      </div>
    </Layout>
  );
}

function GuildList(props: { list: Guild[]; joined: boolean }) {
  return (
    <div>
      <Show
        when={props.list.length}
        fallback={<div class="box flex-row centered">Nothing here</div>}
      >
        <For each={props.list}>
          {(guild) => {
            return (
              <a
                href={
                  props.joined
                    ? `/config/${guild.id}`
                    : `https://discord.com/api/oauth2/authorize?client_id=${import.meta.env.VITE_DISCORD_CLIENT_ID}&permissions=${import.meta.env.VITE_DISCORD_OAUTH2_PERMISSIONS}&scope=bot&guild_id=${guild.id}`
                }
                class="box effect flex-row centered"
              >
                <img
                  class="guildpfp"
                  src={
                    guild.icon
                      ? `https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.webp?size=240`
                      : "https://cdn.discordapp.com/icons/1040502664506646548/bb5a51c4659cf47bdd942bb11e974da7.webp?size=240"
                  }
                  alt="Server pfp"
                />
                <h1>{guild.name}</h1>
                <FontAwesomeIcon
                  icon={props.joined ? faWrench : faPlusCircle}
                  size="xl"
                />
              </a>
            );
          }}
        </For>
      </Show>
    </div>
  );
}

export default index;
