'use client';

import type { TokenResponse } from '@/types/auth';
import { getCurrentPortalLocale, pickPortalText } from '@/lib/i18n/core';

const REQUEST_TIMEOUT_MS = 8000;
const REGISTER_REQUEST_TIMEOUT_MS = 90000;
const PROVIDER_ONBOARDING_TIMEOUT_MS = 120000;

export interface ProviderOnboardingPayload {
  username: string;
  password: string;
  provider: string;
  model: string;
  api_key: string;
  api_base?: string;
}

function normalizeBaseUrl(value?: string | null): string | null {
  const trimmed = value?.trim();
  if (!trimmed) return null;
  return trimmed.replace(/\/+$/, '');
}

function getFrontendBaseUrl(response: TokenResponse): string | null {
  const explicit = normalizeBaseUrl(response.backend_connection?.frontend_base_url);
  if (explicit) return explicit;

  const fromBackend = normalizeBaseUrl(
    response.backend_connection?.api_base_url ||
    response.backend_connection?.public_base_url ||
    response.local_backend?.public_base_url
  );
  return fromBackend;
}

function buildApiUrl(path: string): string {
  return path;
}

async function fetchJSON<T>(path: string, options?: RequestInit, timeoutMs = REQUEST_TIMEOUT_MS): Promise<T> {
  const locale = getCurrentPortalLocale();
  const controller = new AbortController();
  const timeoutId = window.setTimeout(() => controller.abort(), timeoutMs);

  try {
    const response = await fetch(buildApiUrl(path), {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        ...(options?.headers || {}),
      },
      signal: controller.signal,
    });

    if (!response.ok) {
      const text = await response.text();
      let detail = text;
      try {
        const parsed = JSON.parse(text);
        if (parsed && typeof parsed.detail === 'string') {
          detail = parsed.detail;
        }
      } catch {
        // keep raw text
      }
      throw new Error(`${pickPortalText(locale, '接口错误', 'API error')} ${response.status}: ${detail}`);
    }

    return response.json();
  } catch (error) {
    if (error instanceof DOMException && error.name === 'AbortError') {
      throw new Error(pickPortalText(locale, '请求超时', 'Request timed out'));
    }
    throw error;
  } finally {
    window.clearTimeout(timeoutId);
  }
}

export async function login(username: string, password: string): Promise<TokenResponse> {
  return fetchJSON('/api/runtime/login', {
    method: 'POST',
    body: JSON.stringify({ username, password }),
  });
}

export async function register(username: string, email: string, password: string): Promise<TokenResponse> {
  return fetchJSON('/api/runtime/register', {
    method: 'POST',
    body: JSON.stringify({ username, email, password }),
  }, REGISTER_REQUEST_TIMEOUT_MS);
}

export async function configureProviderOnboarding(payload: ProviderOnboardingPayload): Promise<TokenResponse> {
  return fetchJSON('/api/runtime/provider-onboarding', {
    method: 'POST',
    body: JSON.stringify(payload),
  }, PROVIDER_ONBOARDING_TIMEOUT_MS);
}

export function buildFrontendHandoffUrl(response: TokenResponse, nextPath: string): string {
  const locale = getCurrentPortalLocale();
  const frontendBaseUrl = getFrontendBaseUrl(response);
  if (!frontendBaseUrl) {
    throw new Error(pickPortalText(locale, '后端未返回目标前端地址', 'Backend did not return a target frontend URL'));
  }
  const handoffCode = response.handoff_code?.trim();
  if (!handoffCode) {
    throw new Error(pickPortalText(locale, '后端未返回 handoff code', 'Backend did not return a handoff code'));
  }

  const url = new URL('/handoff', frontendBaseUrl);
  url.searchParams.set('code', handoffCode);
  if (nextPath) {
    url.searchParams.set('next', nextPath);
  }
  return url.toString();
}

export function withNext(path: '/login' | '/register', nextPath: string): string {
  const params = new URLSearchParams();
  if (nextPath) {
    params.set('next', nextPath);
  }
  const query = params.toString();
  return query ? `${path}?${query}` : path;
}
