import { z } from "zod/v4";
import { fn } from "../utils/fn.js";
import { Actor } from "../actor.js";
import { Identifier } from "../id.js";
import { Examples } from "../examples.js";
import { eq, isNull, and } from "drizzle-orm";
import { Database } from "../drizzle/index.js";
import { Limitations, steamTable } from "./steam.sql.js";

export namespace Steam {
  export const Info = z
    .object({
      id: Identifier.schema("steam").meta({
        description: "The unique Steam ID of the account",
        example: Examples.SteamAccount.id,
      }),
      ownerID: z.string().meta({
        description:
          "The unique identifier of the user who owns this Steam account",
        example: Examples.SteamAccount.ownerID,
      }),
      name: z.string().meta({
        description: "The display name of the Steam account",
        example: Examples.SteamAccount.name,
      }),
      realName: z.string().nullable().meta({
        description: "The real name associated with the Steam account",
        example: Examples.SteamAccount.realName,
      }),
      memberSince: z.date().meta({
        description: "The date when the Steam account was created",
        example: Examples.SteamAccount.memberSince,
      }),
      avatarHash: z.string().meta({
        description: "The hash of the Steam account's avatar",
        example: Examples.SteamAccount.avatarHash,
      }),
      limitations: Limitations.meta({
        description: "Account limitations and restrictions",
        example: Examples.SteamAccount.limitations,
      }),
      profileUrl: z.string().nullable().meta({
        description: "The Steam community profile URL or identifier",
        example: Examples.SteamAccount.profileUrl,
      }),
      lastSyncedAt: z.date().meta({
        description: "The timestamp when the account was last synced",
        example: Examples.SteamAccount.lastSyncedAt,
      }),
    })
    .meta({
      ref: "SteamAccount",
      description: "Represents a Steam account entity",
      example: Examples.SteamAccount,
    });

  export type Info = z.infer<typeof Info>;

  export const fromID = fn(Info.shape.id, async (id) => {
    const userID = Actor.userID();

    return Database.use((tx) =>
      tx
        .select()
        .from(steamTable)
        .where(
          and(
            eq(steamTable.id, id),
            eq(steamTable.ownerID, userID),
            isNull(steamTable.timeDeleted),
          ),
        )
        .then((rows) => rows.map(serialize).at(0)),
    );
  });

  export function serialize(
    input: typeof steamTable.$inferSelect,
  ): z.infer<typeof Info> {
    return {
      id: input.id,
      name: input.name,
      ownerID: input.ownerID,
      realName: input.realName,
      profileUrl: input.profileUrl,
      memberSince: input.memberSince,
      avatarHash: input.avatarHash,
      limitations: input.limitations,
      lastSyncedAt: input.lastSyncedAt,
    };
  }
}
