import React, {useState} from 'react'
import type {SubmitHandler} from 'react-hook-form'
import {useForm} from 'react-hook-form'
import {Account, AccountClient, Ticker,} from '../../../generated/ManagingApi'
import Modal from '../../../components/mollecules/Modal/Modal'
import useApiUrlStore from '../../../app/store/apiStore'
import {FormInput, Toast} from '../../../components/mollecules'
import {useApiError} from '../../../hooks/useApiError'

interface SendTokenModalProps {
  isOpen: boolean
  onClose: () => void
  account: Account
  fromTicker: Ticker
  availableAmount: number
}

interface SendTokenFormInput {
  recipientAddress: string
  ticker: Ticker
  amount: number
  chainId?: number
}

const SendTokenModal: React.FC<SendTokenModalProps> = ({
  isOpen,
  onClose,
  account,
  fromTicker,
  availableAmount,
}) => {
  const [isLoading, setIsLoading] = useState(false)
  const { error, setError, handleApiErrorWithToast } = useApiError()
  const { apiUrl } = useApiUrlStore()
  const client = new AccountClient({}, apiUrl)

  const { register, handleSubmit, watch, setValue } = useForm<SendTokenFormInput>({
    defaultValues: {
      recipientAddress: '',
      ticker: fromTicker,
      amount: availableAmount * 0.1, // Start with 10% of available amount
      chainId: 42161, // Default to ARBITRUM
    }
  })

  const watchedAmount = watch('amount')
  const watchedRecipientAddress = watch('recipientAddress')

  const onSubmit: SubmitHandler<SendTokenFormInput> = async (form) => {
    const t = new Toast(`Sending ${form.amount} ${form.ticker} to ${form.recipientAddress} from ${account.name}`)
    setIsLoading(true)
    setError(null)

    try {
      const result = await client.account_SendToken(
        account.name,
        {
          recipientAddress: form.recipientAddress,
          ticker: form.ticker,
          amount: form.amount,
          chainId: form.chainId,
        }
      )
      
      if (result.success) {
        t.update('success', `Token sent successfully! Hash: ${result.hash}`)
        onClose()
      } else {
        console.log(result)
        const errorMessage = result.error || result.message || 'Send token failed'
        setError(errorMessage)
        t.update('error', `Send token failed: ${errorMessage}`)
      }
    } catch (err) {
      handleApiErrorWithToast(err, t)
    } finally {
      setIsLoading(false)
    }
  }

  const handleFormSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    handleSubmit(onSubmit)(e)
  }

  const modalContent = (
    <>
      {isLoading ? (
        <div className="text-center py-4">
          <span className="loading loading-spinner loading-md"></span>
          <p>Processing token transfer...</p>
        </div>
      ) : error ? (
        <div className="alert alert-error mb-4">
          <p>{error}</p>
        </div>
      ) : (
        <>
          <div className="mb-4">
            <p className="mb-2">
              <strong>Account:</strong> {account.name}
            </p>
            <p className="mb-2">
              <strong>Token:</strong> {fromTicker}
            </p>
            <p className="mb-2">
              <strong>Available:</strong> {availableAmount.toFixed(6)} {fromTicker}
            </p>
          </div>

          <form onSubmit={handleFormSubmit}>
            <div className="space-y-4 mb-4">
              <FormInput label="Recipient Address" htmlFor="recipientAddress">
                <input
                  type="text"
                  placeholder="0x..."
                  className="input input-bordered w-full"
                  {...register('recipientAddress', { 
                    required: true,
                    pattern: {
                      value: /^0x[a-fA-F0-9]{40}$/,
                      message: 'Please enter a valid Ethereum address'
                    }
                  })}
                />
              </FormInput>

              <FormInput label="Token" htmlFor="ticker">
                <select
                  className="select select-bordered w-full"
                  {...register('ticker')}
                  defaultValue={fromTicker}
                >
                  {Object.values(Ticker).map((ticker) => (
                    <option key={ticker} value={ticker}>
                      {ticker}
                    </option>
                  ))}
                </select>
              </FormInput>

              <FormInput label="Amount" htmlFor="amount">
                <div className="w-full">
                  <input
                    type="number"
                    step="any"
                    placeholder="Enter amount to send"
                    className="input input-bordered w-full mb-2"
                    {...register('amount', { 
                      valueAsNumber: true,
                      min: 0.0001,
                      max: availableAmount,
                      required: true 
                    })}
                  />
                  <div className="w-full">
                    <input
                      type="range"
                      min="0"
                      max={availableAmount}
                      step={availableAmount / 100}
                      className="range range-primary w-full"
                      value={watchedAmount || 0}
                      onChange={(e) => {
                        const value = parseFloat(e.target.value)
                        setValue('amount', value)
                      }}
                    />
                    
                    <div className="text-center text-xs text-gray-500 mt-1">
                      {watchedAmount && availableAmount > 0 ? (
                        <span>{((watchedAmount / availableAmount) * 100).toFixed(1)}% of available balance</span>
                      ) : (
                        <span>0% of available balance</span>
                      )}
                    </div>
                  </div>
                </div>
              </FormInput>

              <FormInput label="Chain ID (Optional)" htmlFor="chainId">
                <select
                  className="select select-bordered w-full"
                  {...register('chainId', { valueAsNumber: true })}
                  defaultValue={42161}
                >
                  <option value={1}>Ethereum Mainnet (1)</option>
                  <option value={42161}>Arbitrum One (42161)</option>
                  <option value={421613}>Arbitrum Goerli (421613)</option>
                  <option value={8453}>Base (8453)</option>
                  <option value={84531}>Base Goerli (84531)</option>
                </select>
              </FormInput>

              <button
                type="submit"
                className="btn btn-primary w-full mt-2"
                disabled={isLoading || !watchedAmount || watchedAmount <= 0 || !watchedRecipientAddress}
              >
                {isLoading ? (
                  <span className="loading loading-spinner"></span>
                ) : (
                  `Send ${watchedAmount || 0} ${fromTicker} to ${watchedRecipientAddress ? watchedRecipientAddress.slice(0, 6) + '...' + watchedRecipientAddress.slice(-4) : 'recipient'}`
                )}
              </button>
            </div>
          </form>

          <div className="mt-4">
            <div className="alert alert-warning">
              <p className="text-sm">
                <strong>Warning:</strong> This will send tokens directly to the specified address. Make sure the address is correct as this action cannot be undone.
              </p>
            </div>
          </div>
        </>
      )}
    </>
  )

  return (
    <Modal
      showModal={isOpen}
      onClose={onClose}
      titleHeader="Send Tokens"
    >
      {modalContent}
    </Modal>
  )
}

export default SendTokenModal 