import { OnlineApiError, OnlineRepository, onlineRepository } from "./onlineRepository";

export type AccountResult =
  | { ok: true; username: string }
  | { ok: false; reason: "missing-credentials" | "account-exists" | "invalid-password" | "server-unavailable" | "invalid-request"; message?: string };

function failure(error: unknown): Extract<AccountResult, { ok: false }> {
  if (!(error instanceof OnlineApiError)) return { ok: false, reason: "server-unavailable" };
  if (error.status === 0 || error.status >= 500) return { ok: false, reason: "server-unavailable", message: error.message };
  if (error.status === 409) return { ok: false, reason: "account-exists", message: error.message };
  if (error.status === 401) return { ok: false, reason: "invalid-password", message: error.message };
  return { ok: false, reason: "invalid-request", message: error.message };
}

export class AccountRepository {
  constructor(private readonly online: OnlineRepository = onlineRepository) {}

  async create(username: string, password: string): Promise<AccountResult> {
    if (!username.trim() || !password) return { ok: false, reason: "missing-credentials" };
    try {
      const account = await this.online.register(username, password);
      return { ok: true, username: account.username };
    } catch (error) {
      return failure(error);
    }
  }

  async authenticate(username: string, password: string): Promise<AccountResult> {
    if (!username.trim() || !password) return { ok: false, reason: "missing-credentials" };
    try {
      const account = await this.online.login(username, password);
      return { ok: true, username: account.username };
    } catch (error) {
      return failure(error);
    }
  }

  session() { return this.online.session(); }
  logout() { return this.online.logout(); }
}
