import React, {useEffect, useState} from 'react'
import {useQuery} from '@tanstack/react-query'
import useApiUrlStore from '../../../app/store/apiStore'
import {
  AccountClient,
  Backtest,
  BotClient,
  BotType,
  MoneyManagement,
  MoneyManagementClient,
  ScenarioClient,
  StartBotRequest,
  Ticker,
  Timeframe,
  TradingBotConfig,
  UpdateBotConfigRequest
} from '../../../generated/ManagingApi'
import Toast from '../Toast/Toast'

interface BotConfigModalProps {
  showModal: boolean
  onClose: () => void
  backtest?: Backtest // When creating from backtest
  existingBot?: {
    identifier: string
    config: TradingBotConfig
  } // When updating existing bot
  mode: 'create' | 'update' // Explicitly specify the mode
}

const BotConfigModal: React.FC<BotConfigModalProps> = ({
  showModal,
  onClose,
  backtest,
  existingBot,
  mode
}) => {
  const { apiUrl } = useApiUrlStore()
  
  // Form state
  const [formData, setFormData] = useState<{
    name: string
    accountName: string
    moneyManagementName: string
    ticker: Ticker
    scenarioName: string
    timeframe: Timeframe
    isForWatchingOnly: boolean
    botTradingBalance: number
    botType: BotType
    cooldownPeriod: number
    maxLossStreak: number
    maxPositionTimeHours: number | null
    flipOnlyWhenInProfit: boolean
    flipPosition: boolean
    closeEarlyWhenProfitable: boolean
    useCustomMoneyManagement: boolean
    customStopLoss: number
    customTakeProfit: number
    customLeverage: number
  }>({
    name: '',
    accountName: '',
    moneyManagementName: '',
    ticker: Ticker.BTC,
    scenarioName: '',
    timeframe: Timeframe.FifteenMinutes,
    isForWatchingOnly: false,
    botTradingBalance: 1000,
    botType: BotType.ScalpingBot,
    cooldownPeriod: 1,
    maxLossStreak: 0,
    maxPositionTimeHours: null,
    flipOnlyWhenInProfit: true,
    flipPosition: false,
    closeEarlyWhenProfitable: false,
    useCustomMoneyManagement: false,
    customStopLoss: 0.01,
    customTakeProfit: 0.02,
    customLeverage: 1
  })

  // Fetch data
  const { data: accounts } = useQuery({
    queryFn: async () => {
      const accountClient = new AccountClient({}, apiUrl)
      return await accountClient.account_GetAccounts()
    },
    queryKey: ['accounts']
  })

  const { data: moneyManagements } = useQuery({
    queryFn: async () => {
      const moneyManagementClient = new MoneyManagementClient({}, apiUrl)
      return await moneyManagementClient.moneyManagement_GetMoneyManagements()
    },
    queryKey: ['moneyManagements']
  })

  const { data: scenarios } = useQuery({
    queryFn: async () => {
      const scenarioClient = new ScenarioClient({}, apiUrl)
      return await scenarioClient.scenario_GetScenarios()
    },
    queryKey: ['scenarios']
  })

  // Initialize form data based on props
  useEffect(() => {
    if (mode === 'create' && backtest) {
      // Initialize from backtest
      setFormData({
        name: `Bot-${backtest.config.scenarioName}-${new Date().toISOString().slice(0, 19).replace(/[-:]/g, '')}`,
        accountName: backtest.config.accountName,
        moneyManagementName: moneyManagements?.[0]?.name || '',
        ticker: backtest.config.ticker,
        scenarioName: backtest.config.scenarioName,
        timeframe: backtest.config.timeframe,
        isForWatchingOnly: false,
        botTradingBalance: 1000,
        botType: backtest.config.botType,
        cooldownPeriod: backtest.config.cooldownPeriod,
        maxLossStreak: backtest.config.maxLossStreak,
        maxPositionTimeHours: backtest.config.maxPositionTimeHours ?? null,
        flipOnlyWhenInProfit: backtest.config.flipOnlyWhenInProfit,
        flipPosition: backtest.config.flipPosition,
        closeEarlyWhenProfitable: backtest.config.closeEarlyWhenProfitable || false,
        useCustomMoneyManagement: true, // Default to custom for backtests
        customStopLoss: backtest.config.moneyManagement?.stopLoss || 0.01,
        customTakeProfit: backtest.config.moneyManagement?.takeProfit || 0.02,
        customLeverage: backtest.config.moneyManagement?.leverage || 1
      })
    } else if (mode === 'update' && existingBot) {
      // Initialize from existing bot
      setFormData({
        name: existingBot.config.name,
        accountName: existingBot.config.accountName,
        moneyManagementName: existingBot.config.moneyManagement?.name || '',
        ticker: existingBot.config.ticker,
        scenarioName: existingBot.config.scenarioName,
        timeframe: existingBot.config.timeframe,
        isForWatchingOnly: existingBot.config.isForWatchingOnly,
        botTradingBalance: existingBot.config.botTradingBalance,
        botType: existingBot.config.botType,
        cooldownPeriod: existingBot.config.cooldownPeriod,
        maxLossStreak: existingBot.config.maxLossStreak,
        maxPositionTimeHours: existingBot.config.maxPositionTimeHours ?? null,
        flipOnlyWhenInProfit: existingBot.config.flipOnlyWhenInProfit,
        flipPosition: existingBot.config.flipPosition,
        closeEarlyWhenProfitable: existingBot.config.closeEarlyWhenProfitable || false,
        useCustomMoneyManagement: false,
        customStopLoss: existingBot.config.moneyManagement?.stopLoss || 0.01,
        customTakeProfit: existingBot.config.moneyManagement?.takeProfit || 0.02,
        customLeverage: existingBot.config.moneyManagement?.leverage || 1
      })
    } else if (mode === 'create' && !backtest) {
      // Initialize for new bot creation
      setFormData({
        name: `Bot-${new Date().toISOString().slice(0, 19).replace(/[-:]/g, '')}`,
        accountName: accounts?.[0]?.name || '',
        moneyManagementName: moneyManagements?.[0]?.name || '',
        ticker: Ticker.BTC,
        scenarioName: scenarios?.[0]?.name || '',
        timeframe: Timeframe.FifteenMinutes,
        isForWatchingOnly: false,
        botTradingBalance: 1000,
        botType: BotType.ScalpingBot,
        cooldownPeriod: 1,
        maxLossStreak: 0,
        maxPositionTimeHours: null,
        flipOnlyWhenInProfit: true,
        flipPosition: false,
        closeEarlyWhenProfitable: false,
        useCustomMoneyManagement: false,
        customStopLoss: 0.01,
        customTakeProfit: 0.02,
        customLeverage: 1
      })
    }
  }, [mode, backtest, existingBot, accounts, moneyManagements, scenarios])

  // Set default money management when data loads
  useEffect(() => {
    if (moneyManagements && moneyManagements.length > 0 && !formData.moneyManagementName) {
      setFormData(prev => ({
        ...prev,
        moneyManagementName: moneyManagements[0].name
      }))
    }
  }, [moneyManagements])

  // Set default account when data loads
  useEffect(() => {
    if (accounts && accounts.length > 0 && !formData.accountName) {
      setFormData(prev => ({
        ...prev,
        accountName: accounts[0].name
      }))
    }
  }, [accounts])

  // Set default scenario when data loads
  useEffect(() => {
    if (scenarios && scenarios.length > 0 && !formData.scenarioName) {
      setFormData(prev => ({
        ...prev,
        scenarioName: scenarios[0].name || ''
      }))
    }
  }, [scenarios])

  const handleInputChange = (field: string, value: any) => {
    setFormData(prev => ({
      ...prev,
      [field]: value
    }))
  }

  const handleSubmit = async () => {
    const t = new Toast(mode === 'create' ? 'Creating bot...' : 'Updating bot...')
    const client = new BotClient({}, apiUrl)

    try {
      // Create the money management object
      let moneyManagement: MoneyManagement | undefined = undefined
      
      if (formData.useCustomMoneyManagement || (mode === 'create' && backtest)) {
        // Use custom money management
        moneyManagement = {
          name: 'custom',
          leverage: formData.customLeverage,
          stopLoss: formData.customStopLoss,
          takeProfit: formData.customTakeProfit,
          timeframe: formData.timeframe
        }
      } else {
        // Use saved money management - load the complete object
        const selectedMoneyManagement = moneyManagements?.find(mm => mm.name === formData.moneyManagementName)
        if (selectedMoneyManagement) {
          moneyManagement = selectedMoneyManagement
        } else {
          t.update('error', 'Selected money management not found')
          return
        }
      }

      if (!moneyManagement) {
        t.update('error', 'Money management is required')
        return
      }

      // Create TradingBotConfig (reused for both create and update)
      const tradingBotConfig: TradingBotConfig = {
        accountName: formData.accountName,
        ticker: formData.ticker,
        scenarioName: formData.scenarioName,
        timeframe: formData.timeframe,
        botType: formData.botType,
        isForWatchingOnly: formData.isForWatchingOnly,
        isForBacktest: false,
        cooldownPeriod: formData.cooldownPeriod,
        maxLossStreak: formData.maxLossStreak,
        maxPositionTimeHours: formData.maxPositionTimeHours,
        flipOnlyWhenInProfit: formData.flipOnlyWhenInProfit,
        flipPosition: formData.flipPosition,
        name: formData.name,
        botTradingBalance: formData.botTradingBalance,
        moneyManagement: moneyManagement,
        closeEarlyWhenProfitable: formData.closeEarlyWhenProfitable
      }

      if (mode === 'create') {
        // Create new bot
        const request: StartBotRequest = {
          config: tradingBotConfig,
          moneyManagementName: formData.useCustomMoneyManagement ? undefined : formData.moneyManagementName
        }

        await client.bot_Start(request)
        t.update('success', 'Bot created successfully!')
      } else {
        // Update existing bot
        const request: UpdateBotConfigRequest = {
          identifier: existingBot!.identifier,
          config: tradingBotConfig,
          moneyManagementName: formData.useCustomMoneyManagement ? undefined : formData.moneyManagementName
        }

        await client.bot_UpdateBotConfig(request)
        t.update('success', 'Bot updated successfully!')
      }

      onClose()
    } catch (error: any) {
      t.update('error', `Error: ${error.message || error}`)
    }
  }

  if (!showModal) return null

  return (
    <div className="modal modal-open">
      <div className="modal-box w-11/12 max-w-4xl">
        <h3 className="font-bold text-lg mb-4">
          {mode === 'create' ? 'Create Bot' : 'Update Bot Configuration'}
          {backtest && ` from Backtest`}
        </h3>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {/* Basic Configuration */}
          <div className="form-control">
            <label className="label">
              <span className="label-text">Bot Name</span>
            </label>
            <input
              type="text"
              className="input input-bordered"
              value={formData.name}
              onChange={(e) => handleInputChange('name', e.target.value)}
            />
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Account</span>
            </label>
            <select
              className="select select-bordered"
              value={formData.accountName}
              onChange={(e) => handleInputChange('accountName', e.target.value)}
            >
              {accounts?.map((account) => (
                <option key={account.name} value={account.name}>
                  {account.name}
                </option>
              ))}
            </select>
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Ticker</span>
            </label>
            <select
              className="select select-bordered"
              value={formData.ticker}
              onChange={(e) => handleInputChange('ticker', e.target.value as Ticker)}
            >
              {Object.values(Ticker).map((ticker) => (
                <option key={ticker} value={ticker}>
                  {ticker}
                </option>
              ))}
            </select>
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Scenario</span>
            </label>
            <select
              className="select select-bordered"
              value={formData.scenarioName}
              onChange={(e) => handleInputChange('scenarioName', e.target.value)}
            >
              {scenarios?.map((scenario) => (
                <option key={scenario.name || ''} value={scenario.name || ''}>
                  {scenario.name}
                </option>
              ))}
            </select>
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Timeframe</span>
            </label>
            <select
              className="select select-bordered"
              value={formData.timeframe}
              onChange={(e) => handleInputChange('timeframe', e.target.value as Timeframe)}
            >
              {Object.values(Timeframe).map((timeframe) => (
                <option key={timeframe} value={timeframe}>
                  {timeframe}
                </option>
              ))}
            </select>
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Bot Type</span>
            </label>
            <select
              className="select select-bordered"
              value={formData.botType}
              onChange={(e) => handleInputChange('botType', e.target.value as BotType)}
              disabled={mode === 'update'} // Can't change bot type for existing bots
            >
              {Object.values(BotType).map((botType) => (
                <option key={botType} value={botType}>
                  {botType}
                </option>
              ))}
            </select>
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Trading Balance</span>
            </label>
            <input
              type="number"
              className="input input-bordered"
              value={formData.botTradingBalance}
              onChange={(e) => handleInputChange('botTradingBalance', parseFloat(e.target.value))}
              min="1"
              step="0.01"
            />
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Cooldown Period (candles)</span>
            </label>
            <input
              type="number"
              className="input input-bordered"
              value={formData.cooldownPeriod}
              onChange={(e) => handleInputChange('cooldownPeriod', parseInt(e.target.value))}
              min="1"
            />
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Max Loss Streak</span>
            </label>
            <input
              type="number"
              className="input input-bordered"
              value={formData.maxLossStreak}
              onChange={(e) => handleInputChange('maxLossStreak', parseInt(e.target.value))}
              min="0"
            />
          </div>

          <div className="form-control">
            <label className="label">
              <span className="label-text">Max Position Time (hours)</span>
            </label>
            <input
              type="number"
              className="input input-bordered"
              value={formData.maxPositionTimeHours || ''}
              onChange={(e) => handleInputChange('maxPositionTimeHours', e.target.value ? parseFloat(e.target.value) : null)}
              min="0.1"
              step="0.1"
              placeholder="Optional"
            />
          </div>

          {/* Checkboxes */}
          <div className="form-control">
            <label className="label cursor-pointer">
              <span className="label-text">Watch Only Mode</span>
              <input
                type="checkbox"
                className="checkbox"
                checked={formData.isForWatchingOnly}
                onChange={(e) => handleInputChange('isForWatchingOnly', e.target.checked)}
              />
            </label>
          </div>

          <div className="form-control">
            <label className="label cursor-pointer">
              <span className="label-text">Flip Only When In Profit</span>
              <input
                type="checkbox"
                className="checkbox"
                checked={formData.flipOnlyWhenInProfit}
                onChange={(e) => handleInputChange('flipOnlyWhenInProfit', e.target.checked)}
              />
            </label>
          </div>

          <div className="form-control">
            <label className="label cursor-pointer">
              <span className="label-text">Enable Position Flipping</span>
              <input
                type="checkbox"
                className="checkbox"
                checked={formData.flipPosition}
                onChange={(e) => handleInputChange('flipPosition', e.target.checked)}
              />
            </label>
          </div>

          <div className="form-control">
            <label className="label cursor-pointer">
              <span className="label-text">Close Early When Profitable</span>
              <input
                type="checkbox"
                className="checkbox"
                checked={formData.closeEarlyWhenProfitable}
                onChange={(e) => handleInputChange('closeEarlyWhenProfitable', e.target.checked)}
                disabled={!formData.maxPositionTimeHours}
              />
            </label>
          </div>
        </div>

        {/* Money Management Section */}
        <div className="divider">Money Management</div>
        
        <div className="form-control">
          <label className="label cursor-pointer">
            <span className="label-text">Use Custom Money Management</span>
            <input
              type="checkbox"
              className="checkbox"
              checked={formData.useCustomMoneyManagement}
              onChange={(e) => handleInputChange('useCustomMoneyManagement', e.target.checked)}
            />
          </label>
        </div>

        {formData.useCustomMoneyManagement ? (
          <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
            <div className="form-control">
              <label className="label">
                <span className="label-text">Stop Loss (%)</span>
              </label>
              <input
                type="number"
                className="input input-bordered"
                value={formData.customStopLoss}
                onChange={(e) => handleInputChange('customStopLoss', parseFloat(e.target.value))}
                min="0.001"
                max="1"
                step="0.001"
              />
            </div>

            <div className="form-control">
              <label className="label">
                <span className="label-text">Take Profit (%)</span>
              </label>
              <input
                type="number"
                className="input input-bordered"
                value={formData.customTakeProfit}
                onChange={(e) => handleInputChange('customTakeProfit', parseFloat(e.target.value))}
                min="0.001"
                max="1"
                step="0.001"
              />
            </div>

            <div className="form-control">
              <label className="label">
                <span className="label-text">Leverage</span>
              </label>
              <input
                type="number"
                className="input input-bordered"
                value={formData.customLeverage}
                onChange={(e) => handleInputChange('customLeverage', parseInt(e.target.value))}
                min="1"
                max="100"
              />
            </div>
          </div>
        ) : (
          <div className="form-control mt-4">
            <label className="label">
              <span className="label-text">Money Management</span>
            </label>
            <select
              className="select select-bordered"
              value={formData.moneyManagementName}
              onChange={(e) => handleInputChange('moneyManagementName', e.target.value)}
            >
              {moneyManagements?.map((mm) => (
                <option key={mm.name} value={mm.name}>
                  {mm.name} (SL: {(mm.stopLoss * 100).toFixed(2)}%, TP: {(mm.takeProfit * 100).toFixed(2)}%)
                </option>
              ))}
            </select>
          </div>
        )}

        {/* Validation Messages */}
        {formData.closeEarlyWhenProfitable && !formData.maxPositionTimeHours && (
          <div className="alert alert-warning mt-4">
            <span>Close Early When Profitable requires Max Position Time to be set.</span>
          </div>
        )}

        <div className="modal-action">
          <button className="btn" onClick={onClose}>
            Cancel
          </button>
          <button 
            className="btn btn-primary" 
            onClick={handleSubmit}
            disabled={formData.closeEarlyWhenProfitable && !formData.maxPositionTimeHours}
          >
            {mode === 'create' ? 'Create Bot' : 'Update Bot'}
          </button>
        </div>
      </div>
    </div>
  )
}

export default BotConfigModal 