import React, {useEffect, useState} from 'react'
import {GridTile, Table} from '../../../components/mollecules'
import useApiUrlStore from '../../../app/store/apiStore'
import {type AgentBalanceHistory, type BestAgentsResponse, DataClient} from '../../../generated/ManagingApi'

// Extend the type to include agentBalances for runtime use
export interface AgentBalanceWithBalances extends AgentBalanceHistory {
  agentBalances?: Array<{
    totalValue?: number
    totalAccountUsdValue?: number
    botsAllocationUsdValue?: number
    pnL?: number
    time?: string
  }>;
}

const FILTERS = [
  { label: '24H', value: '24H', days: 1 },
  { label: '3D', value: '3D', days: 3 },
  { label: '1W', value: '1W', days: 7 },
  { label: '1M', value: '1M', days: 30 },
  { label: '1Y', value: '1Y', days: 365 },
  { label: 'Total', value: 'Total', days: null },
]

function BestAgents({ index }: { index: number }) {
  const { apiUrl } = useApiUrlStore()
  const [data, setData] = useState<AgentBalanceWithBalances[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(10)
  const [totalPages, setTotalPages] = useState(1)
  const [selectedFilter, setSelectedFilter] = useState('Total')

  useEffect(() => {
    setIsLoading(true)
    const client = new DataClient({}, apiUrl)
    const now = new Date()
    
    // Calculate start date based on selected filter
    const filterObj = FILTERS.find(f => f.value === selectedFilter)
    let startDate: Date
    if (filterObj?.days) {
      // Use the filter's days value to calculate start date
      startDate = new Date(now.getTime() - filterObj.days * 24 * 60 * 60 * 1000)
    } else {
      // For 'Total', fetch from a far past date (e.g., 5 years ago)
      startDate = new Date(now.getFullYear() - 5, now.getMonth(), now.getDate())
    }
    
    client.data_GetBestAgents(startDate, now, page, pageSize).then((res: BestAgentsResponse) => {
      setData(res.agents as AgentBalanceWithBalances[] ?? [])
      setTotalPages(res.totalPages ?? 1)
      console.log(res)
    }).finally(() => setIsLoading(false))
  }, [apiUrl, page, pageSize, selectedFilter])

  function filterBalancesByRange(agent: AgentBalanceWithBalances) {
    if (!agent.agentBalances || selectedFilter === 'Total') return agent.agentBalances ?? []
    const days = FILTERS.find(f => f.value === selectedFilter)?.days
    if (!days) return agent.agentBalances ?? []
    const now = new Date()
    const cutoff = new Date(now.getTime() - days * 24 * 60 * 60 * 1000)
    return agent.agentBalances.filter(b => b.time && new Date(b.time) >= cutoff)
  }

  // Get the latest balance for each agent
  const latestBalances = data.map(agent => {
    const filteredBalances = filterBalancesByRange(agent)
    if (filteredBalances.length > 0) {
      const lastBalance = filteredBalances[filteredBalances.length - 1]
      return {
        agentName: agent.agentName,
        originalAgent: { ...agent, agentBalances: filteredBalances },
        ...lastBalance
      }
    }
    return { agentName: agent.agentName, originalAgent: { ...agent, agentBalances: filteredBalances } }
  })

  const columns = [
    { Header: 'Agent', accessor: 'agentName' },
    { Header: 'Total Value (USD)', accessor: 'totalValue', Cell: ({ value }: any) => value?.toLocaleString(undefined, { maximumFractionDigits: 2 }) },
    { Header: 'Account Value (USD)', accessor: 'totalAccountUsdValue', Cell: ({ value }: any) => value?.toLocaleString(undefined, { maximumFractionDigits: 2 }) },
    { Header: 'Bots Allocation (USD)', accessor: 'botsAllocationUsdValue', Cell: ({ value }: any) => value?.toLocaleString(undefined, { maximumFractionDigits: 2 }) },
    { Header: 'PnL (USD)', accessor: 'pnL', Cell: ({ value }: any) => value?.toLocaleString(undefined, { maximumFractionDigits: 2 }) },
    { Header: 'Last Update', accessor: 'time', Cell: ({ value }: any) => value ? new Date(value).toLocaleString() : '' },
  ]

  return (
    <div className="container mx-auto pt-6">
      <GridTile title="Best Agents">
        <div className="flex gap-2 mb-3">
          {FILTERS.map(f => (
            <button
              key={f.value}
              className={`px-2 py-0.5 text-xs rounded ${selectedFilter === f.value ? 'bg-primary text-primary-content' : 'bg-base-200'}`}
              onClick={() => setSelectedFilter(f.value)}
            >
              {f.label}
            </button>
          ))}
        </div>
        {isLoading ? (
          <progress className="progress progress-primary w-56"></progress>
        ) : (
          <Table 
            columns={columns} 
            data={latestBalances} 
            showPagination={false}
          />
        )}
        <div className="flex justify-between items-center mt-4">
          <button className="btn" onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={page === 1}>Previous</button>
          <span>Page {page} of {totalPages}</span>
          <button className="btn" onClick={() => setPage((p) => Math.min(totalPages, p + 1))} disabled={page === totalPages}>Next</button>
          <select className="select select-bordered ml-2" value={pageSize} onChange={e => { setPageSize(Number(e.target.value)); setPage(1) }}>
            {[10, 20, 30, 40, 50].map(size => <option key={size} value={size}>Show {size}</option>)}
          </select>
        </div>
      </GridTile>
    </div>
  )
}

export default BestAgents 