import React, { createContext, useContext, useMemo } from 'react';
import type { ReactNode } from 'react';

import { PlaybasisClient } from './api/client';
import { ThemeProvider } from './theme/context';

// ─────────────────────────────────────────────────────────────────────────────
// Context
// ─────────────────────────────────────────────────────────────────────────────

interface PlaybasisContextValue {
  client: PlaybasisClient;
  tenantId: string;
  playerId: string | null;
  baseUrl: string;
}

const PlaybasisContext = createContext<PlaybasisContextValue | null>(null);

// ─────────────────────────────────────────────────────────────────────────────
// Provider Props
// ─────────────────────────────────────────────────────────────────────────────

interface PlaybasisProviderProps {
  children: ReactNode;
  apiKey: string;
  tenantId?: string;
  playerId?: string;
  baseUrl?: string;
  requestTimeoutMs?: number;
  requestRetries?: number;
}

const QWIK_BASE_URLS = {
  production: 'https://apim-pb-production.azure-api.net/v1',
  staging: 'https://apim-pb-staging.azure-api.net/playbasis/v1',
};

const resolveBaseUrl = (tenantId: string, baseUrl?: string) => {
  if (baseUrl) return baseUrl;
  if (tenantId.toLowerCase().includes('prod')) return QWIK_BASE_URLS.production;
  return QWIK_BASE_URLS.staging;
};

// ─────────────────────────────────────────────────────────────────────────────
// Provider Component
// ─────────────────────────────────────────────────────────────────────────────

export function PlaybasisProvider({
  children,
  apiKey,
  tenantId,
  playerId,
  baseUrl,
  requestTimeoutMs,
  requestRetries,
}: PlaybasisProviderProps) {
  const resolvedTenantId =
    tenantId ?? (baseUrl && baseUrl.includes('production') ? 'qwik-prod' : 'qwikcard');
  const resolvedBaseUrl = resolveBaseUrl(resolvedTenantId, baseUrl);
  const client = useMemo(
    () =>
      new PlaybasisClient({
        apiKey,
        tenantId: resolvedTenantId,
        baseUrl: resolvedBaseUrl,
        timeoutMs: requestTimeoutMs,
        retries: requestRetries,
      }),
    [apiKey, resolvedTenantId, resolvedBaseUrl, requestTimeoutMs, requestRetries],
  );

  const value = useMemo(
    () => ({
      client,
      tenantId: resolvedTenantId,
      playerId: playerId ?? null,
      baseUrl: resolvedBaseUrl,
    }),
    [client, resolvedTenantId, playerId, resolvedBaseUrl],
  );

  return (
    <ThemeProvider>
      <PlaybasisContext.Provider value={value}>{children}</PlaybasisContext.Provider>
    </ThemeProvider>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// Hook
// ─────────────────────────────────────────────────────────────────────────────

export function usePlaybasis(): PlaybasisContextValue {
  const context = useContext(PlaybasisContext);
  if (!context) {
    throw new Error('usePlaybasis must be used within a PlaybasisProvider');
  }
  return context;
}

export default PlaybasisProvider;
