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

import type {
    Account,
    AccountType,
    Backtest,
    Balance,
    IndicatorViewModel,
    LightSignal,
    MoneyManagement,
    Position,
    RiskLevel,
    ScenarioViewModel,
    Ticker,
    Timeframe,
    TradeDirection,
    TradingBotResponse,
    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 ILoginFormInput = {
  name: string
}

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

export type UnifiedTradingModalProps = {
  showModal: boolean
  closeModal: () => void
  mode: 'backtest' | 'createBot' | 'updateBot'
  setBacktests?: React.Dispatch<React.SetStateAction<Backtest[]>>
  backtest?: Backtest
  existingBot?: any // TradingBotResponse or whatever the bot type is
}

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

export type IBacktestsFormInput = {
  accountName: string
  tickers: string[]
  timeframe: Timeframe
  scenarioName: string
  save: boolean
  balance: number
  moneyManagement: MoneyManagement
  startDate: string
  endDate: string
  cooldownPeriod: number
  maxLossStreak: number
  maxPositionTimeHours?: number | null
  flipOnlyWhenInProfit?: boolean
  closeEarlyWhenProfitable?: boolean
  // Synth API fields
  useSynthApi?: boolean
  useForPositionSizing?: boolean
  useForSignalFiltering?: boolean
  useForDynamicStopLoss?: boolean
}

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

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

export type IModalProps = {
  showModal: boolean
  onSubmit?: React.FormEventHandler
  onClose?: React.FormEventHandler
  titleHeader?: string
  children?: React.ReactNode
  toggleModal?: React.MouseEventHandler<HTMLButtonElement>
  moneyManagement?: MoneyManagement
  size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl'
}

export type  IMoneyManagementModalProps = {
  showModal?: boolean | undefined
  onSubmit?: React.FormEventHandler
  onClose: () => void
  toggleModal?: React.MouseEventHandler<HTMLButtonElement>
  moneyManagement?: MoneyManagement
  disableInputs?: boolean
}

export type  IBacktestFormInput = {
  accountName: string
  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: TradingBotResponse[]
}
export type IScenarioFormInput = {
  name: string
  indicators: string[]
  loopbackPeriod: number | undefined
}
export type IScenarioList = {
  list: ScenarioViewModel[]
  indicators?: IndicatorViewModel[]
  setScenarios?: React.Dispatch<React.SetStateAction<ScenarioViewModel[]>>
}

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: TradingBotResponse[]
  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: LightSignal[]
}

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
  account?: Account
}

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[]
  onInitialize: () => Promise<void>
  getFirstAccount: () => Account | null
  getFirstAccountName: () => string
}

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