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 {TradeChart, UnifiedTradingModal} from '../../components/organism'
import {
    BotClient,
    BotStatus,
    MoneyManagement,
    Position,
    TradingBotConfig,
    TradingBotResponse,
    UserClient
} from '../../generated/ManagingApi'
import type {IBotList} from '../../global/type.tsx'
import MoneyManagementModal from '../settingsPage/moneymanagement/moneyManagementModal'
import {useQuery} from '@tanstack/react-query'
import useCookie from '../../hooks/useCookie'

function baseBadgeClass(isOutlined = false) {
  let classes = 'text-xs badge badge-sm transition-all duration-200 hover:scale-105 '

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

function cardClasses(botStatus: BotStatus) {
  let classes = 'card bg-base-300 shadow-md '
  
  switch (botStatus) {
    case BotStatus.Running:
      classes += 'shadow-success'
      break
    case BotStatus.Saved:
      classes += 'shadow-info'
      break
    case BotStatus.Stopped:
      classes += 'shadow-warning'
      break
    default:
      // No additional shadow for other statuses
      break
  }

  return classes
}

const BotList: React.FC<IBotList> = ({ list }) => {
  const { apiUrl } = useApiUrlStore()
  const client = new BotClient({}, apiUrl)
  const userClient = new UserClient({}, apiUrl)
  const { getCookie } = useCookie()
  
  // Get JWT token from cookies
  const jwtToken = getCookie('token')
  
  const { data: currentUser } = useQuery({
    queryFn: () => userClient.user_GetCurrentUser(),
    queryKey: ['currentUser'],
    enabled: !!jwtToken, // Only fetch when JWT token exists
  })

  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<{ name: string; agentName: string } | null>(null)
  const [showBotConfigModal, setShowBotConfigModal] = useState(false)
  const [selectedBotForUpdate, setSelectedBotForUpdate] = useState<{
    identifier: string
    config: TradingBotConfig
  } | null>(null)

  // Helper function to check if current user owns the bot
  const isBotOwner = (botAgentName: string): boolean => {
    return currentUser?.agentName === botAgentName
  }

  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: BotStatus, identifier: string) {
    const classes =
      baseBadgeClass() + (status == BotStatus.Running ? ' bg-error' : ' bg-success')
    return (
      <button
        className={classes}
        onClick={() => toggleBotStatus(status, identifier)}
      >
        {status == BotStatus.Running ? (
          <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(name: string, agentName: string) {
    const classes = baseBadgeClass() + ' bg-secondary'
    return (
      <button className={classes} onClick={() => openTradesModal(name, agentName)}>
         <p className="text-primary-content flex">
            <ChartBarIcon width={15}></ChartBarIcon>
         </p>
      </button>
    )
  }

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

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

  function toggleBotStatus(status: BotStatus, identifier: string) {
    const isUp = status == BotStatus.Running
    const t = new Toast(isUp ? 'Stoping bot' : 'Restarting bot')

    if (status == BotStatus.Running) {
      client
        .bot_Stop(identifier)
        .then(() => {
          t.update('success', 'Bot stopped')
        })
        .catch((err) => {
          t.update('error', err)
        })
    } else if (status == BotStatus.Stopped || status == BotStatus.Saved) {
      client
        .bot_Restart(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-orange-500'
    return (
      <button className={classes} onClick={() => openUpdateBotModal(bot).catch(console.error)}>
        <p className="text-primary-content flex">
          <CogIcon width={15}></CogIcon>
        </p>
      </button>
    )
  }

  async function openUpdateBotModal(bot: TradingBotResponse) {
    const t = new Toast('Loading bot configuration...')
    
    try {
      const config = await client.bot_GetBotConfig(bot.identifier)
      setSelectedBotForUpdate({
        identifier: bot.identifier,
        config: config
      })
      setShowBotConfigModal(true)
      t.update('success', 'Bot configuration loaded')
    } catch (error: any) {
      t.update('error', `Error loading bot configuration: ${error.message || error}`)
      console.error('Error fetching bot config:', error)
    }
  }

  return (
    <div className="flex flex-wrap m-4 -mx-4">
      {list.map((bot: TradingBotResponse, index: number) => (
        <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 as BotStatus)}>
            <figure className="w-full">
              {bot.candles && bot.candles.length > 0 ? (
                <TradeChart
                  candles={bot.candles}
                  positions={Object.values(bot.positions)}
                  signals={Object.values(bot.signals)}
                ></TradeChart>
                ) : null}
            </figure>
            <div className="card-body">
              <div className="mb-4">
                {/* Bot Name - Always on its own line */}
                <h2 className="card-title text-sm mb-3">
                  {bot.name}
                </h2>
                
                {/* Badge Container - Responsive */}
                <div className="flex flex-wrap gap-1 sm:gap-2">
                  
                  {/* Action Badges - Only show for bot owners */}
                  {isBotOwner(bot.agentName) && (
                    <div className="flex flex-wrap gap-1">
                      {getToggleBotStatusBadge(bot.status as BotStatus, bot.identifier)}
                      {getUpdateBotBadge(bot)}
                      {getManualPositionBadge(bot.identifier)}
                      {getDeleteBadge(bot.identifier)}
                    </div>
                  )}
                </div>
              </div>

              <div className="columns-2">
                <div>
                  <div>
                    <CardText
                      title="Ticker"
                      content={bot.ticker}
                    ></CardText>
                  </div>
                </div>
              </div>
              <div className="columns-2">
                <CardText
                      title="Agent"
                      content={bot.agentName}
                    ></CardText>
                <CardSignal signals={Object.values(bot.signals ?? {})}></CardSignal>
              </div>
              <div className="columns-2">
                <CardPosition
                  positivePosition={true}
                  positions={Object.values(bot.positions ?? {}).filter((p: Position) => {
                    const realized = p.ProfitAndLoss?.realized ?? 0
                    return realized > 0 ? p : null
                  })}
                ></CardPosition>
                <CardPosition
                  positivePosition={false}
                  positions={Object.values(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.name, 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?.name ?? null}
        agentName={selectedBotForTrades?.agentName ?? null}
        onClose={() => {
          setShowTradesModal(false)
          setSelectedBotForTrades(null)
        }}
      />
      <UnifiedTradingModal
        mode="updateBot"
        showModal={showBotConfigModal}
        closeModal={() => {
          setShowBotConfigModal(false)
          setSelectedBotForUpdate(null)
        }}
        existingBot={selectedBotForUpdate ? {
          identifier: selectedBotForUpdate.identifier,
          config: selectedBotForUpdate.config
        } : undefined}
      />
    </div>
  )
}

export default BotList
