import { Resource } from "sst"
import { Select } from "./ui/select";
import { subjects } from "./subjects"
import { logger } from "hono/logger";
import { handle } from "hono/aws-lambda";
import { PasswordUI } from "./ui/password"
import { issuer } from "@openauthjs/openauth";
import { User } from "@nestri/core/user/index"
import { Email } from "@nestri/core/email/index";
import { handleDiscord, handleGithub } from "./utils";
import { GithubAdapter } from "./ui/adapters/github";
import { DiscordAdapter } from "./ui/adapters/discord";
import { PasswordAdapter } from "./ui/adapters/password"
import { type Provider } from "@openauthjs/openauth/provider/provider"

type OauthUser = {
    primary: {
        email: any;
        primary: any;
        verified: any;
    };
    avatar: any;
    username: any;
}
const app = issuer({
    select: Select({
        providers: {
            device: {
                hide: true,
            },
        },
    }),
    theme: {
        title: "Nestri | Auth",
        primary: "#FF4F01",
        //TODO: Change this in prod
        logo: "https://nestri.io/logo.webp",
        favicon: "https://nestri.io/seo/favicon.ico",
        background: {
            light: "#f5f5f5 ",
            dark: "#171717"
        },
        radius: "lg",
        font: {
            family: "Geist, sans-serif",
        },
        css: `
                    @import url('https://fonts.googleapis.com/css2?family=Geist:wght@100;200;300;400;500;600;700;800;900&display=swap');
                  `,
    },
    subjects,
    providers: {
        github: GithubAdapter({
            clientID: Resource.GithubClientID.value,
            clientSecret: Resource.GithubClientSecret.value,
            scopes: ["user:email"]
        }),
        discord: DiscordAdapter({
            clientID: Resource.DiscordClientID.value,
            clientSecret: Resource.DiscordClientSecret.value,
            scopes: ["email", "identify"]
        }),
        password: PasswordAdapter(
            PasswordUI({
                sendCode: async (email, code) => {
                    console.log("email & code:", email, code)
                    // await Email.send(
                    //     "auth",
                    //     email,
                    //     `Nestri code: ${code}`,
                    //     `Your Nestri login code is ${code}`,
                    // )
                },
            }),
        ),
        device: {
            type: "device",
            async client(input) {
                if (input.clientSecret !== Resource.AuthFingerprintKey.value) {
                    throw new Error("Invalid authorization token");
                }
                const teamSlug = input.params.team;
                if (!teamSlug) {
                    throw new Error("Team slug is required");
                }

                const hostname = input.params.hostname;
                if (!hostname) {
                    throw new Error("Hostname is required");
                }

                return {
                    hostname,
                    teamSlug
                };
            },
            init() { }
        } as Provider<{ teamSlug: string; hostname: string; }>,
    },
    allow: async (input) => {
        const url = new URL(input.redirectURI);
        const hostname = url.hostname;
        if (hostname.endsWith("nestri.io")) return true;
        if (hostname === "localhost") return true;
        return false;
    },
    success: async (ctx, value) => {
        // if (value.provider === "device") {
        //     const team = await Teams.fromSlug(value.teamSlug)
        //     console.log("team", team)
        //     console.log("teamSlug", value.teamSlug)
        //     if (team) {
        //         await Instances.create({ hostname: value.hostname, teamID: team.id })

        //         return await ctx.subject("device", {
        //             teamSlug: value.teamSlug,
        //             hostname: value.hostname,
        //         })
        //     }
        // }

        if (value.provider === "password") {
            const email = value.email
            const username = value.username
            const matching = await User.fromEmail(email)

            //Sign Up
            if (username && !matching) {
                const userID = await User.create({
                    name: username,
                    email,
                });

                if (!userID) throw new Error("Error creating user");

                return ctx.subject("user", {
                    userID,
                    email
                }, {
                    subject: email
                });

            } else if (matching) {
                //Sign In
                return ctx.subject("user", {
                    userID: matching.id,
                    email
                }, {
                    subject: email
                });
            }
        }

        let user = undefined as OauthUser | undefined;

        if (value.provider === "github") {
            const access = value.tokenset.access;
            user = await handleGithub(access)
        }

        if (value.provider === "discord") {
            const access = value.tokenset.access
            user = await handleDiscord(access)
        }

        if (user) {
            try {
                const matching = await User.fromEmail(user.primary.email);

                //Sign Up
                if (!matching) {
                    const userID = await User.create({
                        email: user.primary.email,
                        name: user.username,
                        avatarUrl: user.avatar
                    });

                    if (!userID) throw new Error("Error creating user");

                    return ctx.subject("user", {
                        userID,
                        email: user.primary.email
                    }, {
                        subject: user.primary.email
                    });
                } else {
                    //Sign In
                    return await ctx.subject("user", {
                        userID: matching.id,
                        email: user.primary.email
                    }, {
                        subject: user.primary.email
                    });
                }

            } catch (error) {
                console.error("error registering the user", error)
            }

        }

        throw new Error("Something went seriously wrong");
    },
}).use(logger())

export const handler = handle(app)
