/**
 * ActionState 信封 + 降级模式方案 B 工具.
 *
 * 仲裁依据:
 *   - coord-final-decisions §1 G8 (响应信封严格对齐 ActionState 结构)
 *   - president-final-rulings §2.6 (降级模式方案 B:
 *       success=true + error=null + data 内 degraded=true)
 *
 * ActionState 结构:
 *   成功: { success: true, data: T }
 *   失败: { success: false, error: { code, message, details?, traceId? } }
 *
 * 降级模式 (方案 B):
 *   {
 *     success: true,
 *     data: {
 *       ...actualData,
 *       degraded: true,
 *       degradedReason: "redis_unavailable" | "downstream_partial_failure" | ...,
 *       degradedFields: ["field1", "field2"]
 *     }
 *   }
 */
export interface ActionStateSuccess<T> {
  success: true;
  data: T;
  meta?: {
    traceId?: string;
    cachedAt?: string;
    degraded?: boolean;
    degradedReason?: string;
    degradedServices?: string[];
  };
}

export interface ActionStateError {
  success: false;
  error: {
    code: string;
    message: string;
    i18nKey?: string;
    details?: Record<string, unknown>;
    traceId?: string;
  };
}

export type ActionState<T> = ActionStateSuccess<T> | ActionStateError;

/**
 * 降级标记字段 (president §2.6 方案 B).
 * 业务 data 对象可包含此字段表示降级状态.
 */
export interface Degradable {
  degraded?: boolean;
  degradedReason?: string;
  degradedFields?: string[];
}

/**
 * 构造成功响应.
 */
export function ok<T>(
  data: T,
  meta?: ActionStateSuccess<T>["meta"],
): ActionStateSuccess<T> {
  return { success: true, data, meta };
}

/**
 * 构造失败响应.
 */
export function fail(
  code: string,
  message: string,
  options?: {
    details?: Record<string, unknown>;
    traceId?: string;
    i18nKey?: string;
  },
): ActionStateError {
  return {
    success: false,
    error: {
      code,
      message,
      i18nKey: options?.i18nKey,
      details: options?.details,
      traceId: options?.traceId,
    },
  };
}

/**
 * 构造降级响应 (方案 B).
 *
 * 下游部分失败但仍返回部分数据时使用:
 *   - success=true (HTTP 200)
 *   - data.degraded=true
 *   - data.degradedReason=原因
 *   - data.degradedFields=哪些字段降级了
 */
export function degraded<T extends object>(
  data: T,
  reason: string,
  degradedFields: string[],
  meta?: ActionStateSuccess<T>["meta"],
): ActionStateSuccess<T> {
  return ok(
    {
      ...data,
      degraded: true,
      degradedReason: reason,
      degradedFields,
    },
    { ...meta, degraded: true, degradedReason: reason },
  );
}

/**
 * 常用降级原因.
 */
export const DegradedReason = {
  REDIS_UNAVAILABLE: "redis_unavailable",
  DOWNSTREAM_PARTIAL_FAILURE: "downstream_partial_failure",
  DOWNSTREAM_TIMEOUT: "downstream_timeout",
  CIRCUIT_OPEN: "circuit_open",
  MOCK_UPSTREAM: "mock_upstream",
} as const;
