import {DotsVerticalIcon, TrashIcon} from '@heroicons/react/solid'
import moment from 'moment'
import React from 'react'

import useApiUrlStore from '../../../app/store/apiStore'
import type {Backtest, MoneyManagement, StartBotRequest, Ticker,} from '../../../generated/ManagingApi'
import {BacktestClient, BotClient, BotType,} from '../../../generated/ManagingApi'
import type {IBacktestCards} from '../../../global/type'
import MoneyManagementModal from '../../../pages/settingsPage/moneymanagement/moneyManagementModal'
import {CardPosition, CardText, Toast} from '../../mollecules'
import CardPositionItem from '../Trading/CardPositionItem'
import TradeChart from '../Trading/TradeChart/TradeChart'

function baseBadgeClass(isOutlined = false) {
  let classes = 'text-xs badge '

  if (isOutlined) {
    classes += 'badge-outline '
  }
  return classes
}

function botStatusResult(
  growthPercentage: number | undefined,
  hodlPercentage: number | undefined
) {
  if (growthPercentage != undefined && hodlPercentage != undefined) {
    const isWinning = growthPercentage > hodlPercentage
    const classes =
      baseBadgeClass() + (isWinning ? 'badge-success' : 'badge-content')
    return <div className={classes}>{isWinning ? 'Winning' : 'Losing'}</div>
  }
}

// function that return the number of day between a date and today
function daysBetween(date: Date) {
  const oneDay = 24 * 60 * 60 * 1000 // hours*minutes*seconds*milliseconds
  const firstDate = new Date(date)
  const secondDate = new Date()
  const diffDays = Math.round(
    Math.abs((firstDate.getTime() - secondDate.getTime()) / oneDay)
  )
  return diffDays
}

