import axios from "axios";

enum ColorScheme {
    System = "system",
    Dark = "dark",
    Light = "light",
}

type UserInfo = {
    name: string;
    patreon: boolean;
    preferences: {
        timezone: string | null;
        reset_inputs_on_create: boolean;
        dashboard_color_scheme: ColorScheme;
        use_browser_timezone: boolean;
    };
};

export type UpdateUserInfo = {
    timezone?: string;
    reset_inputs_on_create?: boolean;
    dashboard_color_scheme?: ColorScheme;
    use_browser_timezone?: boolean;
};

export type GuildInfo = {
    id: string;
    patreon: boolean;
    name: string;
    error?: string;
};

type EmbedField = {
    title: string;
    value: string;
    inline: boolean;
};

export type Reminder = {
    attachment: string | null;
    attachment_name: string | null;
    avatar: string | null;
    channel: string;
    content: string;
    embed_author: string;
    embed_author_url: string | null;
    embed_color: number;
    embed_description: string;
    embed_footer: string;
    embed_footer_url: string | null;
    embed_image_url: string | null;
    embed_thumbnail_url: string | null;
    embed_title: string;
    embed_fields: EmbedField[] | null;
    enabled: boolean;
    expires: string | null;
    interval_seconds: number | null;
    interval_days: number | null;
    interval_months: number | null;
    name: string;
    restartable: boolean;
    tts: boolean;
    uid: string;
    username: string;
    utc_time: string;
};

export type Todo = {
    id: number;
    channel_id: string;
    value: string;
};

export type CreateTodo = {
    channel_id: string;
    value: string;
};

export type UpdateTodo = {
    value: string;
};

export type ChannelInfo = {
    id: string;
    name: string;
};

type RoleInfo = {
    id: string;
    name: string;
};

type EmojiInfo = {
    fmt: string;
    name: string;
};

type Template = {
    id: number;
    name: string;
    attachment: string | null;
    attachment_name: string | null;
    avatar: string | null;
    channel: string;
    content: string;
    embed_author: string;
    embed_author_url: string | null;
    embed_color: number;
    embed_description: string;
    embed_footer: string;
    embed_footer_url: string | null;
    embed_image_url: string | null;
    embed_thumbnail_url: string | null;
    embed_title: string;
    embed_fields: EmbedField[] | null;
};

const USER_INFO_STALE_TIME = 86_400_000;
const GUILD_INFO_STALE_TIME = 300_000;
const OTHER_STALE_TIME = 120_000;

export const fetchUserInfo = () => ({
    queryKey: ["USER_INFO"],
    queryFn: () => axios.get("/dashboard/api/user").then((resp) => resp.data) as Promise<UserInfo>,
    staleTime: USER_INFO_STALE_TIME,
});

export const patchUserInfo = () => ({
    mutationFn: (userInfo: UpdateUserInfo) => axios.patch(`/dashboard/api/user`, userInfo),
});

export const fetchUserGuilds = () => ({
    queryKey: ["USER_GUILDS"],
    queryFn: () =>
        axios.get("/dashboard/api/user/guilds").then((resp) => resp.data) as Promise<GuildInfo[]>,
    staleTime: USER_INFO_STALE_TIME,
});

export const fetchGuildInfo = (guild: string) => ({
    queryKey: ["GUILD_INFO", guild],
    queryFn: () =>
        axios.get(`/dashboard/api/guild/${guild}`).then((resp) => resp.data) as Promise<GuildInfo>,
    staleTime: GUILD_INFO_STALE_TIME,
});

export const fetchGuildChannels = (guild: string) => ({
    queryKey: ["GUILD_CHANNELS", guild],
    queryFn: () =>
        axios
            .get(`/dashboard/api/guild/${guild}/channels`)
            .then((resp) =>
                resp.data.sort((a: ChannelInfo, b: ChannelInfo) =>
                    a.name == b.name ? 0 : a.name > b.name ? 1 : -1,
                ),
            ) as Promise<ChannelInfo[]>,
    staleTime: GUILD_INFO_STALE_TIME,
});

