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

export const GET: RequestHandler<{ id: string }> = async ({ fetch, params, 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
  }
  // 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 includeScores = url.searchParams.get('scores');

  try {
    if (includeScores === '1') {
      const playerId = params.id as string;
      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 });
    }

    const playerId = params.id as string;
    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 });
  } catch (err) {
    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 });
  }
};