const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
  console.log(list)
  const { apiUrl } = useApiUrlStore()
  const [showMoneyManagementModal, setShowMoneyManagementModal] =
    React.useState(false)
  const [selectedMoneyManagement, setSelectedMoneyManagement] =
    React.useState<MoneyManagement>()

  async function runBot(backtest: Backtest, isForWatchOnly: boolean) {
    const t = new Toast('Bot is starting')
    const client = new BotClient({}, apiUrl)

    const request: StartBotRequest = {
      accountName: backtest.accountName,
      botName: backtest.ticker + '-' + backtest.timeframe.toString(),
      botType: BotType.ScalpingBot,
      isForWatchOnly: isForWatchOnly,
      moneyManagementName: backtest.moneyManagement?.name,
      scenario: backtest.scenario,
      ticker: backtest.ticker as Ticker,
      timeframe: backtest.timeframe,
      initialTradingBalance: 1000,
    }

    await client
      .bot_Start(request)
      .then((botStatus: string) => {
        t.update('info', 'Bot status :' + botStatus)
      })
      .catch((err) => {
        t.update('error', 'Error :' + err)
      })
  }

  async function runOptimizedBacktest(backtest: Backtest) {
    const t = new Toast('Optimized backtest is running')
    const client = new BacktestClient({}, apiUrl)

    // Calculate dates for the API call
    const startDate = backtest.candles[0].date
    const endDate = backtest.candles[backtest.candles.length - 1].date

    await client
      .backtest_Run(
        backtest.accountName,
        backtest.botType,
        backtest.ticker as Ticker,
        backtest.scenario,
        backtest.timeframe,
        false, // watchOnly
        backtest.walletBalances[0].value, // balance
        '', // moneyManagementName (empty since we're passing the optimized moneyManagement object)
        startDate, // startDate
        endDate, // endDate
        false, // save
        backtest.optimizedMoneyManagement // moneyManagement object
      )
      .then((backtest: Backtest) => {
        t.update('success', `${backtest.ticker} Backtest Succeeded`)
        setBacktests((arr) => [...arr, backtest])
      })
      .catch((err) => {
        t.update('error', 'Error :' + err)
      })
  }

  function saveMoneyManagement(moneyManagement: MoneyManagement) {
    setSelectedMoneyManagement(moneyManagement)
    setShowMoneyManagementModal(true)
  }

  return (
    <div className="flex flex-wrap m-4 -mx-4">
      {list?.map((backtest: Backtest, index) => (
        <div
          key={index.toString()}
          className="sm:w-1/2 md:w-1/2 xl:w-1/2 w-full p-2"
        >
          <div className="indicator">
            <div className="indicator-item indicator-top">
              <button className="btn btn-primary h-5 min-h-0 px-2 mr-5 rounded-full">
                <TrashIcon width={15}></TrashIcon>
              </button>
            </div>

            <div className="card bg-base-300 shadow-xl">
              <figure className="z-0">
                {
                  <TradeChart
                    candles={backtest.candles}
                    positions={backtest.positions}
                    walletBalances={backtest.walletBalances}
                    signals={backtest.signals}
                    strategiesValues={backtest.strategiesValues}
                    width={720}
                    height={512}
                  ></TradeChart>
                }
              </figure>

              <div className="card-body">
                <h2 className="card-title text-sm">
                  <div className="dropdown">
                    <label
                      htmlFor={index.toString()}
                      tabIndex={index}
                      className=""
                    >
                      <DotsVerticalIcon className="text-primary w-5 h-5" />
                    </label>
                    <ul
                      id={index.toString()}
                      className="dropdown-content menu bg-base-100 rounded-box w-52 p-2 shadow"
                    >
                      <li>
                        <button
                          className="text-xs"
                          onClick={() => runBot(backtest, false)}
                        >
                          Run bot
                        </button>
                      </li>
                      <li>
                        <button
                          className="text-xs"
                          onClick={() => runBot(backtest, true)}
                        >
                          Run watcher
                        </button>
                      </li>
                      <li>
                        <button
                          className="text-xs"
                          onClick={() =>
                            saveMoneyManagement(backtest.moneyManagement)
                          }
                        >
                          Save money management
                        </button>
                      </li>
                      <li>
                        <button
                          className="text-xs"
                          onClick={() => runOptimizedBacktest(backtest)}
                        >
                          Run optimized money management
                        </button>
                      </li>
                    </ul>
                  </div>
                  {backtest.ticker}
                  {botStatusResult(
                    backtest.growthPercentage,
                    backtest.hodlPercentage
                  )}
                </h2>
                <div className="columns-4 mb-2">
                  <div>
                    <CardText
                      title="Ticker"
                      content={backtest.ticker}
                    ></CardText>
                    <CardText
                      title="Account"
                      content={backtest.accountName}
                    ></CardText>
                    <CardText
                      title="Scenario"
                      content={backtest.scenario}
                    ></CardText>
                    <CardText
                      title="Timeframe"
                      content={backtest.timeframe}
                    ></CardText>
                  </div>
                </div>
                <div className="columns-4 mb-2">
                  <CardText
                    title="Duration"
                    content={moment
                      .duration(
                        moment(
                          backtest.candles[backtest.candles.length - 1].date
                        ).diff(backtest.candles[0].date)
                      )
                      .humanize()}
                  ></CardText>
                  {/* <CardSignal signals={backtest.signals}></CardSignal> */}
                  <CardPosition
                    positivePosition={true}
                    positions={backtest.positions.filter((p) => {
                      const realized = p.profitAndLoss?.realized ?? 0
                      return realized > 0 ? p : null
                    })}
                  ></CardPosition>
                  <CardPosition
                    positivePosition={false}
                    positions={backtest.positions.filter((p) => {
                      const realized = p.profitAndLoss?.realized ?? 0
                      return realized <= 0 ? p : null
                    })}
                  ></CardPosition>
                  <CardPositionItem
                    positions={backtest.positions}
                  ></CardPositionItem>
                </div>

                <div className="columns-4 mb-2">
                  <div>
                    <CardText
                      title="Max Drowdown"
                      content={
                        backtest.statistics.maxDrawdown?.toFixed(4).toString() +
                        '$'
                      }
                    ></CardText>
                    <CardText
                      title="PNL"
                      content={backtest.finalPnl?.toFixed(4).toString() + '$'}
                    ></CardText>
                    <CardText
                      title="Sharpe Ratio"
                      content={
                        (backtest.statistics.sharpeRatio
                          ? backtest.statistics.sharpeRatio * 100
                          : 0
                        )
                          .toFixed(4)
                          .toString() + '%'
                      }
                    ></CardText>
                    <CardText
                      title="%Hodl"
                      content={
                        backtest.hodlPercentage?.toFixed(2).toString() + '%'
                      }
                    ></CardText>
                  </div>
                </div>
                <div className="card-actions justify-center pt-2 text-sm">
                  <div className={baseBadgeClass(true)}>
                    WR {backtest.winRate?.toFixed(2).toString()} %
                  </div>
                  <div className={baseBadgeClass(true)}>
                    PNL {backtest.growthPercentage?.toFixed(2).toString()} %
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      ))}

      <MoneyManagementModal
        showModal={showMoneyManagementModal}
        moneyManagement={selectedMoneyManagement}
        onClose={() => setShowMoneyManagementModal(false)}
      />
    </div>
  )
}

export default BacktestCards
