/**
 * User 状态机：Actors（异步服务）
 *
 * 从 `user-machine.ts` 抽出的"Actors"段：
 *   - `userInitActor`（fromPromise：读 UserStorage 并行 user + avatarUrl）
 *   - `userFetchActor`（fromPromise：调 API + 持久化到本地）
 *   - `userLogoutActor`（fromPromise：auth logout + 清本地数据）
 *
 * 设计：
 *   - 依赖 `user-machine.helpers.ts`（toView, readInitData, userStorage）
 *   - 仓库以接口类型注入（调用面只看接口，运行时仍是同一单例）
 *   - 命名约定：`[user-machine]` 前缀日志（如未来加）—— 与 chat 模块对齐
 */

import { fromPromise } from "xstate";

import type { UserView } from "@/data/dto/user";
import { userRepository } from "@/data/repositories/user_repository";
import { authRepository } from "@/data/repositories/auth_repository";
import type {
  IAuthRepository,
  IUserRepository,
} from "@/data/repositories/interfaces";
import { Result } from "@/utils";

import { type InitData, readInitData, toView, userStorage } from "./user-machine.helpers";

// ============================================================
// 仓库注入
// ============================================================
// 仓库以接口类型注入：调用面只看接口，运行时仍是同一单例
const userRepo: IUserRepository = userRepository;
const authRepo: IAuthRepository = authRepository;

// ============================================================
// Init actor：从 UserStorage 读 user + avatarUrl
// ============================================================
/**
 * 读本地 user + avatarUrl（并行）。
 * - 失败/无数据 → 返回 null，不抛错（machine 走 onDone 回到 idle，context 是 null）
 * - onDone 赋 currentUser + avatarUrl 到 context
 */
export const userInitActor = fromPromise<InitData>(async () => readInitData());

// ============================================================
// Fetch actor：调 API 拉当前用户 + 持久化
// ============================================================
/**
 * 调 `userRepo.getCurrentUser` 拉当前 user：
 * - 成功 → 转 UserView + 写本地（userStorage.setUser）→ 返回 View
 * - 失败 → 返回 null（machine 走 onDone，context 保持不变；onError 兜底）
 */
export const userFetchActor = fromPromise<UserView | null>(async () => {
  const result = await userRepo.getCurrentUser();
  if (Result.isErr(result)) return null;
  const view = toView(result.data.toJson());
  // 持久化到本地
  await userStorage.setUser(result.data.toJson());
  return view;
});

// ============================================================
// Logout actor：后端登出 + 清本地用户数据
// ============================================================
/**
 * 登出：
 * - 调 `authRepo.logout` 让后端吊销 token
 * - `userStorage.clearUserData` 清本地 user / avatar 等
 * - onDone / onError 都跑 `clearUser` action（machine 层）—— 失败也清本地
 */
export const userLogoutActor = fromPromise<void>(async () => {
  await authRepo.logout();
});
