declare module "@mathieuc/tradingview" {
  export type SendPacket = (
    t: string,
    p: [string, ...(string | number)[]]
  ) => Promise<void>;
  export interface User {
    id: number;
    username: string;
    firstName: string;
    lastName: string;
    reputation: number;
    following: number;
    followers: number;
    notifications: {
      user: number;
      following: number;
    };
    session: string;
    sessionHash: string;
    signature: string;
    privateChannel: string;
    authToken: string;
    joinDate: Date;
  }

  export interface Period {
    // Period type definition
    time: number;
    open: number;
    high: number;
    low: number;
    close: number;
    volume?: number;
  }

  export interface Periods {
    "1": Period[];
    "5": Period[];
    "15": Period[];
    "30": Period[];
    "60": Period[];
    "240": Period[];
    D: Period[];
    W: Period[];
    M: Period[];
  }

  export interface SearchResult {
    id: string;
    exchange: string;
    fullExchange: string;
    symbol: string;
    description: string;
    type: string;
    getTA: () => Promise<Periods>;
  }

  export interface IndicatorResult {
    id: string;
    version: string;
    name: string;
    author: {
      id: number;
      username: string;
    };
    image: string;
    source: string | "";
    type: "study" | "strategy";
    access:
      | "open_source"
      | "closed_source"
      | "invite_only"
      | "private"
      | "other";
    get: () => Promise<any>;
  }

  export class Client {
    constructor(options?: {
      token?: string;
      signature?: string;
      datafeed?: boolean;
    });
    Session: {
      Chart: typeof ChartSession;
      Quote: typeof QuoteSession;
    };
    end(): void;
    send: SendPacket;
  }

  export class ChartSession {
    constructor();
    chartSessionID: string;
    replaySessionID: string;
    client: Client;
    onUpdate(callback: (data: any) => void): void;
    onError(callback: (error: any) => void): void;
    on(event: string, callback: (data: any) => void): void;
  }

  export class QuoteSession {
    constructor();
  }

  export class BuiltInIndicator {
    constructor(type: string, data?: any, name?: string);
    type: string;
    data: any;
    name: string;
  }

  export class PineIndicator {
    constructor(id: string, version: string, data?: any);
    id: string;
    version: string;
    data: any;
  }

  export class PinePermManager {
    constructor(session: string, signature?: string);
    session: string;
    signature: string;
  }

  export function getTA(id: string): Promise<Periods>;
  export function searchMarket(
    search: string,
    filter?:
      | "stock"
      | "futures"
      | "forex"
      | "cfd"
      | "crypto"
      | "index"
      | "economic"
  ): Promise<SearchResult[]>;
  export function searchMarketV3(
    search: string,
    filter?:
      | "stock"
      | "futures"
      | "forex"
      | "cfd"
      | "crypto"
      | "index"
      | "economic"
  ): Promise<SearchResult[]>;
  export function searchIndicator(search?: string): Promise<IndicatorResult[]>;
  export function getIndicator(
    id: string,
    version?: "last" | string,
    session?: string,
    signature?: string
  ): Promise<PineIndicator>;
  export function loginUser(
    username: string,
    password: string,
    remember?: boolean,
    UA?: string
  ): Promise<User>;
  export function getUser(
    session: string,
    signature?: string,
    location?: string
  ): Promise<User>;
  export function getPrivateIndicators(
    session: string,
    signature?: string
  ): Promise<IndicatorResult[]>;
  export function getChartToken(
    layout: string,
    credentials?: { id: number; session: string; signature?: string }
  ): Promise<string>;
  export function getDrawings(
    layout: string,
    symbol?: string,
    credentials?: { id: number; session: string; signature?: string },
    chartID?: number
  ): Promise<any[]>;

  const _default: {
    Client: typeof Client;
    BuiltInIndicator: typeof BuiltInIndicator;
    PineIndicator: typeof PineIndicator;
    PinePermManager: typeof PinePermManager;
    getTA: typeof getTA;
    searchMarket: typeof searchMarket;
    searchMarketV3: typeof searchMarketV3;
    searchIndicator: typeof searchIndicator;
    getIndicator: typeof getIndicator;
    loginUser: typeof loginUser;
    getUser: typeof getUser;
    getPrivateIndicators: typeof getPrivateIndicators;
    getChartToken: typeof getChartToken;
    getDrawings: typeof getDrawings;
  };
  export default _default;
}
