'use client'

// AUTO-GENERATED by mizan - do not edit manually
// Regenerate with: npm run schemas

// This file provides typed wrappers around the mizan library.
// - DjangoContext: Typed provider wrapping mizanProvider
// - Typed hooks: useAuthStatus(), useUser(), etc.

import { type ReactNode, useCallback } from 'react'
import {
  mizanProvider,
  usemizan,
  usemizanContext,
  usemizanCall,
  type mizanHydration,
  type Transport,
} from 'mizan'
import { ChannelProvider, ChannelConnection } from 'mizan/channels'
import { useRef } from 'react'

import type { addEmailSchemaOutput, addEmailValidateInput, addEmailValidateOutput, addInput, addOutput, buggyFnOutput, contactSchemaInput, contactSchemaOutput, contactSubmitOutput, contactValidateInput, contactValidateOutput, currentUserOutput, echoInput, echoOutput, greetInput, greetOutput, httpOnlyEchoInput, httpOnlyEchoOutput, itemFormsetSchemaInput, itemFormsetSchemaOutput, itemFormsetSubmitInput, itemFormsetSubmitOutput, itemFormsetValidateInput, itemFormsetValidateOutput, itemSchemaInput, itemSchemaOutput, itemSubmitOutput, itemValidateInput, itemValidateOutput, jwtObtainOutput, jwtRefreshInput, jwtRefreshOutput, loginSchemaOutput, loginSubmitInput, loginSubmitOutput, loginValidateInput, loginValidateOutput, multiplyInput, multiplyOutput, notImplementedFnOutput, permissionCheckFnInput, permissionCheckFnOutput, signupSchemaOutput, signupSubmitInput, signupSubmitOutput, signupValidateInput, signupValidateOutput, staffOnlyOutput, superuserOnlyOutput, verifiedOnlyOutput, whoamiOutput, wsWhoamiOutput } from './generated.mizan'

// ============================================================================
// Hydration Types
// ============================================================================

/** Typed hydration data for SSR */
export interface DjangoHydration {
  currentUser?: currentUserOutput
  greet?: greetOutput
}

/** Convert typed hydration to mizan format */
function tomizanHydration(hydration?: DjangoHydration): mizanHydration | undefined {
  if (!hydration) return undefined
  const result: mizanHydration = {}
  if (hydration.currentUser !== undefined) result['current_user'] = hydration.currentUser
  if (hydration.greet !== undefined) result['greet'] = hydration.greet
  return result
}

// ============================================================================
// Provider
// ============================================================================

export interface DjangoContextProps {
  children: ReactNode
  /** SSR hydration data */
  hydration?: DjangoHydration
  /** WebSocket URL for RPC calls (default: /ws/) */
  wsUrl?: string
  /** Base URL for HTTP fallback (default: /api/mizan) */
  baseUrl?: string
}

/**
 * Typed Django context provider.
 *
 * Wraps mizanProvider with:
 * - Typed hydration
 * - Auto-fetch for registered contexts
 *
 * Usage:
 *   <DjangoContext hydration={hydration}>
 *     <App />
 *   </DjangoContext>
 */
export function DjangoContext({
  children,
  hydration,
  wsUrl,
  baseUrl,
}: DjangoContextProps) {
  const connectionRef = useRef<ChannelConnection | null>(null)
  if (!connectionRef.current) {
    connectionRef.current = new ChannelConnection({ url: wsUrl || '/ws/' })
  }

  return (
    <mizanProvider
      hydration={tomizanHydration(hydration)}
      contexts={['current_user', 'greet']}
      wsUrl={wsUrl}
      baseUrl={baseUrl}
      connection={connectionRef.current}
    >
      <ChannelProvider connection={connectionRef.current} autoConnect={true}>
        {children}
      </ChannelProvider>
    </mizanProvider>
  )
}

// ============================================================================
// Context Hooks (typed wrappers)
// ============================================================================

/**
 * Get current_user context data.
 * @throws if context not loaded yet
 */
