import type {TableInstance, UsePaginationInstanceProps, UsePaginationState, UseSortByInstanceProps,} from 'react-table'
import type {Edge, Node} from 'reactflow'

import type {
    Account,
    AccountType,
    Backtest,
    Balance,
    BotType,
    Candle,
    FlowOutput,
    FlowType,
    IFlow,
    KeyValuePairOfDateTimeAndDecimal,
    MoneyManagement,
    PerformanceMetrics,
    Position,
    RiskLevel,
    Scenario,
    Signal,
    StrategiesResultBase,
    StrategyType,
    Ticker,
    Timeframe,
    TradeDirection,
    TradingBot,
    TradingExchanges
} from '../generated/ManagingApi'
import {FC, ReactNode} from 'react'

export type TabsType = {
  label: string
  index: number
  Component: React.FC<{}>
}[]

export type TableInstanceWithHooks<T extends object> = TableInstance<T> &
  UsePaginationInstanceProps<T> &
  UseSortByInstanceProps<T> & {
    state: UsePaginationState<T>
  }

export type IWidgetProperties = {
  id: string
  title: string
  layout: {
    h: number
    i: string
    w: number
    x: number
    y: number
    minW: number
    minH: number
  }
}

export type IFlowData = {
  name: string
  type: string
}

export type IFlowItem = {
  data: IFlow
  isConnectable: boolean
  id: string
  position: any
  type: FlowType
}

export type IFlowProps = {
  name: string
  description?: string
  children: React.ReactNode
  inputs: FlowOutput[]
  outputs: FlowOutput[]
  isConnectable: boolean
}

export type IWorkflow = {
  name: string
  nodes: Node<IFlow>[]
  edges: Edge[]
}

export type ILoginFormInput = {
  name: string
}

export type BacktestModalProps = {
  showModal: boolean
  closeModal: () => void
  setBacktests: React.Dispatch<React.SetStateAction<Backtest[]>>
  showLoopSlider?: boolean
}

export type ISpotlightBadge = {
  direction: TradeDirection | undefined
  date?: Date | undefined
  price?: number | undefined
}

export type IBacktestsFormInput = {
  accountName: string
  tickers: string[]
  botType: BotType
  timeframe: Timeframe
  scenarioName: string
  save: boolean
  balance: number
  moneyManagement: MoneyManagement
  loop: number
  startDate: string
  endDate: string
}

export type  IBacktestCards = {
  list: Backtest[] | undefined
  isFetching?: boolean
  setBacktests: React.Dispatch<React.SetStateAction<Backtest[]>>
}

export type  IFormInput = {
  children: React.ReactNode
  htmlFor: string
  label: string
  inline?: boolean
}

export type  IModalProps = {
  showModal?: boolean | undefined
  onSubmit?: React.FormEventHandler
  onClose?: React.FormEventHandler
  titleHeader?: string
  children?: React.ReactNode
  toggleModal?: React.MouseEventHandler<HTMLButtonElement>
  moneyManagement?: MoneyManagement
}

export type  IMoneyManagementModalProps = {
  showModal?: boolean | undefined
  onSubmit?: React.FormEventHandler
  onClose: () => void
  toggleModal?: React.MouseEventHandler<HTMLButtonElement>
  moneyManagement?: MoneyManagement
  disableInputs?: boolean
}
export type  IBotRowDetails = {
  candles: Candle[]
  positions: Position[]
  walletBalances?: KeyValuePairOfDateTimeAndDecimal[] | null
  strategiesValues?: { [key in keyof typeof StrategyType]?: StrategiesResultBase; } | null;
  signals: Signal[]
  optimizedMoneyManagement: MoneyManagement
  statistics: PerformanceMetrics
  moneyManagement: MoneyManagement
}

export type  IBacktestFormInput = {
  accountName: string
  botType: BotType
  ticker: Ticker
  timeframe: Timeframe
  save: boolean
  scenarioName: string
  balance: number
  moneyManagement: MoneyManagement
  startDate: string
  endDate: string
}

export type  IOpenPositionFormInput = {
  accountName: string
  direction: TradeDirection
  ticker: Ticker
  riskLevel: RiskLevel
  stopLoss?: number
  takeProfit?: number
}

export type  IBotList = {
  list: TradingBot[]
}
export type  IScenarioFormInput = {
  name: string
  strategies: string[]
  loopbackPeriod: number | undefined
}
export type  IScenarioList = {
  list: Scenario[]
}

export type  IMoneyManagementList = {
  list: MoneyManagement[]
}

export type  IMoneyManagementFormInput = {
  timeframe: Timeframe
  riskLevel: RiskLevel
  balanceAtRisk: number
  stopLoss: number
  takeProfit: number
  leverage: number
  name: string
}
export type  IAccountFormInput = {
  name: string
  key: string
  secret: string
  exchange: TradingExchanges
  type: AccountType
}

export type  IAccountBalanceProps = {
  bots: TradingBot[]
  accounts: Account[]
}

export type  IPropsComponent = {
  disabled?: boolean | undefined
  children?: React.ReactNode
  value?: string | number
  href?: string
  as?: 'navlink' | 'link' | 'newtab'
  className?: string | ((prop: { isActive: boolean }) => string)
  onClick?: () => void
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
  id: string
  min?: string
  max?: string
  step?: string
  prefixValue?: string
  suffixValue?: string
}

export type  IListProp = {
  children: React.ReactNode
  className?: string
}

export type  IMyLinkProps = {
  href: string
  children: React.ReactNode
  as?: 'navlink' | 'link' | 'newtab'
  className?: string | ((prop: { isActive: boolean }) => string)
  onClick?: () => void
}

export type  ICardText = {
  title: string
  content: string
}

export type  ICardPosition = {
  positions: Position[]
  positivePosition: boolean
}

export type  ICardSignal = {
  signals: Signal[]
}

export type  INavItemProps = {
  children: ReactNode
  href: string
  isMobile?: boolean
}

export type  IStatusBadge = {
  status: string
  isForWatchOnly: boolean
}

export type  ITabsProps = {
  tabs: ITabsType | undefined
  selectedTab: number
  onClick: (index: number) => void
  orientation?: 'horizontal' | 'vertical'
  className?: string
  addButton?: boolean
  onAddButton?: () => void
}

export type ITabsType = {
  label: string
  index: number
  Component: FC<{ index: number }>
  props?: any
}[]

export type ICardPositionFlipped = {
  positions: Position[]
}

export type IAccountRowDetail = {
  balances: Balance[]
  showTotal?: boolean
}

export type IGridTile = {
  children: any
  title: string
}

export type CardProps = {
  name: string
  children: React.ReactNode
  info?: string
  showCloseButton?: boolean
}

export type AccountStore = {
  setAccounts: (accounts: Account[]) => void
  accounts: Account[]
}

export type ILoader = {
  size?: 'xs' | 'sm' | 'md' | 'lg'
}