import { createFileRoute } from "@tanstack/react-router";

const SPOTIFY_CLIENT_ID = process.env.VITE_SPOTIFY_CLIENT_ID!;
const SPOTIFY_CLIENT_SECRET = process.env.SPOTIFY_CLIENT_SECRET!;
const SPOTIFY_REDIRECT_URI = process.env.VITE_SPOTIFY_REDIRECT_URI!;

export const Route = createFileRoute("/api/spotify/callback")({
  server: {
    handlers: {
      GET: async ({ request }: { request: Request }) => {
        const getReturnPath = (state: string | null): string => {
          if (!state) return "/";
          try {
            const decodedState = JSON.parse(atob(state));
            return decodedState.returnPath || "/";
          } catch {
            return "/";
          }
        };

        try {
          const url = new URL(request.url);
          const code = url.searchParams.get("code");
          const state = url.searchParams.get("state");
          const error = url.searchParams.get("error");

          const returnPath = getReturnPath(state);

          if (error) {
            console.error("Spotify OAuth error:", error);
            return new Response(null, {
              status: 302,
              headers: {
                Location:
                  returnPath + "?spotify_error=" + encodeURIComponent(error),
              },
            });
          }

          if (!code || !state) {
            console.error("Missing code or state:", {
              code: !!code,
              state: !!state,
            });
            return new Response(null, {
              status: 302,
              headers: {
                Location: returnPath + "?spotify_error=missing_code_or_state",
              },
            });
          }

          console.log("Token exchange attempt:", {
            client_id: SPOTIFY_CLIENT_ID,
            redirect_uri: SPOTIFY_REDIRECT_URI,
            has_code: !!code,
            has_state: !!state,
          });

          const tokenResponse = await fetch(
            "https://accounts.spotify.com/api/token",
            {
              method: "POST",
              headers: {
                "Content-Type": "application/x-www-form-urlencoded",
                Authorization: `Basic ${Buffer.from(`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`).toString("base64")}`,
              },
              body: new URLSearchParams({
                grant_type: "authorization_code",
                code,
                redirect_uri: SPOTIFY_REDIRECT_URI,
              }),
            }
          );

          if (!tokenResponse.ok) {
            const errorText = await tokenResponse.text();
            console.error("Token exchange error:", {
              status: tokenResponse.status,
              statusText: tokenResponse.statusText,
              body: errorText,
              redirect_uri: SPOTIFY_REDIRECT_URI,
            });

            const errorParam = encodeURIComponent(
              `${tokenResponse.status}: ${errorText}`
            );
            return new Response(null, {
              status: 302,
              headers: {
                Location: `${returnPath}?spotify_error=token_exchange_failed&details=${errorParam}`,
              },
            });
          }

          const tokens = await tokenResponse.json();

          console.log("Token exchange successful:", {
            has_access_token: !!tokens.access_token,
            has_refresh_token: !!tokens.refresh_token,
            expires_in: tokens.expires_in,
          });

          console.log("Decoded return path:", returnPath);

          const response = new Response(null, {
            status: 302,
            headers: {
              Location: returnPath + "?spotify_auth=success",
            },
          });

          const isSecure = import.meta.env.NODE_ENV === "production";
          const cookieOptions = `HttpOnly; ${isSecure ? 'Secure; ' : ''}SameSite=Lax; Path=/; Max-Age=${tokens.expires_in}`;

          response.headers.append(
            "Set-Cookie",
            `spotify_access_token=${tokens.access_token}; ${cookieOptions}`
          );

          if (tokens.refresh_token) {
            const refreshCookieOptions = `HttpOnly; ${isSecure ? 'Secure; ' : ''}SameSite=Lax; Path=/; Max-Age=${60 * 60 * 24 * 30}`; // 30 days
            response.headers.append(
              "Set-Cookie",
              `spotify_refresh_token=${tokens.refresh_token}; ${refreshCookieOptions}`
            );
          }

          return response;
        } catch (error) {
          console.error("Spotify callback error:", error);
          const url = new URL(request.url);
          const state = url.searchParams.get("state");
          const returnPath = getReturnPath(state);
          return new Response(null, {
            status: 302,
            headers: {
              Location: returnPath + "?spotify_error=callback_failed",
            },
          });
        }
      },
    },
  },
});
