import React from 'react'
import {useQuery} from '@tanstack/react-query'
import useApiUrlStore from '../../../app/store/apiStore'
import {Table} from '../../../components/mollecules'

// Define health check response interface based on the provided example
interface HealthCheckEntry {
    data: Record<string, any>
    duration: string
    status: string
    tags: string[]
    description?: string
}

interface HealthCheckResponse {
    status: string
    totalDuration: string
    entries: Record<string, HealthCheckEntry>
}

// Interface for candle timeframe check data
interface CandleTimeframeCheck {
    CheckedTicker: string
    CheckedTimeframe: string
    StartDate: string
    LatestCandleDate?: string
    TimeDifference?: string
    Status: string
    Message: string
}

interface Web3ProxyHealthDetail {
    status: string
    message: string
    data?: Record<string, any>
}

const HealthChecks: React.FC = () => {
    const {apiUrl, workerUrl} = useApiUrlStore()

    // Use TanStack Query for API health check
    const {data: apiHealth, isLoading: isLoadingApi} = useQuery({
        queryKey: ['health', 'api'],
        queryFn: async () => {
            const response = await fetch(`${apiUrl}/health`)
            if (!response.ok) throw new Error('Failed to fetch API health')
            return response.json() as Promise<HealthCheckResponse>
        }
    })

    // Use TanStack Query for Worker health check
    const {data: workerHealth, isLoading: isLoadingWorker} = useQuery({
        queryKey: ['health', 'worker'],
        queryFn: async () => {
            const response = await fetch(`${workerUrl}/health`)
            if (!response.ok) throw new Error('Failed to fetch Worker health')
            return response.json() as Promise<HealthCheckResponse>
        }
    })


    // Determine overall loading state
    const isLoading = isLoadingApi || isLoadingWorker

    // Helper function to prepare table data from health response
    const prepareHealthData = (
        service: string,
        health: HealthCheckResponse | null
    ) => {
        if (!health) {
            return [
                {
                    service,
                    component: 'N/A',
                    status: 'Unreachable',
                    duration: 'N/A',
                    tags: 'N/A',
                    description: 'Service unreachable',
                    details: null,
                },
            ]
        }

        // Convert entries to rows for the table
        const results: any[] = [];

        Object.entries(health.entries).forEach(([key, entry]) => {
            // Basic health check entry
            const baseEntry = {
                service,
                component: key,
                status: entry.status,
                duration: entry.duration,
                tags: entry.tags.join(', '),
                description: entry.description || '',
                details: null,
            };

            // Add the base entry
            results.push(baseEntry);

            // Special handling for candle-data to expand timeframe checks
            if (key === 'candle-data' && entry.data) {
                // Extract timeframe checks
                Object.entries(entry.data)
                    .filter(([dataKey]) => dataKey.startsWith('TimeframeCheck_'))
                    .forEach(([dataKey, timeframeData]) => {
                        const tfData = timeframeData as CandleTimeframeCheck;
                        results.push({
                            service,
                            component: `${key} - ${tfData.CheckedTimeframe}`,
                            status: tfData.Status,
                            duration: '',
                            tags: 'candles',
                            description: tfData.Message,
                            details: {
                                Ticker: tfData.CheckedTicker,
                                LatestCandle: tfData.LatestCandleDate,
                                TimeDifference: tfData.TimeDifference,
                            },
                        });
                    });
            }

            // Special handling for Web3Proxy components
            if (key === 'web3proxy' && entry.data) {
                // Handle Privy check if present
                if (entry.data.privy) {
                    const privyData = entry.data.privy as Web3ProxyHealthDetail;
                    results.push({
                        service,
                        component: `${key} - Privy`,
                        status: privyData.status,
                        duration: '',
                        tags: 'privy, external',
                        description: privyData.message || '',
                        details: null,
                    });
                }

                // Handle GMX check if present
                if (entry.data.gmx) {
                    const gmxData = entry.data.gmx as Web3ProxyHealthDetail;
                    const marketDetails: Record<string, any> = {};

                    // Add market count and response time if available
                    if (gmxData.data) {
                        if (gmxData.data.marketCount) {
                            marketDetails['Market Count'] = gmxData.data.marketCount;
                        }
                        if (gmxData.data.responseTimeMs) {
                            marketDetails['Response Time'] = `${gmxData.data.responseTimeMs}ms`;
                        }
                        if (gmxData.data.uiFeeFactor) {
                            marketDetails['UI Fee Factor'] = gmxData.data.uiFeeFactor;
                        }

                        // Add sample markets info (just count for details section)
                        if (gmxData.data.sampleMarkets && Array.isArray(gmxData.data.sampleMarkets)) {
                            marketDetails['Sample Markets'] = gmxData.data.sampleMarkets.length;

                            // If there are sample markets, add the first one's details
                            if (gmxData.data.sampleMarkets.length > 0) {
                                const firstMarket = gmxData.data.sampleMarkets[0];
                                if (firstMarket.indexToken) {
                                    marketDetails['Example Market'] = firstMarket.indexToken;
                                }
                            }
                        }
                    }

                    results.push({
                        service,
                        component: `${key} - GMX`,
                        status: gmxData.status,
                        duration: '',
                        tags: 'gmx, external',
                        description: gmxData.message || '',
                        details: Object.keys(marketDetails).length > 0 ? marketDetails : null,
                    });
                }

                // Add version info if available
                if (entry.data.version) {
                    const versionDetails: Record<string, any> = {
                        Version: entry.data.version
                    };

                    if (entry.data.timestamp) {
                        versionDetails['Last Updated'] = entry.data.timestamp;
                    }

                    results.push({
                        service,
                        component: `${key} - Version`,
                        status: entry.status,
                        duration: '',
                        tags: 'version',
                        description: `Web3Proxy Version: ${entry.data.version}`,
                        details: versionDetails,
                    });
                }
            }
        });

        return results;
    }

    // Combine all health check data for display
    const healthData = [
        ...prepareHealthData('Managing API', apiHealth || null),
        ...prepareHealthData('Managing Worker', workerHealth || null),
    ]

    // Define columns for the table
    const columns = React.useMemo(
        () => [
            {
                Header: 'Service',
                accessor: 'service',
                disableSortBy: true,
                disableFilters: true,
            },
            {
                Header: 'Component',
                accessor: 'component',
                disableSortBy: true,
                disableFilters: true,
            },
            {
                Header: 'Status',
                accessor: 'status',
                Cell: ({value}: { value: string }) => (
                    <span
                        className={`badge ${
                            value === 'Healthy' || value === 'healthy'
                                ? 'badge-success'
                                : value === 'Unreachable' || value === 'unhealthy'
                                    ? 'badge-error'
                                    : 'badge-warning'
                        }`}
                    >
            {value.charAt(0).toUpperCase() + value.slice(1)}
          </span>
                ),
                disableSortBy: true,
                disableFilters: true,
            },
            {
                Header: 'Description',
                accessor: 'description',
                disableSortBy: true,
                disableFilters: true,
                Cell: ({value, row}: any) => (
                    <div>
                        <div>{value}</div>
                        {row.original.details && (
                            <div className="text-xs mt-1 opacity-80">
                                {Object.entries(row.original.details).filter(([_, val]) => val !== undefined).map(
                                    ([key, val]) => (
                                        <div key={key}>
                                            <span className="font-semibold">{key}:</span> {String(val)}
                                        </div>
                                    )
                                )}
                            </div>
                        )}
                    </div>
                ),
            },
            {
                Header: 'Duration',
                accessor: 'duration',
                disableSortBy: true,
                disableFilters: true,
            },
            {
                Header: 'Tags',
                accessor: 'tags',
                disableSortBy: true,
                disableFilters: true,
            },
        ],
        []
    )

    return (
        <div className="container mx-auto">
            <h2 className="text-xl font-bold mb-4">System Health Status</h2>
            {isLoading ? (
                <progress className="progress progress-primary w-56"></progress>
            ) : (
                <Table
                    columns={columns}
                    data={healthData}
                    showPagination={true}
                />
            )}
        </div>
    )
}

export default HealthChecks
