import { BigNumberish } from "ethers";

export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;

export type Scalars = {
  ID: string;
  String: string;
  Boolean: boolean;
  Int: number;
  Float: number;
  DateTime: any;
  JSON: any;
};

export enum SortOrderEnum {
  Asc = "ASC",
  Desc = "DESC",
}

export type PaginationConfig = {
  page_number?: InputMaybe<Scalars["Float"]>;
  page_size?: InputMaybe<Scalars["Float"]>;
};

export type OrderConfig = {
  field_name: Scalars["String"];
  sort_order: SortOrderEnum;
};

export type Result<T, E = Error> =
  | { success: true; value: T }
  | { success: false; error: E };

export type TransactionHash = string;

export interface Buy {
  transactionHash: string;
  price: number;
}

export interface Sale {
  transactionHash: string;
  price: number;
  fee: number;
}

export interface Listing {
  price: Price;
  is_royalties_enabled: boolean;
  data: Data;
}

interface Price {
  display_price: number;
  display_price_without_royalties: number;
  raw_price: number;
  royalties: number;
  optional_royalties: number;
}

interface Data {
  project_id: string;
  token_address: string;
  name: string;
  supply: number;
  metadata_img: string;
  metadata_uri: string;
  animation_url: string;
  attributes: Attributes;
  nft_standard: string;
  token_type: string;
  creator_royalty: number;
  floor_price: number;
  floor_price_1day_change: number;
  feeless_floor_price: number;
  project_name: string;
  project_image: string;
  project_supply: number;
  project_metadata: ProjectMetadata;
  is_project_verified: boolean;
  project_slug: string;
  project_description: string;
  project_protocol: string;
  owner: string;
  marketplace_state: string;
  listing_snapshot: ListingSnapshot;
  bid_snapshot: BidSnapshot;
  last_sale_snapshot: any; // TODO: `LastSaleSnapshot` type.
  rarity_snapshot: RaritySnapshot;
  non_marketplace_state: any; // TODO: `NonMarketplaceState` type.
  created_at: number;
  updated_at: number;
}

// TODO: Update this to use specific types.
interface Attributes {
  Hair: any;
  Mask: any;
  Skin: any;
  Special: any;
  Clothing: any;
  Background: any;
}

// TODO: Check if this types are accurate.
interface ProjectMetadata {
  transfer_policy_id: string;
  allow_list_id: string;
  royalty_strategy_id: string;
  orderbook_id: string;
  token_type: string;
  withdraw_policy_id: string;
  minimum_royalty: string;
  contract_address: string;
}

interface ListingSnapshot {
  project_id: string;
  token_address: string;
  seller_address: string;
  program_id: string;
  program_instance_id: string;
  amount: number;
  price: number;
  display_price: number; // TODO: This has to be a float.
  listing_type: string;
  tx_id: string;
  escrow_address: string;
  fee: number;
  seller_referral_address: string;
  seller_referral_fee: number;
  program_fee_address: string;
  metadata: any; // TODO: `Metadata` type.
  marketplace_config: any; // TODO: `MarketplaceConfig` type.
  currency_price: BigNumberish;
  decimal: number;
  currency: string;
  expiry_time: number;
  block_timestamp: number;
  block_number: number;
  created_at: number;
  updated_at: number;
}

interface BidSnapshot {
  project_id: string;
  token_address: string;
  buyer_address: string;
  program_id: string;
  program_instance_id: string;
  amount: number;
  price: number;
  display_price: number; // TODO: This has to be a float.
  tx_id: string;
  escrow_address: string;
  fee: number;
  buyer_referral_address: string;
  buyer_referral_fee: number;
  program_fee_address: string;
  metadata: any; // TODO: `Metadata` type.
  currency_price: BigNumberish;
  decimal: number;
  currency: string;
  expiry_time: number;
  block_timestamp: number;
  block_number: number;
  created_at: number;
  updated_at: number;
}

interface RaritySnapshot {
  project_id: string;
  token_address: string;
  hyperspace: number;
}

export interface CollectionBid {
  identifier_key: string;
  identifier_type: string;
  identifier_index: number;
  trade_state: string;
  instruction_index: any; // TODO: `InstructionIndex` type.
  type: string; // TODO: Enum type.
  block_number: number;
  tx_id: string;
  block_timestamp: number;
  seller_address: string;
  buyer_address: string;
  fee_address: string;
  program_id: string;
  program_instance_id: string;
  price: number;
  display_price: number;
  fee: number;
  amount: number;
  seller_referral_address: string;
  seller_referral_fee: number;
  buyer_referral_address: string;
  buyer_referral_fee: number;
  metadata: CollectionBidMetadata;
  currency_price: BigNumberish;
  decimal: number;
  currency: string;
  expiration: any; // TODO: `Expiration` type.
  expiry_time: number;
  created_at: string;
  updated_at: string;
  protocol: any; // TODO: `Protocol` type.
}

export interface CollectionBidMetadata {
  event_log: EventLog;
  is_offchain: boolean;
  raw_total_price: string;
}

interface EventLog {
  fees: any; // TODO: `Fee[]` type.
  maker: string;
  nonce: string;
  taker: string;
  expiry: string;
  direction: number;
  signature: any; // TODO: `Signature` type.
  erc20Token: string;
  erc721Token: string;
  rawSignature: string;
  erc721TokenId: string;
  erc20TokenAmount: string;
  erc721TokenProperties: any; // TODO: `Erc721TokenProperty[]` type.
}

