import {ChevronDownIcon, ChevronRightIcon, ChevronUpIcon, CogIcon, PlayIcon, TrashIcon} from '@heroicons/react/solid'
import React, {useEffect, useState} from 'react'
import {useExpanded, useFilters, usePagination, useSortBy, useTable,} from 'react-table'

import useApiUrlStore from '../../../app/store/apiStore'
import useBacktestStore from '../../../app/store/backtestStore'
import type {Backtest, LightBacktestResponse} from '../../../generated/ManagingApi'
import {BacktestClient} from '../../../generated/ManagingApi'
import {ConfigDisplayModal, IndicatorsDisplay, SelectColumnFilter} from '../../mollecules'
import {UnifiedTradingModal} from '../index'
import Toast from '../../mollecules/Toast/Toast'

import BacktestRowDetails from './backtestRowDetails'

// Custom Table component for server-side sorting
const ServerSortableTable = ({ 
    columns, 
    data, 
    renderRowSubCompontent, 
    onSortChange, 
    currentSort 
}: any) => {
    const defaultColumn = React.useMemo<any>(
        () => ({
            Filter: SelectColumnFilter,
        }),
        []
    )

    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        prepareRow,
        visibleColumns,
        rows,
    } = useTable(
        {
            columns,
            data,
            defaultColumn,
        },
        useFilters,
        useSortBy,
        useExpanded,
        usePagination
    )

    const handleSortClick = (column: any) => {
        if (!onSortChange || !column.canSort) return;
        
        const isCurrentlySorted = currentSort?.sortBy === column.id;
        const newSortOrder = isCurrentlySorted && currentSort?.sortOrder === 'desc' ? 'asc' : 'desc';
        
        onSortChange(column.id, newSortOrder);
    };

    return (
        <div className="w-full mt-3 mb-3 overflow-x-auto">
            <table {...getTableProps()} className="table-compact table">
                <thead>
                    {headerGroups.map((headerGroup: any) => (
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map((column: any) => (
                                <th 
                                    {...column.getHeaderProps()}
                                    onClick={() => handleSortClick(column)}
                                    className={column.canSort ? 'cursor-pointer hover:bg-base-200' : ''}
                                >
                                    <p className="mb-2 text-center">
                                        {column.render('Header')}
                                    </p>
                                    <span className="relative">
                                        {(() => {
                                            // Map backend field names to column IDs for comparison
                                            const backendToColumnMapping: { [key: string]: string } = {
                                                'score': 'score',
                                                'finalpnl': 'finalPnl',
                                                'winrate': 'winRate',
                                                'growthpercentage': 'growthPercentage',
                                                'hodlpercentage': 'hodlPercentage',
                                            };
                                            const columnId = backendToColumnMapping[currentSort?.sortBy || ''] || currentSort?.sortBy;
                                            
                                            return currentSort?.sortBy && columnId === column.id ? (
                                                currentSort.sortOrder === 'desc' ? (
                                                    <ChevronDownIcon className="text-primary absolute right-0 w-4" />
                                                ) : (
                                                    <ChevronUpIcon className="text-secondary absolute right-0 w-4" />
                                                )
                                            ) : (
                                                ''
                                            );
                                        })()}
                                    </span>
                                    <div>
                                        {column.canFilter ? column.render('Filter') : null}
                                    </div>
                                </th>
                            ))}
                        </tr>
                    ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                    {rows.map((row: any) => {
                        prepareRow(row)
                        return (
                            <>
                                <tr {...row.getRowProps()}>
                                    {row.cells.map((cell: any) => {
                                        return (
                                            <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                                        )
                                    })}
                                </tr>
                                {row.isExpanded ? (
                                    <tr>
                                        <td colSpan={visibleColumns.length}>
                                            {renderRowSubCompontent({ row })}
                                        </td>
                                    </tr>
                                ) : null}
                            </>
                        )
                    })}
                </tbody>
            </table>
        </div>
    )
}

interface BacktestTableProps {
    list: LightBacktestResponse[] | undefined
    isFetching?: boolean
    displaySummary?: boolean
    onSortChange?: (sortBy: string, sortOrder: 'asc' | 'desc') => void
    currentSort?: { sortBy: string; sortOrder: 'asc' | 'desc' }
    onBacktestDeleted?: () => void // Callback when a backtest is deleted
}



const BacktestTable: React.FC<BacktestTableProps> = ({list, isFetching, onSortChange, currentSort, onBacktestDeleted}) => {
    const [rows, setRows] = useState<LightBacktestResponse[]>([])
    const {apiUrl} = useApiUrlStore()
    const {removeBacktest} = useBacktestStore()

    // Bot configuration modal state
    const [showBotConfigModal, setShowBotConfigModal] = useState(false)
    const [selectedBacktest, setSelectedBacktest] = useState<Backtest | null>(null)

    // Backtest configuration modal state
    const [showBacktestConfigModal, setShowBacktestConfigModal] = useState(false)
    const [selectedBacktestForRerun, setSelectedBacktestForRerun] = useState<Backtest | null>(null)

    // Config display modal state
    const [showConfigDisplayModal, setShowConfigDisplayModal] = useState(false)
    const [selectedBacktestForConfigView, setSelectedBacktestForConfigView] = useState<Backtest | null>(null)

    // Handle sort change
    const handleSortChange = (columnId: string, sortOrder: 'asc' | 'desc') => {
        if (!onSortChange) return;
        
        // Map column IDs to backend field names
        const sortByMapping: { [key: string]: string } = {
            'score': 'score',
            'finalPnl': 'finalpnl',
            'winRate': 'winrate',
            'growthPercentage': 'growthpercentage',
            'hodlPercentage': 'hodlpercentage',
        };
        
        const backendSortBy = sortByMapping[columnId] || 'score';
        onSortChange(backendSortBy, sortOrder);
    };

    const handleOpenBotConfigModal = (backtest: Backtest) => {
        setSelectedBacktest(backtest)
        setShowBotConfigModal(true)
    }

    const handleCloseBotConfigModal = () => {
        setShowBotConfigModal(false)
        setSelectedBacktest(null)
    }

    const handleOpenBacktestConfigModal = (backtest: Backtest) => {
        setSelectedBacktestForRerun(backtest)
        setShowBacktestConfigModal(true)
    }

    const handleCloseBacktestConfigModal = () => {
        setShowBacktestConfigModal(false)
        setSelectedBacktestForRerun(null)
    }

    const handleOpenConfigDisplayModal = (backtest: Backtest) => {
        setSelectedBacktestForConfigView(backtest)
        setShowConfigDisplayModal(true)
    }

    const handleCloseConfigDisplayModal = () => {
        setShowConfigDisplayModal(false)
        setSelectedBacktestForConfigView(null)
    }

    async function deleteBacktest(id: string) {
        const t = new Toast('Deleting backtest')
        const client = new BacktestClient({}, apiUrl)

        await client
            .backtest_DeleteBacktest(id)
            .then(() => {
                t.update('success', 'Backtest deleted')
                // Remove the deleted backtest from the store
                removeBacktest(id)
                // Call the callback to invalidate queries
                if (onBacktestDeleted) {
                    onBacktestDeleted()
                }
            })
            .catch((err) => {
                t.update('error', err)
            })
    }

    const getScoreColor = (score: number) => {
        // Create a smooth gradient from red to green
        if (score >= 90) return '#00D100'; // bright green
        if (score >= 80) return '#2ECC71'; // green
        if (score >= 70) return '#5DBA5D'; // light green
        if (score >= 60) return '#8BC34A'; // lime green
        if (score >= 50) return '#CDDC39'; // lime
        if (score >= 40) return '#FFEB3B'; // yellow
        if (score >= 30) return '#FF9800'; // orange
        if (score >= 20) return '#FF5722'; // deep orange
        if (score >= 10) return '#F44336'; // red
        return '#D32F2F'; // dark red
    };

    const columns = React.useMemo(
        () => [
            {
                Header: 'Informations',
                columns: [
                    {
                        Cell: ({row}: any) => (
                            // Use Cell to render an expander for each row.
                            // We can use the getToggleRowExpandedProps prop-getter
                            // to build the expander.
                            <span {...row.getToggleRowExpandedProps()}>
                {row.isExpanded ? (
                    <ChevronDownIcon></ChevronDownIcon>
                ) : (
                    <ChevronRightIcon></ChevronRightIcon>
                )}
              </span>
                        ),

                        // Make sure it has an ID
                        Header: ({
                                     getToggleAllRowsExpandedProps,
                                     isAllRowsExpanded,
                                 }: any) => (
                            <span {...getToggleAllRowsExpandedProps()}>
                {isAllRowsExpanded ? 'v' : '>'}
              </span>
                        ),
                        // Build our expander column
                        id: 'expander',
                    },
                    {
                        Header: 'Score',
                        accessor: 'score',
                        Cell: ({cell}: any) => {
                            const backtest = cell.row.original as LightBacktestResponse;
                            const scoreMessage = backtest.scoreMessage || 'No scoring details available';
                            
                            return (
                                <div className="dropdown dropdown-right bg-base-200">
                                    <div 
                                        tabIndex={0} 
                                        role="button" 
                                        className="cursor-help"
                                        style={{
                                            color: getScoreColor(cell.row.values.score),
                                            fontWeight: 500,
                                            display: 'inline-block',
                                            width: '60px'
                                        }}
                                    >
                                        {cell.row.values.score.toFixed(2)}
                                    </div>
                                    <div 
                                        tabIndex={0} 
                                        className="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-96 max-h-64 overflow-y-auto"
                                    >
                                        <div className="text-sm whitespace-pre-wrap">
                                            {scoreMessage}
                                        </div>
                                    </div>
                                </div>
                            );
                        },
                        disableFilters: true,
                        disableSortBy: false,
                        sortType: 'basic',
                    },
                    {
                        Filter: SelectColumnFilter,
                        Header: 'Ticker',
                        accessor: 'config.ticker',
                        disableSortBy: true,
                    },

                    {
                        Filter: SelectColumnFilter,
                        Header: 'Timeframe',
                        accessor: 'config.timeframe',
                        disableSortBy: true,
                    },
                    {
                        Header: 'Indicators',
                        accessor: 'config.scenario.indicators',
                        Cell: ({cell}: any) => {
                            const backtest = cell.row.original as Backtest;
                            const indicators = backtest.config?.scenario?.indicators || [];
                            
                            return (
                                <IndicatorsDisplay indicators={indicators} />
                            );
                        },
                        disableFilters: true,
                        disableSortBy: true,
                    },
                ],
            },
            {
                Header: 'Results',
                columns: [
                    {
                        Cell: ({cell}: any) => (
                            <>{cell.row.values.finalPnl.toFixed(2)} $</>
                        ),
                        Header: 'Pnl $',
                        accessor: 'finalPnl',
                        disableFilters: true,
                        disableSortBy: false,
                        sortType: 'basic',
                    },
                    {
                        Cell: ({cell}: any) => <>{cell.row.values.winRate} %</>,
                        Header: 'Winrate',
                        accessor: 'winRate',
                        disableFilters: true,
                        disableSortBy: false,
                        sortType: 'basic',
                    },
                    {
                        Cell: ({cell}: any) => (
                            <>{cell.row.values.hodlPercentage.toFixed(2)} %</>
                        ),
                        Header: 'Hodl %',
                        accessor: 'hodlPercentage',
                        disableFilters: true,
                        disableSortBy: false,
                        sortType: 'basic',
                    },
                    {
                        Cell: ({cell}: any) => (
                            <>{cell.row.values.growthPercentage.toFixed(2)} %</>
                        ),
                        Header: 'Pnl %',
                        accessor: 'growthPercentage',
                        disableFilters: true,
                        disableSortBy: false,
                        sortType: 'basic',
                    },
                    {
                        Cell: ({cell}: any) => (
                            <>
                                {(
                                    cell.row.values.growthPercentage -
                                    cell.row.values.hodlPercentage
                                ).toFixed(2)}
                            </>
                        ),
                        Header: 'H/P',
                        accessor: 'diff',
                        disableFilters: true,
                        sortType: 'basic',
                    },
                ],
            },
            {
                Header: 'Action',
                columns: [
                    {
                        Cell: ({cell}: any) => (
                            <>
                                <div className="tooltip" data-tip="Delete backtest">
                                    <button
                                        data-value={cell.row.values.name}
                                        onClick={() => deleteBacktest(cell.row.values.id)}
                                    >
                                        <TrashIcon className="text-error w-4"></TrashIcon>
                                    </button>
                                </div>
                            </>
                        ),
                        Header: '',
                        accessor: 'id',
                        disableFilters: true,
                    },
                    
                    {
                        Cell: ({cell}: any) => (
                            <>
                                <div className="tooltip" data-tip="Create bot from backtest">
                                    <button
                                        data-value={cell.row.values.name}
                                        onClick={() => handleOpenBotConfigModal(cell.row.original as Backtest)}
                                    >
                                        <PlayIcon className="text-success w-4"></PlayIcon>
                                    </button>
                                </div>
                            </>
                        ),
                        Header: '',
                        accessor: 'runner',
                        disableFilters: true,
                    },
                    {
                        Cell: ({cell}: any) => (
                            <>
                                <div className="tooltip" data-tip="Rerun backtest with same config">
                                    <button
                                        data-value={cell.row.values.name}
                                        onClick={() => handleOpenBacktestConfigModal(cell.row.original as Backtest)}
                                    >
                                        <svg className="w-4 h-4 text-warning" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
                                        </svg>
                                    </button>
                                </div>
                            </>
                        ),
                        Header: '',
                        accessor: 'rerun',
                        disableFilters: true,
                    },
                    {
                        Cell: ({cell}: any) => (
                            <>
                                <div className="tooltip" data-tip="View/Copy configuration">
                                    <button
                                        data-value={cell.row.values.name}
                                        onClick={() => handleOpenConfigDisplayModal(cell.row.original as Backtest)}
                                    >
                                        <CogIcon className="text-info w-4"></CogIcon>
                                    </button>
                                </div>
                            </>
                        ),
                        Header: '',
                        accessor: 'config',
                        disableFilters: true,
                    }
                ],
            },
        ],
        []
    )

    useEffect(() => {
        if (list) {
            setRows(list)
        }
    }, [list])

    return (
        <>
            {isFetching ? (
                <div className="flex justify-center">
                    <progress className="progress progress-primary w-56"></progress>
                </div>
            ) : (
                <>
                    <ServerSortableTable
                        columns={columns}
                        data={rows}
                        renderRowSubCompontent={({row}: any) => (
                            <BacktestRowDetails
                                backtest={row.original}
                            />
                        )}
                        onSortChange={handleSortChange}
                        currentSort={currentSort}
                    />

                    {/* Bot Configuration Modal */}
                    {selectedBacktest && (
                        <UnifiedTradingModal
                            showModal={showBotConfigModal}
                            mode="createBot"
                            backtest={selectedBacktest}
                            closeModal={handleCloseBotConfigModal}
                        />
                    )}

                    {/* Backtest Configuration Modal */}
                    {selectedBacktestForRerun && (
                        <UnifiedTradingModal
                            showModal={showBacktestConfigModal}
                            mode="backtest"
                            backtest={selectedBacktestForRerun}
                            closeModal={handleCloseBacktestConfigModal}
                        />
                    )}

                    {/* Config Display Modal */}
                    <ConfigDisplayModal
                        showModal={showConfigDisplayModal}
                        onClose={handleCloseConfigDisplayModal}
                        backtest={selectedBacktestForConfigView}
                    />
                </>
            )}
        </>
    )
}

export default BacktestTable
