import type { RequestHandler } from '@sveltejs/kit';
import { createBeatLeaderAPI, RateLimitError } from '$lib/server/beatleader';
import { getValidAccessToken, getBeatLeaderSessionCookieHeader } from '$lib/server/beatleaderAuth';
import { getSteamIdFromCookies } from '$lib/server/steam';

export const GET: RequestHandler = async ({ fetch, url, cookies }) => {
  type AuthMode = 'steam' | 'oauth' | 'session' | 'auto' | 'none';
  const authMode = (url.searchParams.get('auth') as AuthMode | null) ?? 'steam';
  const debug = url.searchParams.get('debug') === '1';

  let token: string | undefined;
  let websiteCookieHeader: string | undefined;

  if (authMode === 'oauth') {
    const maybeToken = await getValidAccessToken(cookies);
    token = maybeToken ?? undefined;
  } else if (authMode === 'session') {
    websiteCookieHeader = getBeatLeaderSessionCookieHeader(cookies) ?? undefined;
  } else if (authMode === 'steam') {
    websiteCookieHeader = getBeatLeaderSessionCookieHeader(cookies) ?? undefined;
    if (!websiteCookieHeader) {
      const steamId = getSteamIdFromCookies(cookies);
      if (steamId) {
        try {
          const probe = await fetch('https://api.beatleader.com/user', { credentials: 'include' as RequestCredentials });
          const setCookieHeaders = (probe.headers as any).getSetCookie?.() ?? probe.headers.get('set-cookie')?.split(',') ?? [];
          const { setBeatLeaderSessionFromSetCookieHeaders } = await import('$lib/server/beatleaderAuth');
          setBeatLeaderSessionFromSetCookieHeaders(cookies, Array.isArray(setCookieHeaders) ? setCookieHeaders : [setCookieHeaders]);
          websiteCookieHeader = getBeatLeaderSessionCookieHeader(cookies) ?? undefined;
        } catch {}
      }
    }
  } else if (authMode === 'auto') {
    const maybeToken = await getValidAccessToken(cookies);
    if (maybeToken) {
      token = maybeToken;
    } else {
      websiteCookieHeader = getBeatLeaderSessionCookieHeader(cookies) ?? undefined;
      if (!websiteCookieHeader) {
        const steamId = getSteamIdFromCookies(cookies);
        if (steamId) {
          try {
            const probe = await fetch('https://api.beatleader.com/user', { credentials: 'include' as RequestCredentials });
            const setCookieHeaders = (probe.headers as any).getSetCookie?.() ?? probe.headers.get('set-cookie')?.split(',') ?? [];
            const { setBeatLeaderSessionFromSetCookieHeaders } = await import('$lib/server/beatleaderAuth');
            setBeatLeaderSessionFromSetCookieHeaders(cookies, Array.isArray(setCookieHeaders) ? setCookieHeaders : [setCookieHeaders]);
            websiteCookieHeader = getBeatLeaderSessionCookieHeader(cookies) ?? undefined;
          } catch {}
        }
      }
    }
  } else {
    // 'none' -> no auth headers
  }

  // Wrap fetch to track upstream BL requests
  let blCallCount = 0;
  let blLastUrl: string | undefined;
  let blLastHeaders: Record<string, string> | undefined;
  const wrappedFetch: typeof fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
    const inputUrl = typeof input === 'string' ? input : (input instanceof URL ? input.toString() : (input as Request).url);
    const isBL = String(inputUrl).startsWith('https://api.beatleader.com');
    if (isBL) {
      blCallCount += 1;
      blLastUrl = String(inputUrl);
      const hdrs: Record<string, string> = {};
      if (init?.headers) {
        if (init.headers instanceof Headers) {
          init.headers.forEach((v, k) => { hdrs[k] = v; });
        } else if (Array.isArray(init.headers)) {
          for (const [k, v] of init.headers) { if (v != null) hdrs[k] = String(v); }
        } else {
          Object.entries(init.headers as Record<string, string>).forEach(([k, v]) => { if (v != null) hdrs[k] = String(v); });
        }
      }
      blLastHeaders = hdrs;
    }
    return fetch(input as any, init as any);
  };
  const api = createBeatLeaderAPI(wrappedFetch, token, websiteCookieHeader);
  const resolvedAuth = token ? 'oauth' : (websiteCookieHeader ? 'session' : 'none');
  const path = url.searchParams.get('path');
  if (!path) {
    return new Response(JSON.stringify({ error: 'Missing path' }), { status: 400 });
  }

  try {
    // Simple pass-through for safe GETs: limit to known patterns
    if (path.startsWith('/player/')) {
      const parts = path.split('/').filter(Boolean);
      if (parts.length === 2) {
        const playerId = parts[1];
        const data = await api.getPlayer(playerId);
        const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
        if (blLastUrl) headers['x-bl-last-url'] = blLastUrl;
        if (blLastHeaders) {
          const hasAuthHeader = blLastHeaders['Authorization'] || blLastHeaders['authorization'];
          const hasCookieHeader = blLastHeaders['Cookie'] || blLastHeaders['cookie'];
          if (debug) {
            if (hasAuthHeader) headers['x-bl-last-authorization'] = hasAuthHeader as string;
            if (hasCookieHeader) headers['x-bl-last-cookie'] = hasCookieHeader as string;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', `\"Authorization: ${hasAuthHeader}\"`);
            if (hasCookieHeader) curlParts.push('-H', `\"Cookie: ${hasCookieHeader}\"`);
            headers['x-bl-curl'] = curlParts.join(' ');
          } else {
            const authTag = hasAuthHeader ? 'present' : 'absent';
            const cookieTag = hasCookieHeader ? 'present' : 'absent';
            headers['x-bl-last-authorization'] = authTag;
            headers['x-bl-last-cookie'] = cookieTag;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', '\"Authorization: Bearer <redacted>\"');
            if (hasCookieHeader) curlParts.push('-H', '\"Cookie: <redacted>\"');
            headers['x-bl-curl'] = curlParts.join(' ');
          }
        }
        return new Response(JSON.stringify(data), { headers });
      }
      if (parts.length === 3 && parts[2] === 'scores') {
        const playerId = parts[1];
        const data = await api.getPlayerScores(playerId, Object.fromEntries(url.searchParams));
        const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
        if (blLastUrl) headers['x-bl-last-url'] = blLastUrl;
        if (blLastHeaders) {
          const hasAuthHeader = blLastHeaders['Authorization'] || blLastHeaders['authorization'];
          const hasCookieHeader = blLastHeaders['Cookie'] || blLastHeaders['cookie'];
          if (debug) {
            if (hasAuthHeader) headers['x-bl-last-authorization'] = hasAuthHeader as string;
            if (hasCookieHeader) headers['x-bl-last-cookie'] = hasCookieHeader as string;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', `\"Authorization: ${hasAuthHeader}\"`);
            if (hasCookieHeader) curlParts.push('-H', `\"Cookie: ${hasCookieHeader}\"`);
            headers['x-bl-curl'] = curlParts.join(' ');
          } else {
            const authTag = hasAuthHeader ? 'present' : 'absent';
            const cookieTag = hasCookieHeader ? 'present' : 'absent';
            headers['x-bl-last-authorization'] = authTag;
            headers['x-bl-last-cookie'] = cookieTag;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', '\"Authorization: Bearer <redacted>\"');
            if (hasCookieHeader) curlParts.push('-H', '\"Cookie: <redacted>\"');
            headers['x-bl-curl'] = curlParts.join(' ');
          }
        }
        return new Response(JSON.stringify(data), { headers });
      }
    }

    if (path.startsWith('/v5/scores/')) {
      const parts = path.split('/').filter(Boolean);
      // /v5/scores/{hash}/{diff}/{mode}
      if (parts.length >= 5) {
        const hash = parts[2];
        const diff = parts[3];
        const mode = parts[4];
        const data = await api.getLeaderboard(hash, {
          diff,
          mode,
          page: Number(url.searchParams.get('page') ?? '1'),
          count: Number(url.searchParams.get('count') ?? '10')
        });
        return new Response(JSON.stringify(data), { headers: { 'content-type': 'application/json' } });
      }
    }

    if (path.startsWith('/leaderboards/hash/')) {
      const parts = path.split('/').filter(Boolean);
      if (parts.length === 3) {
        const hash = parts[2];
        const data = await api.getLeaderboardsByHash(hash);
        const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
        if (blLastUrl) headers['x-bl-last-url'] = blLastUrl;
        if (blLastHeaders) {
          const hasAuthHeader = blLastHeaders['Authorization'] || blLastHeaders['authorization'];
          const hasCookieHeader = blLastHeaders['Cookie'] || blLastHeaders['cookie'];
          if (debug) {
            if (hasAuthHeader) headers['x-bl-last-authorization'] = hasAuthHeader as string;
            if (hasCookieHeader) headers['x-bl-last-cookie'] = hasCookieHeader as string;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', `\"Authorization: ${hasAuthHeader}\"`);
            if (hasCookieHeader) curlParts.push('-H', `\"Cookie: ${hasCookieHeader}\"`);
            headers['x-bl-curl'] = curlParts.join(' ');
          } else {
            const authTag = hasAuthHeader ? 'present' : 'absent';
            const cookieTag = hasCookieHeader ? 'present' : 'absent';
            headers['x-bl-last-authorization'] = authTag;
            headers['x-bl-last-cookie'] = cookieTag;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', '\"Authorization: Bearer <redacted>\"');
            if (hasCookieHeader) curlParts.push('-H', '\"Cookie: <redacted>\"');
            headers['x-bl-curl'] = curlParts.join(' ');
          }
        }
        return new Response(JSON.stringify(data), { headers });
      }
    }

    if (path === '/user') {
      const redirect = url.searchParams.get('redirect_uri') ?? '/';
      if (authMode === 'oauth') {
        if (!token) {
          return new Response(
            JSON.stringify({ error: 'Unauthorized', login: '/auth/beatleader/login?redirect_uri=' + encodeURIComponent(redirect) }),
            { status: 401, headers: { 'content-type': 'application/json' } }
          );
        }
        const data = await api.getUser();
        const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
        if (blLastUrl) headers['x-bl-last-url'] = blLastUrl;
        if (blLastHeaders) {
          const hasAuthHeader = blLastHeaders['Authorization'] || blLastHeaders['authorization'];
          const hasCookieHeader = blLastHeaders['Cookie'] || blLastHeaders['cookie'];
          if (debug) {
            if (hasAuthHeader) headers['x-bl-last-authorization'] = hasAuthHeader as string;
            if (hasCookieHeader) headers['x-bl-last-cookie'] = hasCookieHeader as string;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', `\"Authorization: ${hasAuthHeader}\"`);
            if (hasCookieHeader) curlParts.push('-H', `\"Cookie: ${hasCookieHeader}\"`);
            headers['x-bl-curl'] = curlParts.join(' ');
          } else {
            const authTag = hasAuthHeader ? 'present' : 'absent';
            const cookieTag = hasCookieHeader ? 'present' : 'absent';
            headers['x-bl-last-authorization'] = authTag;
            headers['x-bl-last-cookie'] = cookieTag;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', '\"Authorization: Bearer <redacted>\"');
            if (hasCookieHeader) curlParts.push('-H', '\"Cookie: <redacted>\"');
            headers['x-bl-curl'] = curlParts.join(' ');
          }
        }
        return new Response(JSON.stringify(data), { headers });
      }
      if (authMode === 'session') {
        const cookieHeader = websiteCookieHeader ?? getBeatLeaderSessionCookieHeader(cookies) ?? undefined;
        if (!cookieHeader) {
          return new Response(
            JSON.stringify({ error: 'Unauthorized', sessionLogin: '/tools/beatleader-session?return=' + encodeURIComponent(redirect) }),
            { status: 401, headers: { 'content-type': 'application/json' } }
          );
        }
        const res = await fetch('https://api.beatleader.com/user', { headers: { Cookie: cookieHeader } });
        const data = await res.json();
        const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
        headers['x-bl-last-url'] = 'https://api.beatleader.com/user';
        headers['x-bl-last-cookie'] = debug ? String(cookieHeader) : 'present';
        headers['x-bl-last-authorization'] = 'absent';
        const curlParts = [ 'curl', '-sS', '-X', 'GET', 'https://api.beatleader.com/user' ];
        if (cookieHeader) curlParts.push('-H', debug ? `\"Cookie: ${cookieHeader}\"` : '\"Cookie: <redacted>\"');
        headers['x-bl-curl'] = curlParts.join(' ');
        return new Response(JSON.stringify(data), { headers });
      }
      if (authMode === 'steam') {
        const cookieHeader = websiteCookieHeader ?? getBeatLeaderSessionCookieHeader(cookies) ?? undefined;
        if (!cookieHeader) {
          return new Response(
            JSON.stringify({ error: 'Unauthorized', steamLogin: '/auth/steam/login?redirect_uri=' + encodeURIComponent(redirect) }),
            { status: 401, headers: { 'content-type': 'application/json' } }
          );
        }
        const res = await fetch('https://api.beatleader.com/user', { headers: { Cookie: cookieHeader } });
        const data = await res.json();
        const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
        headers['x-bl-last-url'] = 'https://api.beatleader.com/user';
        headers['x-bl-last-cookie'] = debug ? String(cookieHeader) : 'present';
        headers['x-bl-last-authorization'] = 'absent';
        const curlParts = [ 'curl', '-sS', '-X', 'GET', 'https://api.beatleader.com/user' ];
        if (cookieHeader) curlParts.push('-H', debug ? `\"Cookie: ${cookieHeader}\"` : '\"Cookie: <redacted>\"');
        headers['x-bl-curl'] = curlParts.join(' ');
        return new Response(JSON.stringify(data), { headers });
      }
      // auto/none fallthrough
      if (token) {
        const data = await api.getUser();
        const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
        if (blLastUrl) headers['x-bl-last-url'] = blLastUrl;
        if (blLastHeaders) {
          const hasAuthHeader = blLastHeaders['Authorization'] || blLastHeaders['authorization'];
          const hasCookieHeader = blLastHeaders['Cookie'] || blLastHeaders['cookie'];
          if (debug) {
            if (hasAuthHeader) headers['x-bl-last-authorization'] = hasAuthHeader as string;
            if (hasCookieHeader) headers['x-bl-last-cookie'] = hasCookieHeader as string;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', `\"Authorization: ${hasAuthHeader}\"`);
            if (hasCookieHeader) curlParts.push('-H', `\"Cookie: ${hasCookieHeader}\"`);
            headers['x-bl-curl'] = curlParts.join(' ');
          } else {
            const authTag = hasAuthHeader ? 'present' : 'absent';
            const cookieTag = hasCookieHeader ? 'present' : 'absent';
            headers['x-bl-last-authorization'] = authTag;
            headers['x-bl-last-cookie'] = cookieTag;
            const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
            if (hasAuthHeader) curlParts.push('-H', '\"Authorization: Bearer <redacted>\"');
            if (hasCookieHeader) curlParts.push('-H', '\"Cookie: <redacted>\"');
            headers['x-bl-curl'] = curlParts.join(' ');
          }
        }
        return new Response(JSON.stringify(data), { headers });
      }
      const cookieHeader = websiteCookieHeader ?? getBeatLeaderSessionCookieHeader(cookies) ?? undefined;
      if (cookieHeader) {
        const res = await fetch('https://api.beatleader.com/user', { headers: { Cookie: cookieHeader } });
        const data = await res.json();
        const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
        headers['x-bl-last-url'] = 'https://api.beatleader.com/user';
        headers['x-bl-last-cookie'] = debug ? String(cookieHeader) : 'present';
        headers['x-bl-last-authorization'] = 'absent';
        const curlParts = [ 'curl', '-sS', '-X', 'GET', 'https://api.beatleader.com/user' ];
        if (cookieHeader) curlParts.push('-H', debug ? `\"Cookie: ${cookieHeader}\"` : '\"Cookie: <redacted>\"');
        headers['x-bl-curl'] = curlParts.join(' ');
        return new Response(JSON.stringify(data), { headers });
      }
      return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401, headers: { 'content-type': 'application/json' } });
    }

    if (path === '/leaderboards') {
      const data = await api.getRankedLeaderboards({
        stars_from: url.searchParams.get('stars_from') ? Number(url.searchParams.get('stars_from')) : undefined,
        stars_to: url.searchParams.get('stars_to') ? Number(url.searchParams.get('stars_to')) : undefined,
        page: url.searchParams.get('page') ? Number(url.searchParams.get('page')) : undefined,
        count: url.searchParams.get('count') ? Number(url.searchParams.get('count')) : undefined
      });
      const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
      if (blLastUrl) headers['x-bl-last-url'] = blLastUrl;
      if (blLastHeaders) {
        const hasAuthHeader = blLastHeaders['Authorization'] || blLastHeaders['authorization'];
        const hasCookieHeader = blLastHeaders['Cookie'] || blLastHeaders['cookie'];
        if (debug) {
          if (hasAuthHeader) headers['x-bl-last-authorization'] = hasAuthHeader as string;
          if (hasCookieHeader) headers['x-bl-last-cookie'] = hasCookieHeader as string;
          const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
          if (hasAuthHeader) curlParts.push('-H', `\"Authorization: ${hasAuthHeader}\"`);
          if (hasCookieHeader) curlParts.push('-H', `\"Cookie: ${hasCookieHeader}\"`);
          headers['x-bl-curl'] = curlParts.join(' ');
        } else {
          const authTag = hasAuthHeader ? 'present' : 'absent';
          const cookieTag = hasCookieHeader ? 'present' : 'absent';
          headers['x-bl-last-authorization'] = authTag;
          headers['x-bl-last-cookie'] = cookieTag;
          const curlParts = [ 'curl', '-sS', '-X', 'GET', blLastUrl ?? '' ];
          if (hasAuthHeader) curlParts.push('-H', '\"Authorization: Bearer <redacted>\"');
          if (hasCookieHeader) curlParts.push('-H', '\"Cookie: <redacted>\"');
          headers['x-bl-curl'] = curlParts.join(' ');
        }
      }
      return new Response(JSON.stringify(data), { headers });
    }

    return new Response(JSON.stringify({ error: 'Unsupported path' }), { status: 400 });
  } catch (err) {
    if (err instanceof RateLimitError) {
      const retrySeconds = err.retryAfterMs ? Math.ceil(err.retryAfterMs / 1000) : undefined;
      const headers: Record<string, string> = { 'content-type': 'application/json' };
      if (retrySeconds !== undefined && Number.isFinite(retrySeconds)) {
        headers['Retry-After'] = String(retrySeconds);
      }
      return new Response(JSON.stringify({ error: 'Rate limited by BeatLeader' }), { status: 429, headers });
    }
    const message = err instanceof Error ? err.message : 'Unknown error';
    const headers: Record<string, string> = { 'content-type': 'application/json', 'x-bl-auth-mode': resolvedAuth, 'x-bl-auth-requested': authMode, 'x-bl-call-count': String(blCallCount) };
    if (blLastUrl) headers['x-bl-last-url'] = blLastUrl;
    return new Response(JSON.stringify({ error: message }), { status: 502, headers });
  }
};