// direction: 1,
//     maker: '0x8cdd7a500f21455361cf1c2e01c0525ce92481b2',
//     taker: '0x0000000000000000000000000000000000000000',
//     expiry: '2524604400',
//     nonce: '100131415900000000000000000000000000000219409817343000727143006819376437804085',
//     erc20Token: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7',
//     erc20TokenAmount: '1500000000000000000',
//     fees: [ [Object], [Object] ],
//     erc721Token: '0x54c800d2331e10467143911aabca092d68bf4166',
//     erc721TokenId: '0',
//     erc721TokenProperties: [ [Object] ]

export interface Order {
  direction: number;
  maker: string;
  taker: string;
  expiry: string;
  nonce: string;
  erc20Token: string;
  erc20TokenAmount: string;
  fees: any; // TODO: `Fee[]` type.
  erc721Token: string;
  erc721TokenId: string;
  erc721TokenProperties: any; // TODO: `Erc721TokenProperty[]` type.
}

// {
//   project_id: '260c3b22-1c12-4cab-9811-c78f29af58c2',
//   token_address: '0xa09477b44cff7b525436364a0da4e870bc9e052c_1096',
//   name: '1096',
//   supply: 1,
//   metadata_img: 'https://f7c3325c363bfab1f462ba96c718e2a4.ipfscdn.io/ipfs/bafybeibbfcvizwze4kp2ouhxsw5jfk7bnfgo6vich25liskvl2zo2ak24u/532.GIF',
//   metadata_uri: '',
//   animation_url: null,
//   attributes: [Object],
//   nft_standard: 'ERC721',
//   token_type: null,
//   creator_royalty: null,
//   floor_price: 5.18,
//   floor_price_1day_change: -0.0115,
//   feeless_floor_price: 5.053658537,
//   project_name: 'Ripperz',
//   project_image: 'https://beta.api.solanalysis.com/images/800x800/filters:frames(,0)/https://f7c3325c363bfab1f462ba96c718e2a4.ipfscdn.io/ipfs/bafybeibbfcvizwze4kp2ouhxsw5jfk7bnfgo6vich25liskvl2zo2ak24u/1830.GIF',
//   project_supply: 2000,
//   project_metadata: [Object],
//   is_project_verified: true,
//   project_slug: 'ripperz',
//   project_description: null,
//   project_protocol: 'AVAX',
//   owner: '0x8cdd7a500f21455361cf1c2e01c0525ce92481b2',
//   marketplace_state: null,
//   listing_snapshot: [Object],
//   bid_snapshot: [Object],
//   last_sale_snapshot: null,
//   rarity_snapshot: [Object],
//   non_marketplace_state: null,
//   created_at: null,
//   updated_at: null
// },

export interface Nft {
  project_id: string;
  token_address: string;
  name: string;
  supply: number;
  metadata_img: string;
  metadata_uri: string;
  animation_url: string;
  attributes: any; // TODO: `Attributes` type.
  nft_standard: string;
  token_type: string;
  creator_royalty: number;
  floor_price: number;
  floor_price_1day_change: number;
  feeless_floor_price: number;
  project_name: string;
  project_image: string;
  project_supply: number;
  project_metadata: any; // TODO: `ProjectMetadata` type.
  is_project_verified: boolean;
  project_slug: string;
  project_description: string;
  project_protocol: string;
  owner: string;
  marketplace_state: any; // TODO: `MarketplaceState` type.
  listing_snapshot: ListingSnapshot;
  bid_snapshot: any; // TODO: `BidSnapshot` type.
  last_sale_snapshot: any; // TODO: `LastSaleSnapshot` type.
  rarity_snapshot: RaritySnapshot;
  non_marketplace_state: any; // TODO: `NonMarketplaceState` type.
  created_at: number;
  updated_at: number;
}

export interface ProjectStats {
  project_id: string;
  project: Project;
  market_cap: number;
  volume: number;
  volume_7day: number;
  volume_1day: number;
  volume_1hr: number;
  volume_1day_change: number;
  volume_7day_change: number;
  raw_market_cap: number;
  raw_volume: number;
  raw_volume_7day: number;
  raw_volume_1day: number;
  raw_volume_1hr: number;
  raw_volume_1day_change: number;
  raw_volume_7day_change: number;
  feeless_floor_price: number;
  floor_price: number;
  floor_price_1day_change: number;
  average_price: number;
  average_price_1day_change: number;
  average_price_7day_change: number;
  max_price: number;
  twitter_followers: number;
  discord_members: number;
  supply: number;
  num_of_token_holders: number;
  num_of_token_listed: number;
  percentage_of_token_listed: number;
  rank: number;
  volume_1m: number;
  volume_5m: number;
  volume_15m: number;
  volume_30m: number;
  created_at: string;
  updated_at: string;
}

export interface Project {
  project_id: string;
  contract_address: string;
  protocol: string;
  is_verified: boolean;
  is_trading_enabled: boolean;
  is_trading_disabled: boolean;
  twitter: string;
  discord: string;
  rarities: any; // TODO: `Rarity[]` type.
  website: string;
  display_name: string;
  supply: number;
  description: string;
  short_description: string;
  img_url: string;
  banner_url: string;
  launch_date: string;
  launch_timestamp: string;
  project_attributes: any; // TODO: `ProjectAttribute[]` type.
  project_slug: string;
  token_type: string;
  royalty: number;
  minimum_royalty: number;
  display_id: string;
  transfer_policy_id: string;
  withdraw_policy_id: string;
  orderbook_id: string;
  allow_list_id: string;
  royalty_strategy_id: string;
  metadata: any; // TODO: `Metadata` type.
  is_launchpad: boolean;
  launchpad_details: any; // TODO: `LaunchpadDetails` type.
  project_identifiers: any; // TODO: `ProjectIdentifier[]` type.
  rewards_earning: boolean;
  created_at: string;
  updated_at: string;
}
