/**
 * Mandu Contract Module
 * Contract-first API 정의 시스템
 *
 * Elysia DNA 패턴 채택:
 * - Contract → Handler 타입 자동 추론
 * - TypedContext로 요청 데이터 접근
 * - z.object({...}) 스키마 기반 검증
 */

export * from "./schema";
export * from "./types";
export * from "./validator";
export * from "./handler";
export * from "./client";
export * from "./normalize";
export * from "./registry";
export * from "./client-safe";
export * from "./protection";
export * from "./route-helpers";

// Phase 18.κ — tRPC-like typed RPC (see `./rpc.ts`).
export {
  defineRpc,
  registerRpc,
  getRpc,
  clearRpcRegistry,
  listRpcEndpoints,
  matchRpcPath,
  dispatchRpc,
  type RpcContext,
  type RpcProcedure,
  type RpcProcedureRecord,
  type RpcDefinition,
  type RpcClient,
  type RpcWireEnvelope,
  type RpcWireError,
} from "./rpc";

import type { ContractDefinition, ContractInstance } from "./schema";

import { defineHandler, defineRoute } from "./handler";
import { createClient, contractFetch } from "./client";
import { createClientContract } from "./client-safe";

/**
 * Create a Mandu API Contract
 *
 * Contract-first 방식으로 API 스키마를 정의합니다.
 * 정의된 스키마는 다음에 활용됩니다:
 * - TypeScript 타입 추론 (Slot에서 자동 완성)
 * - 런타임 요청/응답 검증
 * - OpenAPI 문서 자동 생성
 * - Guard의 Contract-Slot 일관성 검사
 *
 * @example
 * ```typescript
 * import { z } from "zod";
 * import { Mandu } from "@mandujs/core";
 *
 * const UserSchema = z.object({
 *   id: z.string().uuid(),
 *   email: z.string().email(),
 *   name: z.string().min(2),
 * });
 *
 * export default Mandu.contract({
 *   description: "사용자 관리 API",
 *   tags: ["users"],
 *
 *   request: {
 *     GET: {
 *       query: z.object({
 *         page: z.coerce.number().default(1),
 *         limit: z.coerce.number().default(10),
 *       }),
 *     },
 *     POST: {
 *       body: UserSchema.omit({ id: true }),
 *     },
 *   },
 *
 *   response: {
 *     200: z.object({ data: z.array(UserSchema) }),
 *     201: z.object({ data: UserSchema }),
 *     400: z.object({ error: z.string() }),
 *     404: z.object({ error: z.string() }),
 *   },
 * });
 * ```
 */
export function createContract<T extends ContractDefinition>(definition: T): T & ContractInstance {
  return {
    ...definition,
    _validated: false,
  };
}

/**
 * Mandu Namespace
 *
 * Contract-first API 개발을 위한 메인 인터페이스
 *
 * @example
 * ```typescript
 * import { Mandu } from "@mandujs/core";
 * import { z } from "zod";
 *
 * // 1. Contract 정의
 * const userContract = Mandu.contract({
 *   request: {
 *     GET: { query: z.object({ id: z.string() }) },
 *     POST: { body: z.object({ name: z.string(), email: z.string().email() }) },
 *   },
 *   response: {
 *     200: z.object({ user: z.object({ id: z.string(), name: z.string() }) }),
 *     201: z.object({ user: z.object({ id: z.string(), name: z.string() }) }),
 *   },
 * });
 *
 * // 2. Handler 정의 (타입 자동 추론)
 * const handlers = Mandu.handler(userContract, {
 *   GET: async (ctx) => {
 *     // ctx.query.id는 string 타입으로 자동 추론
 *     const user = await db.users.findUnique({ where: { id: ctx.query.id } });
 *     return { user };
 *   },
 *   POST: async (ctx) => {
 *     // ctx.body.name, ctx.body.email 자동 추론
 *     const user = await db.users.create({ data: ctx.body });
 *     return { user };
 *   },
 * });
 *
 * // 3. 또는 Route로 한 번에 정의
 * export default Mandu.route({
 *   contract: userContract,
 *   handler: handlers,
 * });
 * ```
 */
/**
 * Contract-specific Mandu functions
 * Note: Use `ManduContract` to avoid conflict with other Mandu exports
 */
export const ManduContract = {
  /**
   * Create a typed Contract
   * Contract 스키마 정의 및 타입 추론
   */
  contract: createContract,

  /**
   * Create typed handlers for a contract
   * Contract 기반 타입 안전 핸들러 정의
   *
   * @example
   * ```typescript
   * const handlers = Mandu.handler(contract, {
   *   GET: (ctx) => {
   *     // ctx.query, ctx.body, ctx.params 모두 타입 추론
   *     return { data: ctx.query.id };
   *   },
   * });
   * ```
   */
  handler: defineHandler,

  /**
   * Define a complete route with contract and handler
   * Contract와 Handler를 한 번에 정의
   *
   * @example
   * ```typescript
   * export default Mandu.route({
   *   contract: {
   *     request: { GET: { query: z.object({ id: z.string() }) } },
   *     response: { 200: z.object({ data: z.string() }) },
   *   },
   *   handler: {
   *     GET: (ctx) => ({ data: ctx.query.id }),
   *   },
   * });
   * ```
   */
  route: defineRoute,

  /**
   * Create a type-safe API client from contract
   * Contract 기반 타입 안전 클라이언트 생성
   *
   * @example
   * ```typescript
   * const client = Mandu.client(userContract, {
   *   baseUrl: "http://localhost:3000/api/users",
   * });
   *
   * // Type-safe API calls
   * const users = await client.GET({ query: { page: 1 } });
   * const newUser = await client.POST({ body: { name: "Alice" } });
   * ```
   */
  client: createClient,

  /**
   * Create a client-safe contract
   * Client에서 노출할 스키마만 선택
   */
  clientContract: createClientContract,

  /**
   * Single type-safe fetch call
   * 단일 타입 안전 fetch 호출
   *
   * @example
   * ```typescript
   * const result = await Mandu.fetch(contract, "GET", "/api/users", {
   *   query: { page: 1 },
   * });
   * ```
   */
  fetch: contractFetch,
} as const;

// Note: The unified `Mandu` namespace is defined in the main index.ts.
// ManduContract is available for direct import from this module.