export const fetchGuildRoles = (guild: string) => ({
    queryKey: ["GUILD_ROLES", guild],
    queryFn: () =>
        axios.get(`/dashboard/api/guild/${guild}/roles`).then((resp) => resp.data) as Promise<
            RoleInfo[]
        >,
    staleTime: GUILD_INFO_STALE_TIME,
});

export const fetchGuildEmojis = (guild: string) => ({
    queryKey: ["GUILD_EMOJIS", guild],
    queryFn: () =>
        axios.get(`/dashboard/api/guild/${guild}/emojis`).then((resp) => resp.data) as Promise<
            EmojiInfo[]
        >,
    staleTime: GUILD_INFO_STALE_TIME,
});

export const fetchGuildReminders = (guild: string) => ({
    queryKey: ["GUILD_REMINDERS", guild],
    queryFn: () =>
        axios.get(`/dashboard/api/guild/${guild}/reminders`).then((resp) => resp.data) as Promise<
            Reminder[]
        >,
    staleTime: OTHER_STALE_TIME,
});

export const patchGuildReminder = (guild: string) => ({
    mutationFn: (reminder: Reminder) =>
        axios.patch(`/dashboard/api/guild/${guild}/reminders`, reminder),
});

export const postGuildReminder = (guild: string) => ({
    mutationFn: (reminder: Reminder) =>
        axios.post(`/dashboard/api/guild/${guild}/reminders`, reminder).then((resp) => resp.data),
});

export const deleteReminder = () => ({
    mutationFn: (reminder: Reminder) =>
        axios.delete(`/dashboard/api/reminders`, {
            data: {
                uid: reminder.uid,
            },
        }),
});

export const fetchGuildTemplates = (guild: string) => ({
    queryKey: ["GUILD_TEMPLATES", guild],
    queryFn: () =>
        axios.get(`/dashboard/api/guild/${guild}/templates`).then((resp) => resp.data) as Promise<
            Template[]
        >,
    staleTime: OTHER_STALE_TIME,
});

export const postGuildTemplate = (guild: string) => ({
    mutationFn: (reminder: Reminder) =>
        axios.post(`/dashboard/api/guild/${guild}/templates`, reminder).then((resp) => resp.data),
});

export const deleteGuildTemplate = (guild: string) => ({
    mutationFn: (template: Template) =>
        axios.delete(`/dashboard/api/guild/${guild}/templates`, {
            data: {
                id: template.id,
            },
        }),
});

export const fetchGuildTodos = (guild: string) => ({
    queryKey: ["GUILD_TODOS", guild],
    queryFn: () =>
        axios.get(`/dashboard/api/guild/${guild}/todos`).then((resp) => resp.data) as Promise<
            Todo[]
        >,
    staleTime: OTHER_STALE_TIME,
});

export const patchGuildTodo = (guild: string) => ({
    mutationFn: ({id, todo}) => axios.patch(`/dashboard/api/guild/${guild}/todos/${id}`, todo),
});

export const postGuildTodo = (guild: string) => ({
    mutationFn: (todo: CreateTodo) =>
        axios.post(`/dashboard/api/guild/${guild}/todos`, todo).then((resp) => resp.data),
});

export const deleteGuildTodo = (guild: string) => ({
    mutationFn: (todoId: number) => axios.delete(`/dashboard/api/guild/${guild}/todos/${todoId}`),
});

export const fetchUserReminders = () => ({
    queryKey: ["USER_REMINDERS"],
    queryFn: () =>
        axios.get(`/dashboard/api/user/reminders`).then((resp) => resp.data) as Promise<Reminder[]>,
    staleTime: OTHER_STALE_TIME,
});

export const postUserReminder = () => ({
    mutationFn: (reminder: Reminder) =>
        axios.post(`/dashboard/api/user/reminders`, reminder).then((resp) => resp.data),
});

export const patchUserReminder = () => ({
    mutationFn: (reminder: Reminder) => axios.patch(`/dashboard/api/user/reminders`, reminder),
});