export function useCurrentUser(): currentUserOutput {
  const data = usemizanContext<currentUserOutput>('current_user')
  if (data === undefined) {
    throw new Error('useCurrentUser: context not loaded yet')
  }
  return data
}

/**
 * Get greet context data.
 * @throws if context not loaded yet
 */
export function useGreet(): greetOutput {
  const data = usemizanContext<greetOutput>('greet')
  if (data === undefined) {
    throw new Error('useGreet: context not loaded yet')
  }
  return data
}

/**
 * Get context refresh functions without subscribing to data changes.
 * Use this in components that only need to trigger refreshes.
 */
export function useDjangoRefresh() {
  const { refreshContext, refreshAllContexts } = usemizan()
  return {
    refreshCurrentUser: () => refreshContext('current_user'),
    refreshGreet: () => refreshContext('greet'),
    refreshAll: refreshAllContexts,
  }
}

// ============================================================================
// Function Hooks (typed wrappers)
// ============================================================================

/**
 * Call echo server function.
 * Transport: websocket
 */
export function useEcho() {
  return usemizanCall<echoInput, echoOutput>('echo', 'websocket')
}

/**
 * Call add server function.
 * Transport: websocket
 */
export function useAdd() {
  return usemizanCall<addInput, addOutput>('add', 'websocket')
}

/**
 * Call whoami server function.
 * Transport: http
 */
export function useWhoami() {
  return usemizanCall<void, whoamiOutput>('whoami', 'http')
}

/**
 * Call http_only_echo server function.
 * Transport: http
 */
export function useHttpOnlyEcho() {
  return usemizanCall<httpOnlyEchoInput, httpOnlyEchoOutput>('http_only_echo', 'http')
}

/**
 * Call staff_only server function.
 * Transport: http
 */
export function useStaffOnly() {
  return usemizanCall<void, staffOnlyOutput>('staff_only', 'http')
}

/**
 * Call superuser_only server function.
 * Transport: http
 */
export function useSuperuserOnly() {
  return usemizanCall<void, superuserOnlyOutput>('superuser_only', 'http')
}

/**
 * Call verified_only server function.
 * Transport: http
 */
export function useVerifiedOnly() {
  return usemizanCall<void, verifiedOnlyOutput>('verified_only', 'http')
}

/**
 * Call multiply server function.
 * Transport: http
 */
export function useMultiply() {
  return usemizanCall<multiplyInput, multiplyOutput>('multiply', 'http')
}

/**
 * Call not_implemented_fn server function.
 * Transport: http
 */
export function useNotImplementedFn() {
  return usemizanCall<void, notImplementedFnOutput>('not_implemented_fn', 'http')
}

/**
 * Call buggy_fn server function.
 * Transport: http
 */
export function useBuggyFn() {
  return usemizanCall<void, buggyFnOutput>('buggy_fn', 'http')
}

/**
 * Call permission_check_fn server function.
 * Transport: http
 */
export function usePermissionCheckFn() {
  return usemizanCall<permissionCheckFnInput, permissionCheckFnOutput>('permission_check_fn', 'http')
}

/**
 * Call ws_whoami server function.
 * Transport: websocket
 */
export function useWsWhoami() {
  return usemizanCall<void, wsWhoamiOutput>('ws_whoami', 'websocket')
}

/**
 * Call jwt_obtain server function.
 * Transport: http
 */
export function useJwtObtain() {
  return usemizanCall<void, jwtObtainOutput>('jwt_obtain', 'http')
}

/**
 * Call jwt_refresh server function.
 * Transport: http
 */
export function useJwtRefresh() {
  return usemizanCall<jwtRefreshInput, jwtRefreshOutput>('jwt_refresh', 'http')
}

// ============================================================================
// Re-exports from mizan library
// ============================================================================

export { usemizan, usemizanStatus, usePush, DjangoError } from 'mizan'
export type { ConnectionStatus, PushMessage, PushListener } from 'mizan'
