import {ChartBarIcon, CogIcon, EyeIcon, PlayIcon, PlusCircleIcon, StopIcon, TrashIcon} from '@heroicons/react/solid'
import React, {useState} from 'react'

import useApiUrlStore from '../../app/store/apiStore'
import {CardPosition, CardSignal, CardText, Toast,} from '../../components/mollecules'
import ManualPositionModal from '../../components/mollecules/ManualPositionModal'
import TradesModal from '../../components/mollecules/TradesModal/TradesModal'
import BotConfigModal from '../../components/mollecules/BotConfigModal/BotConfigModal'
import {TradeChart} from '../../components/organism'
import type {BotType, MoneyManagement, Position, TradingBotResponse} from '../../generated/ManagingApi'
import {BotClient} from '../../generated/ManagingApi'
import type {IBotList} from '../../global/type'
import MoneyManagementModal from '../settingsPage/moneymanagement/moneyManagementModal'

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

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

function cardClasses(botStatus: string) {
  const classes =
    'card bg-base-300 shadow-md ' + (botStatus == 'Up' ? 'shadow-success' : '')

  return classes
}

const BotList: React.FC<IBotList> = ({ list }) => {
  const { apiUrl } = useApiUrlStore()
  const client = new BotClient({}, apiUrl)
  const [showMoneyManagementModal, setShowMoneyManagementModal] =
    useState(false)
  const [selectedMoneyManagement, setSelectedMoneyManagement] =
    useState<MoneyManagement>()
  const [showManualPositionModal, setShowManualPositionModal] = useState(false)
  const [selectedBotForManualPosition, setSelectedBotForManualPosition] = useState<string | null>(null)
  const [showTradesModal, setShowTradesModal] = useState(false)
  const [selectedBotForTrades, setSelectedBotForTrades] = useState<{ identifier: string; agentName: string } | null>(null)
  const [showBotConfigModal, setShowBotConfigModal] = useState(false)
  const [botConfigModalMode, setBotConfigModalMode] = useState<'create' | 'update'>('create')
  const [selectedBotForUpdate, setSelectedBotForUpdate] = useState<{
    identifier: string
    config: any
  } | null>(null)

  function getIsForWatchingBadge(isForWatchingOnly: boolean, identifier: string) {
    const classes =
      baseBadgeClass() + (isForWatchingOnly ? ' bg-accent' : ' bg-primary')
    return (
      <button className={classes} onClick={() => toggleIsForWatchingOnly(identifier)}>
        {isForWatchingOnly ? (
          <p className="text-accent-content flex">
            <EyeIcon width={12}></EyeIcon>
            Watch Only
          </p>
        ) : (
          <p className="text-primary-content flex">
            <PlayIcon width={12}></PlayIcon>
            Trading
          </p>
        )}
      </button>
    )
  }

  function toggleIsForWatchingOnly(identifier: string) {
    const t = new Toast('Switch watch only')
    client.bot_ToggleIsForWatching(identifier).then(() => {
      t.update('success', 'Bot updated')
    })
  }
  function getDeleteBadge(identifier: string) {
    const classes = baseBadgeClass() + 'bg-error'
    return (
      <button className={classes} onClick={() => deleteBot(identifier)}>
        <p className="text-primary-content flex">
          <TrashIcon width={15}></TrashIcon>
        </p>
      </button>
    )
  }
  function getToggleBotStatusBadge(
    status: string,
    identifier: string,
    botType: BotType
  ) {
    const classes =
      baseBadgeClass() + (status == 'Up' ? ' bg-error' : ' bg-success')
    return (
      <button
        className={classes}
        onClick={() => toggleBotStatus(status, identifier, botType)}
      >
        {status == 'Up' ? (
          <p className="text-accent-content flex">
            <StopIcon width={15}></StopIcon>
          </p>
        ) : (
          <p className="text-primary-content flex">
            <PlayIcon width={15}></PlayIcon>
          </p>
        )}
      </button>
    )
  }

  function getMoneyManagementBadge(moneyManagement: MoneyManagement) {
    const classes = baseBadgeClass() + ' bg-primary'
    return (
      <button
        className={classes}
        onClick={() => {
          setSelectedMoneyManagement(moneyManagement)
          setShowMoneyManagementModal(true)
        }}
      >
        <p className="text-primary-content flex">
          <EyeIcon width={15}></EyeIcon>
          MoneyManagement
        </p>
      </button>
    )
  }

  function getManualPositionBadge(botIdentifier: string) {
    const classes = baseBadgeClass() + ' bg-info'
    return (
      <button className={classes} onClick={() => openManualPositionModal(botIdentifier)}>
         <p className="text-primary-content flex">
            <PlusCircleIcon width={15}></PlusCircleIcon>
         </p>
      </button>
    )
  }

  function getTradesBadge(botIdentifier: string, agentName: string) {
    const classes = baseBadgeClass() + ' bg-secondary'
    return (
      <button className={classes} onClick={() => openTradesModal(botIdentifier, agentName)}>
         <p className="text-primary-content flex">
            <ChartBarIcon width={15}></ChartBarIcon>
         </p>
      </button>
    )
  }

  function openManualPositionModal(botIdentifier: string) {
    setSelectedBotForManualPosition(botIdentifier)
    setShowManualPositionModal(true)
  }

  function openTradesModal(botIdentifier: string, agentName: string) {
    setSelectedBotForTrades({ identifier: botIdentifier, agentName })
    setShowTradesModal(true)
  }

  function toggleBotStatus(status: string, identifier: string, botType: BotType) {
    const isUp = status == 'Up'
    const t = new Toast(isUp ? 'Stoping bot' : 'Restarting bot')

    if (status == 'Up') {
      client
        .bot_Stop(botType, identifier)
        .then(() => {
          t.update('success', 'Bot stopped')
        })
        .catch((err) => {
          t.update('error', err)
        })
    } else if (status == 'Down') {
      client
        .bot_Restart(botType, identifier)
        .then(() => {
          t.update('success', 'Bot up')
        })
        .catch((err) => {
          t.update('error', err)
        })
    }
  }

  function deleteBot(identifier: string) {
    const t = new Toast('Deleting bot')

    client
      .bot_Delete(identifier)
      .then(() => {
        t.update('success', 'Bot deleted')
      })
      .catch((err) => {
        t.update('error', err)
      })
  }

  function getUpdateBotBadge(bot: TradingBotResponse) {
    const classes = baseBadgeClass() + ' bg-warning'
    return (
      <button className={classes} onClick={() => openUpdateBotModal(bot)}>
        <p className="text-primary-content flex">
          <CogIcon width={15}></CogIcon>
        </p>
      </button>
    )
  }

  function getCreateBotBadge() {
    const classes = baseBadgeClass() + ' bg-success'
    return (
      <button className={classes} onClick={() => openCreateBotModal()}>
        <p className="text-primary-content flex">
          <PlusCircleIcon width={15}></PlusCircleIcon>
          Create Bot
        </p>
      </button>
    )
  }

  function openCreateBotModal() {
    setBotConfigModalMode('create')
    setSelectedBotForUpdate(null)
    setShowBotConfigModal(true)
  }

  function openUpdateBotModal(bot: TradingBotResponse) {
    setBotConfigModalMode('update')
    setSelectedBotForUpdate({
      identifier: bot.identifier,
      config: bot.config
    })
    setShowBotConfigModal(true)
  }

  return (
    <div className="flex flex-wrap m-4 -mx-4">
      <div className="w-full p-2 mb-4">
        <div className="flex justify-end">
          {getCreateBotBadge()}
        </div>
      </div>

      {list.map((bot: TradingBotResponse, index) => (
        <div
          key={index.toString()}
          className="sm:w-1 md:w-1/2 xl:w-1/2 w-full p-2"
        >
          <div className={cardClasses(bot.status)}>
            <figure>
              {
                <TradeChart
                  candles={bot.candles}
                  positions={bot.positions}
                  signals={bot.signals}
                  width={510}
                  height={300}
                ></TradeChart>
              }
            </figure>
            <div className="card-body">
              <h2 className="card-title text-sm">
                {bot.config.ticker}
                {getMoneyManagementBadge(bot.config.moneyManagement)}
                {getIsForWatchingBadge(bot.config.isForWatchingOnly, bot.identifier)}
                {getToggleBotStatusBadge(bot.status, bot.identifier, bot.config.botType)}
                {getUpdateBotBadge(bot)}
                {getManualPositionBadge(bot.identifier)}
                {getDeleteBadge(bot.identifier)}
              </h2>
             

              <div className="columns-2">
                <div>
                  <div>
                    <CardText
                      title="Scenario"
                      content={bot.config.scenarioName}
                    ></CardText>
                  </div>
                </div>
              </div>
              <div className="columns-2">
                <CardSignal signals={bot.signals}></CardSignal>
                <CardText title="Type" content={bot.config.botType}></CardText>
              </div>
              <div className="columns-2">
                <CardPosition
                  positivePosition={true}
                  positions={bot.positions.filter((p: Position) => {
                    const realized = p.profitAndLoss?.realized ?? 0
                    return realized > 0 ? p : null
                  })}
                ></CardPosition>
                <CardPosition
                  positivePosition={false}
                  positions={bot.positions.filter((p: Position) => {
                    const realized = p.profitAndLoss?.realized ?? 0
                    return realized <= 0 ? p : null
                  })}
                ></CardPosition>
              </div>
              <div className="text-sm">
                <div className="card-actions justify-center pt-2">
                  <div className={baseBadgeClass(true)}>
                    WR {bot.winRate?.toFixed(2).toString()} %
                  </div>
                  <div className={baseBadgeClass(true)}>
                    PNL {bot.profitAndLoss.toFixed(2).toString()} $
                  </div>
                  {getTradesBadge(bot.identifier, bot.agentName)}
                </div>
              </div>
            </div>
          </div>
        </div>
      ))}

      <MoneyManagementModal
        showModal={showMoneyManagementModal}
        moneyManagement={selectedMoneyManagement}
        onClose={() => setShowMoneyManagementModal(false)}
        disableInputs={true}
      />
      <ManualPositionModal
        showModal={showManualPositionModal}
        botName={selectedBotForManualPosition}
        onClose={() => {
          setShowManualPositionModal(false)
          setSelectedBotForManualPosition(null)
        }}
      />
      <TradesModal
        showModal={showTradesModal}
        strategyName={selectedBotForTrades?.identifier ?? null}
        agentName={selectedBotForTrades?.agentName ?? null}
        onClose={() => {
          setShowTradesModal(false)
          setSelectedBotForTrades(null)
        }}
      />
      <BotConfigModal
        showModal={showBotConfigModal}
        mode={botConfigModalMode}
        existingBot={selectedBotForUpdate || undefined}
        onClose={() => {
          setShowBotConfigModal(false)
          setSelectedBotForUpdate(null)
        }}
      />
    </div>
  )
}

export default BotList
