import { getSession } from "@auth/solid-start";
import { faToggleOff, faToggleOn } from "@fortawesome/pro-regular-svg-icons";
import { useNavigate, useParams } from "@solidjs/router";
import { eq } from "drizzle-orm";
import moment from "moment-timezone";
import createClient from "openapi-fetch";
import { Index, createEffect, createResource, createSignal } from "solid-js";
import { createStore } from "solid-js/store";
import { getRequestEvent } from "solid-js/web";
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon";
import Layout from "~/components/Layout";
import db from "~/drizzle";
import { accounts } from "~/drizzle/schema";
import { authOptions } from "~/server/auth";
import { paths } from "~/types/discord";
import "../../styles/pages/config.scss";

const guessTZ = () => Intl.DateTimeFormat().resolvedOptions().timeZone;

const initialValue = (params: ReturnType<typeof useParams>) => ({
  success: null as boolean | null,
  guild: {
    id: params.guildId,
    name: undefined as string | undefined,
    icon: undefined as string | null | undefined,
  },
  tzNames: [guessTZ()],
});

const getPayload = async (
  id: string,
): 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 session = await getSession(event.request, authOptions);
  if (!session?.user?.id)
    return { success: false, message: "No user with id!" };

  const { DISCORD_ACCESS_TOKEN } = (
    await db
      .selectDistinct({ DISCORD_ACCESS_TOKEN: accounts.access_token })
      .from(accounts)
      .where(eq(accounts.userId, session.user?.id))
      .limit(1)
      .execute()
  )[0];
  if (!DISCORD_ACCESS_TOKEN)
    return { success: false, message: "No discord access token!" };

  // const guilds = await fetch("https://discord.com/api/users/@me/guilds", {
  //   headers: { Authorization: `Bearer ${DISCORD_ACCESS_TOKEN}` },
  // }).then((res) => res.json());
  const { GET } = createClient<paths>({
    baseUrl: "https://discord.com/api/v10",
  });
  const { data: guilds, error } = await GET("/users/@me/guilds", {
    headers: { Authorization: `Bearer ${DISCORD_ACCESS_TOKEN}` },
  });

  if (error) {
    console.log(error);
    return { success: false, message: "Error on discord api request!" };
  }

  const guild = guilds?.find((e) => e.id === id);

  if (!guild)
    return {
      success: false,
      message: "User is in no such guild with requested id!",
    };
  if (!(parseInt(guild.permissions) & (1 << 5)))
    return {
      success: false,
      message:
        "User is no MANAGE_GUILD permissions on this guild with requested id!",
    };

  return {
    success: true,
    guild: {
      id: guild.id,
      name: guild.name,
      icon: guild.icon,
    },
    // guild: guilds
    //   .filter((e: any) => e.permissions & (1 << 5))
    //   .map((e: any) => e.name),
    tzNames: moment.tz.names(),
  };
};

function config() {
  const params = useParams();
  const navigator = useNavigate();
  let timezoneRef: HTMLInputElement;
  let timePlanningRef: HTMLInputElement;
  let pingableRolesRef: HTMLInputElement;

  const [timezone, setTimezone] = createSignal(guessTZ());
  const [payload] = createResource(params.guildId, async (id) => {
    const payload = await getPayload(id);

    if (!payload.success) {
      console.log(payload.message, "No success");
      navigator("/config", { replace: false });
      return initialValue(params);
    }
    return payload;
  });
  const guild = () => payload()?.guild ?? initialValue(params).guild;
  const tzNames = () => payload()?.tzNames ?? [];
  const [config, setConfig] = createStore({
    features: {
      timePlanning: {
        enabled: false,
        pingableRoles: false,
      },
    },
  });

  createEffect(() => console.log(payload()));
  createEffect(() => console.log("timezone", timezone()));
  createEffect(() =>
    console.log("timePlanning.enabled", config.features.timePlanning.enabled),
  );
  createEffect(() =>
    console.log(
      "timePlanning.pingableRoles",
      config.features.timePlanning.pingableRoles,
    ),
  );

  createEffect(() => (timezoneRef.value = timezone()));
  createEffect(
    () => (timePlanningRef.checked = config.features.timePlanning.enabled),
  );
  createEffect(
    () =>
      (pingableRolesRef.checked = config.features.timePlanning.pingableRoles),
  );

  return (
    <Layout site="config">
      <h3 class="text-center">Configure li&apos;l Judd in</h3>
      <div>
        <div>
          <div class="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 ?? "li'l Judds home base"}</h1>
          </div>
        </div>

        <section>
          <h2>Guild</h2>
          <p>General settings for this guild.</p>
          <div class="flex-row">
            <label for="timezone">Timezone for your server:</label>
            <input
              type="text"
              list="timezones"
              id="timezone"
              ref={timezoneRef!}
              // disabled={!tzNames().find((e) => e === timezone())}
              onInput={(e) => setTimezone(e.target.value)}
            />

            <datalist id="timezones">
              <Index each={tzNames()}>
                {(zone) => <option value={zone()} />}
              </Index>
            </datalist>

            <button
              disabled={guessTZ() === timezone()}
              title={"Detected: " + guessTZ()}
              onClick={() => setTimezone(guessTZ())}
            >
              Auto-detect
            </button>
          </div>
        </section>

        <section>
          <h2>Features</h2>
          <p>Configure the features of the bot</p>
          <label for="timePlanning" class="flex-row">
            <p>Time Planning </p>
            <FontAwesomeIcon
              icon={
                config.features.timePlanning.enabled ? faToggleOn : faToggleOff
              }
              size="xl"
            />
          </label>
          <input
            hidden
            type="checkbox"
            id="timePlanning"
            ref={timePlanningRef!}
            onInput={(e) =>
              setConfig("features", "timePlanning", "enabled", e.target.checked)
            }
          />
          <div
            class="sub"
            classList={{ disabled: !config.features.timePlanning.enabled }}
          >
            <div class="flex-row">
              <label>Target channel:</label>
              <select value={timezone()}>
                <optgroup label="--Select a Channel--">
                  <Index each={tzNames()}>
                    {(channel) => <option>{channel()}</option>}
                  </Index>
                </optgroup>
              </select>
            </div>
            <div class="flex-row">
              <label for="pingableRoles" class="flex-row">
                <p>Enable pingable Roles:</p>
                <FontAwesomeIcon
                  icon={
                    config.features.timePlanning.pingableRoles
                      ? faToggleOn
                      : faToggleOff
                  }
                  size="xl"
                />
              </label>
              <input
                hidden
                type="checkbox"
                id="pingableRoles"
                ref={pingableRolesRef!}
                onInput={(e) =>
                  setConfig(
                    "features",
                    "timePlanning",
                    "pingableRoles",
                    e.target.checked,
                  )
                }
              />
            </div>
          </div>
        </section>

        <section>
          <button>Apply</button>
        </section>
      </div>
    </Layout>
  );
}

export default config;
