import React, { createContext, useContext, useMemo } from 'react';
import type { Shade } from '@shade/sdk';
import { resolveTheme, type ShadeTheme, type ThemeMode } from './theme.js';

export interface ShadeRuntimeContextValue {
  runtime: Shade;
  theme: ShadeTheme;
}

const ShadeRuntimeContext = createContext<ShadeRuntimeContextValue | null>(null);

export interface ShadeRuntimeProviderProps {
  /** Initialized `Shade` instance (after `await shade.initialize()`). */
  runtime: Shade;
  /** Theme mode: `'dark'` (default), `'light'`, or `'auto'`. */
  themeMode?: ThemeMode;
  /** Optional theme overrides applied on top of the resolved base theme. */
  themeOverrides?: Partial<ShadeTheme>;
  children: React.ReactNode;
}

/**
 * `ShadeRuntimeProvider` — root for the upload/download widget tree.
 *
 * Distinct from `ShadeProvider` (which targets the observer dashboard) —
 * this one wraps an actual `Shade` runtime so transfer hooks/components
 * can call `shade.upload(...)`, `shade.onIncomingTransfer(...)`, etc.
 *
 * Wrap your application root once; multiple uploaders/downloaders share
 * the same runtime instance.
 */
export function ShadeRuntimeProvider({
  runtime,
  themeMode = 'dark',
  themeOverrides,
  children,
}: ShadeRuntimeProviderProps): React.ReactElement {
  const value = useMemo<ShadeRuntimeContextValue>(
    () => ({ runtime, theme: { ...resolveTheme(themeMode), ...themeOverrides } }),
    [runtime, themeMode, themeOverrides],
  );
  return (
    <ShadeRuntimeContext.Provider value={value}>{children}</ShadeRuntimeContext.Provider>
  );
}

export function useShadeRuntime(): Shade {
  const ctx = useContext(ShadeRuntimeContext);
  if (ctx === null) {
    throw new Error(
      'useShadeRuntime must be used inside <ShadeRuntimeProvider runtime={shade}>',
    );
  }
  return ctx.runtime;
}

export function useShadeRuntimeTheme(): ShadeTheme {
  const ctx = useContext(ShadeRuntimeContext);
  if (ctx === null) {
    throw new Error(
      'useShadeRuntimeTheme must be used inside <ShadeRuntimeProvider runtime={shade}>',
    );
  }
  return ctx.theme;
}
