import { createFileRoute } from "@tanstack/react-router";
import { msg } from "@lingui/core/macro";
import { SpotifyWebApiClient } from "@/lib/spotify/client";
import { localizedFor } from "@/lib/i18n/server-messages";

function getAccessTokenFromCookies(request: Request): string | null {
  const cookieHeader = request.headers.get("cookie");
  if (!cookieHeader) return null;

  const cookies = Object.fromEntries(
    cookieHeader.split("; ").map((c) => c.split("="))
  );

  return cookies.spotify_access_token || null;
}

export const Route = createFileRoute("/api/spotify/playback")({
  server: {
    handlers: {
      POST: async ({ request }: { request: Request }) => {
        // No session middleware on this route; localize with DEFAULT_LOCALE.
        const i18n = localizedFor(null);
        try {
          const accessToken = getAccessTokenFromCookies(request);
          if (!accessToken) {
            return new Response(
              JSON.stringify({ error: i18n._(msg`No access token found`) }),
              {
                status: 401,
                headers: { "Content-Type": "application/json" },
              }
            );
          }

          const body = await request.json();
          const { action, deviceId, volumePercent, trackId, positionMs } = body;

          const spotifyClient = new SpotifyWebApiClient(accessToken);

          switch (action) {
            case "play":
              await spotifyClient.play(deviceId);
              break;
            case "playTrack":
              if (!trackId) {
                return new Response(
                  JSON.stringify({
                    error: i18n._(msg`trackId is required for playTrack action`),
                  }),
                  {
                    status: 400,
                    headers: { "Content-Type": "application/json" },
                  }
                );
              }
              await spotifyClient.playTrack(trackId, deviceId, positionMs);
              break;
            case "pause":
              await spotifyClient.pause();
              break;
            case "next":
              await spotifyClient.skipToNext();
              break;
            case "previous":
              await spotifyClient.skipToPrevious();
              break;
            case "volume":
              if (typeof volumePercent !== "number") {
                return new Response(
                  JSON.stringify({ error: i18n._(msg`volumePercent must be a number`) }),
                  {
                    status: 400,
                    headers: { "Content-Type": "application/json" },
                  }
                );
              }
              await spotifyClient.setVolume(volumePercent);
              break;
            case "transfer":
              if (!deviceId) {
                return new Response(
                  JSON.stringify({
                    error: i18n._(msg`deviceId is required for transfer action`),
                  }),
                  {
                    status: 400,
                    headers: { "Content-Type": "application/json" },
                  }
                );
              }
              await spotifyClient.transferPlayback(deviceId);
              break;
            default:
              return new Response(
                JSON.stringify({ error: i18n._(msg`Invalid action`) }),
                {
                  status: 400,
                  headers: { "Content-Type": "application/json" },
                }
              );
          }

          return new Response(JSON.stringify({ success: true }), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (error) {
          console.error("Playback control error:", error);

          if (error instanceof Error) {
            if (error.message.includes("NO_ACTIVE_DEVICE")) {
              return new Response(
                JSON.stringify({
                  error: i18n._(
                    msg`No active device found. Please select a device first.`
                  ),
                }),
                {
                  status: 400,
                  headers: { "Content-Type": "application/json" },
                }
              );
            }

            if (error.message.includes("PREMIUM_REQUIRED")) {
              return new Response(
                JSON.stringify({
                  error: i18n._(
                    msg`Spotify Premium is required for playback control.`
                  ),
                }),
                {
                  status: 403,
                  headers: { "Content-Type": "application/json" },
                }
              );
            }

            console.error("Full error details:", {
              message: error.message,
              stack: error.stack,
              name: error.name,
            });
          }

          return new Response(
            JSON.stringify({
              error: i18n._(msg`Playback control failed`),
              details: error instanceof Error ? error.message : "Unknown error",
            }),
            {
              status: 500,
              headers: { "Content-Type": "application/json" },
            }
          );
        }
      },

      GET: async ({ request }: { request: Request }) => {
        // No session middleware on this route; localize with DEFAULT_LOCALE.
        const i18n = localizedFor(null);
        try {
          const accessToken = getAccessTokenFromCookies(request);
          if (!accessToken) {
            return new Response(
              JSON.stringify({ error: i18n._(msg`No access token found`) }),
              {
                status: 401,
                headers: { "Content-Type": "application/json" },
              }
            );
          }

          const url = new URL(request.url);
          const type = url.searchParams.get("type");

          const spotifyClient = new SpotifyWebApiClient(accessToken);

          if (type === "devices") {
            const devices = await spotifyClient.getDevices();
            return new Response(JSON.stringify({ devices }), {
              status: 200,
              headers: { "Content-Type": "application/json" },
            });
          } else if (type === "state") {
            const playbackState = await spotifyClient.getPlaybackState();
            return new Response(JSON.stringify({ playbackState }), {
              status: 200,
              headers: { "Content-Type": "application/json" },
            });
          } else {
            const [devices, playbackState] = await Promise.all([
              spotifyClient.getDevices(),
              spotifyClient.getPlaybackState(),
            ]);

            return new Response(JSON.stringify({ devices, playbackState }), {
              status: 200,
              headers: { "Content-Type": "application/json" },
            });
          }
        } catch (error) {
          console.error("Get playback data error:", error);
          return new Response(
            JSON.stringify({ error: i18n._(msg`Failed to get playback data`) }),
            {
              status: 500,
              headers: { "Content-Type": "application/json" },
            }
          );
        }
      },
    },
  },
});
