import type { BybitClient } from "./client.js";

/**
 * Métodos tipados da Bybit P2P Open API (v5). Tipos de resposta PARCIAIS de
 * propósito (`[extra]: unknown`): rodar contra a API real e completar com o
 * JSON que volta.
 *
 * Endpoints (do SDK oficial bybit_p2p):
 *   ads:    item/online, item/create, item/update, item/cancel,
 *           item/personal/list, item/info
 *   orders: order/simplifyList, order/info, order/pending/simplifyList,
 *           order/pay, order/finish
 *   chat:   order/message/send, order/message/listpage
 *   user:   user/personal/info, user/order/personal/info, user/payment/list
 */

/** "0" = compra (BUY) | "1" = venda (SELL) — lado da Bybit (confirmar). */
export type BybitSide = "0" | "1";

export interface BybitOnlineAdsReq {
  tokenId: string; // asset, ex: USDT
  currencyId: string; // fiat, ex: BRL
  side: BybitSide;
  page?: string;
  size?: string;
  payment?: string[];
  amount?: string;
}

export interface BybitAdItem {
  id: string;
  accountId?: string;
  nickName?: string;
  userId?: string;
  price: string;
  tokenId: string;
  currencyId: string;
  side: number;
  quantity?: string;
  lastQuantity?: string;
  minAmount?: string;
  maxAmount?: string;
  payments?: string[];
  finishNum?: number;
  recentExecuteRate?: number;
  [extra: string]: unknown;
}

export interface BybitPage<T> {
  count?: number;
  items: T[];
  [extra: string]: unknown;
}

export interface BybitOrderItem {
  id: string;
  itemId?: string;
  side: number;
  tokenId: string;
  currencyId: string;
  amount?: string;
  quantity?: string;
  price?: string;
  status?: number;
  buyerRealName?: string;
  sellerRealName?: string;
  targetNickName?: string;
  targetUserId?: string;
  createDate?: string;
  [extra: string]: unknown;
}

export interface BybitChatMessage {
  id?: string;
  msgUuid?: string;
  message?: string;
  msgType?: number;
  userId?: string;
  orderId?: string;
  createDate?: string;
  contentType?: string;
  [extra: string]: unknown;
}

export class BybitP2PApi {
  constructor(private readonly c: BybitClient) {}

  /* ---- Anúncios ---- */

  onlineAds(req: BybitOnlineAdsReq) {
    return this.c.request<BybitPage<BybitAdItem>>({
      method: "POST",
      path: "/v5/p2p/item/online",
      params: req,
    });
  }

  myAds(req: { page?: string; size?: string } = {}) {
    return this.c.request<BybitPage<BybitAdItem>>({
      method: "POST",
      path: "/v5/p2p/item/personal/list",
      params: req,
    });
  }

  adInfo(itemId: string) {
    return this.c.request<BybitAdItem>({
      method: "POST",
      path: "/v5/p2p/item/info",
      params: { itemId },
    });
  }

  updateAd(params: Record<string, unknown>) {
    return this.c.request<unknown>({
      method: "POST",
      path: "/v5/p2p/item/update",
      params,
    });
  }

  createAd(params: Record<string, unknown>) {
    return this.c.request<unknown>({
      method: "POST",
      path: "/v5/p2p/item/create",
      params,
    });
  }

  cancelAd(itemId: string) {
    return this.c.request<unknown>({
      method: "POST",
      path: "/v5/p2p/item/cancel",
      params: { itemId },
    });
  }

  /* ---- Ordens ---- */

  orders(req: { page?: string; size?: string; status?: number } = {}) {
    return this.c.request<BybitPage<BybitOrderItem>>({
      method: "POST",
      path: "/v5/p2p/order/simplifyList",
      params: req,
    });
  }

  pendingOrders(req: { page?: string; size?: string } = {}) {
    return this.c.request<BybitPage<BybitOrderItem>>({
      method: "POST",
      path: "/v5/p2p/order/pending/simplifyList",
      params: req,
    });
  }

  orderInfo(orderId: string) {
    return this.c.request<BybitOrderItem>({
      method: "POST",
      path: "/v5/p2p/order/info",
      params: { orderId },
    });
  }

  markPaid(params: { orderId: string; paymentType?: string; paymentId?: string }) {
    return this.c.request<unknown>({
      method: "POST",
      path: "/v5/p2p/order/pay",
      params,
    });
  }

  release(orderId: string) {
    return this.c.request<unknown>({
      method: "POST",
      path: "/v5/p2p/order/finish",
      params: { orderId },
    });
  }

  /* ---- Chat ---- */

  chatMessages(req: { orderId: string; page?: string; size?: string }) {
    return this.c.request<BybitPage<BybitChatMessage>>({
      method: "POST",
      path: "/v5/p2p/order/message/listpage",
      params: req,
    });
  }

  sendMessage(params: { orderId: string; message: string; contentType?: string; msgUuid?: string }) {
    return this.c.request<unknown>({
      method: "POST",
      path: "/v5/p2p/order/message/send",
      params,
    });
  }

  /* ---- Usuário ---- */

  accountInfo() {
    return this.c.request<Record<string, unknown>>({
      method: "POST",
      path: "/v5/p2p/user/personal/info",
      params: {},
    });
  }

  paymentTypes() {
    return this.c.request<unknown>({
      method: "POST",
      path: "/v5/p2p/user/payment/list",
      params: {},
    });
  }
}
