import { FastifyInstance } from "fastify";
import { run } from "../../shared/database";

async function anilist(fastify: FastifyInstance) {
    fastify.get("/anilist", async (request, reply) => {
        try {
            const { code, state } = request.query as { code?: string; state?: string };

            if (!code) return reply.status(400).send("No code");
            if (!state) return reply.status(400).send("No user state");

            const userId = Number(state);
            if (!userId || isNaN(userId)) {
                return reply.status(400).send("Invalid user id");
            }

            const tokenRes = await fetch("https://anilist.co/api/v2/oauth/token", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({
                    grant_type: "authorization_code",
                    client_id: process.env.ANILIST_CLIENT_ID,
                    client_secret: process.env.ANILIST_CLIENT_SECRET,
                    redirect_uri: "http://localhost:54322/api/anilist",
                    code
                })
            });

            const tokenData = await tokenRes.json();

            if (!tokenData.access_token) {
                console.error("AniList token error:", tokenData);
                return reply.status(500).send("Failed to get AniList token");
            }

            const userRes = await fetch("https://graphql.anilist.co", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    Authorization: `${tokenData.token_type} ${tokenData.access_token}`
                },
                body: JSON.stringify({
                    query: `query { Viewer { id } }`
                })
            });

            const userData = await userRes.json();
            const anilistUserId = userData?.data?.Viewer?.id;

            if (!anilistUserId) {
                console.error("AniList Viewer error:", userData);
                return reply.status(500).send("Failed to fetch AniList user");
            }

            const expiresAt = new Date(
                Date.now() + tokenData.expires_in * 1000
            ).toISOString();

            await run(
                `
                    INSERT INTO UserIntegration
                    (user_id, platform, access_token, refresh_token, token_type, anilist_user_id, expires_at)
                    VALUES (?, ?, ?, ?, ?, ?, ?)
                        ON CONFLICT(user_id) DO UPDATE SET
                        access_token = excluded.access_token,
                                                    refresh_token = excluded.refresh_token,
                                                    token_type = excluded.token_type,
                                                    anilist_user_id = excluded.anilist_user_id,
                                                    expires_at = excluded.expires_at
                `,
                [
                    userId,
                    "AniList",
                    tokenData.access_token,
                    tokenData.refresh_token,
                    tokenData.token_type,
                    anilistUserId,
                    expiresAt
                ],
                "userdata"
            );

            return reply.redirect("http://localhost:54322/?anilist=success");
        } catch (e) {
            console.error("AniList error:", e);
            return reply.redirect("http://localhost:54322/?anilist=error");
        }
    });
}

export default anilist;