import { createGrpcWebTransport } from "@connectrpc/connect-web";
import { createClient, type Interceptor } from "@connectrpc/connect";
import {
  getToken,
  isTokenExpired,
  clearTokens,
  SESSION_EXPIRED_KEY,
} from "./auth";

// Generated service definitions (protoc-gen-es v2 — services live in *_pb.ts)
import { TradingService } from "../gen/trading_pb";
import { RiskService } from "../gen/risk_pb";
import { MLService } from "../gen/ml_pb";
import { MLTrainingService } from "../gen/ml_training_pb";
import { ConfigService } from "../gen/config_pb";
import { MonitoringService } from "../gen/monitoring_pb";
import { BacktestingService } from "../gen/fxt_trading_pb";
import { AuthService } from "../gen/auth_pb";

const API_URL = import.meta.env.VITE_API_URL ?? "http://localhost:50051";

/** Margin in seconds before actual expiry to treat the token as expired */
const EXPIRY_MARGIN_SECONDS = 60;

/**
 * Interceptor that attaches the JWT Authorization header to every request
 * and handles session expiry / UNAUTHENTICATED responses.
 */
const authInterceptor: Interceptor = (next) => async (req) => {
  const token = getToken();
  if (token) {
    if (isTokenExpired(token, EXPIRY_MARGIN_SECONDS)) {
      sessionStorage.setItem(SESSION_EXPIRED_KEY, "1");
      clearTokens();
      window.location.href = "/login";
      throw new Error("Session expired");
    }
    req.header.set("authorization", `Bearer ${token}`);
  }
  try {
    return await next(req);
  } catch (err: unknown) {
    // gRPC status 16 = UNAUTHENTICATED
    if (
      err &&
      typeof err === "object" &&
      "code" in err &&
      (err as { code: number }).code === 16
    ) {
      sessionStorage.setItem(SESSION_EXPIRED_KEY, "1");
      clearTokens();
      window.location.href = "/login";
    }
    throw err;
  }
};

/** Authenticated transport — used for all services except login */
const transport = createGrpcWebTransport({
  baseUrl: API_URL,
  interceptors: [authInterceptor],
});

/** Public transport — no auth header, used for login/refresh */
const publicTransport = createGrpcWebTransport({
  baseUrl: API_URL,
});

// ---------------------------------------------------------------------------
// Service clients
// ---------------------------------------------------------------------------

export const authClient = createClient(AuthService, publicTransport);
export const tradingClient = createClient(TradingService, transport);
export const riskClient = createClient(RiskService, transport);
export const mlClient = createClient(MLService, transport);
export const mlTrainingClient = createClient(MLTrainingService, transport);
export const configClient = createClient(ConfigService, transport);
export const monitoringClient = createClient(MonitoringService, transport);
export const backtestingClient = createClient(BacktestingService, transport);
