'use client';

import { getGlobalApiLogger } from '@/lib/infrastructure/ApiRequestLogger';
import { getGlobalErrorHandler } from '@/lib/infrastructure/GlobalErrorHandler';
import { getErrorAnalyticsStats, type ErrorStats } from '@/lib/services/error/ErrorAnalyticsService';
import { Badge } from '@/ui/Badge';
import { Button } from '@/ui/Button';
import { Icon } from '@/ui/Icon';
import { IconButton } from '@/ui/IconButton';
import { Input } from '@/ui/Input';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import {
    Activity,
    AlertTriangle,
    Bug,
    ChevronDown,
    Clock,
    Copy,
    Cpu,
    Download,
    FileText,
    Globe,
    RefreshCw,
    Search,
    Terminal,
    Trash2,
    Zap
} from 'lucide-react';
import { useEffect, useState } from 'react';

import { DateDisplay } from '@/lib/display-objects/DateDisplay';
import { DurationDisplay } from '@/lib/display-objects/DurationDisplay';
import { MemoryDisplay } from '@/lib/display-objects/MemoryDisplay';
import { PercentDisplay } from '@/lib/display-objects/PercentDisplay';
import { TimeDisplay } from '@/lib/display-objects/TimeDisplay';

interface ErrorAnalyticsDashboardProps {
  /**
   * Auto-refresh interval in milliseconds
   */
  refreshInterval?: number;
  /**
   * Whether to show in production (default: false)
   */
  showInProduction?: boolean;
}

function formatDuration(duration: number): string {
  return DurationDisplay.formatMs(duration);
}

function formatPercentage(value: number, total: number): string {
  if (total === 0) return '0%';
  return PercentDisplay.format(value / total);
}

function formatMemory(bytes: number): string {
  return MemoryDisplay.formatMB(bytes);
}

interface PerformanceWithMemory extends Performance {
  memory?: {
    usedJSHeapSize: number;
    totalJSHeapSize: number;
    jsHeapSizeLimit: number;
  };
}

interface NavigatorWithConnection extends Navigator {
  connection?: {
    effectiveType: string;
    downlink: number;
    rtt: number;
  };
}

/**
 * Comprehensive Error Analytics Dashboard
 * Shows real-time error statistics, API metrics, and environment details
 */
export function ErrorAnalyticsDashboard({ 
  refreshInterval = 5000,
  showInProduction = false 
}: ErrorAnalyticsDashboardProps) {
  const [stats, setStats] = useState<ErrorStats | null>(null);
  const [isExpanded, setIsExpanded] = useState(true);
  const [selectedTab, setSelectedTab] = useState<'errors' | 'api' | 'environment' | 'raw'>('errors');
  const [searchTerm, setSearchTerm] = useState('');
  const [copied, setCopied] = useState(false);

  const isDev = process.env.NODE_ENV === 'development';
  const shouldShow = isDev || showInProduction;

  const perf = typeof performance !== 'undefined' ? performance as PerformanceWithMemory : null;
  const nav = typeof navigator !== 'undefined' ? navigator as NavigatorWithConnection : null;

  useEffect(() => {
    if (!shouldShow) return;

    const update = () => {
      setStats(getErrorAnalyticsStats());
    };

    update();

    if (refreshInterval > 0) {
      const interval = setInterval(update, refreshInterval);
      return () => clearInterval(interval);
    }
  }, [refreshInterval, shouldShow]);

  if (!shouldShow) {
    return null;
  }

  const updateStatsManual = () => {
    setStats(getErrorAnalyticsStats());
  };

  const copyToClipboard = async (data: unknown) => {
    try {
      await navigator.clipboard.writeText(JSON.stringify(data, null, 2));
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch (err) {
      // Silent failure
    }
  };

  const exportAllData = () => {
    const globalHandler = getGlobalErrorHandler();
    const apiLogger = getGlobalApiLogger();

    const exportData = {
      timestamp: new Date().toISOString(),
      errors: globalHandler.getErrorHistory(),
      apiRequests: apiLogger.getHistory(),
      stats: stats,
    };

    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `gridpilot-error-report-${Date.now()}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const clearAllData = () => {
    if (confirm('Are you sure you want to clear all error and API logs?')) {
      const globalHandler = getGlobalErrorHandler();
      const apiLogger = getGlobalApiLogger();
      
      globalHandler.clearHistory();
      apiLogger.clearHistory();
      updateStatsManual();
    }
  };

  const filteredRecentErrors = stats?.recentErrors.filter(error => 
    searchTerm === '' || 
    error.message.toLowerCase().includes(searchTerm.toLowerCase()) ||
    error.type.toLowerCase().includes(searchTerm.toLowerCase())
  ) || [];

  if (!isExpanded) {
    return (
      <Stack position="fixed" bottom="4" left="4" zIndex={50}>
        <IconButton
          icon={Activity}
          onClick={() => setIsExpanded(true)}
          variant="secondary"
          title="Open Error Analytics"
          size="lg"
          color="rgb(239, 68, 68)"
        />
      </Stack>
    );
  }

  return (
    <Stack 
      position="fixed" 
      bottom="4" 
      left="4" 
      zIndex={50} 
      w="96" 
      bg="bg-deep-graphite" 
      border 
      borderColor="border-charcoal-outline" 
      rounded="xl" 
      shadow="2xl" 
      overflow="hidden" 
      display="flex" 
      flexDirection="col"
      maxHeight="80vh"
    >
      {/* Header */}
      <Stack display="flex" alignItems="center" justifyContent="between" px={4} py={3} bg="bg-iron-gray/50" borderBottom borderColor="border-charcoal-outline">
        <Stack display="flex" alignItems="center" gap={2}>
          <Icon icon={Activity} size={4} intent="critical" />
          <Text size="sm" weight="semibold" variant="high">Error Analytics</Text>
          {isDev && (
            <Badge variant="critical" size="sm">
              DEV
            </Badge>
          )}
        </Stack>
        <Stack display="flex" alignItems="center" gap={1}>
          <IconButton
            icon={RefreshCw}
            onClick={updateStatsManual}
            variant="ghost"
            size="sm"
            title="Refresh"
          />
          <IconButton
            icon={ChevronDown}
            onClick={() => setIsExpanded(false)}
            variant="ghost"
            size="sm"
            title="Minimize"
          />
        </Stack>
      </Stack>

      {/* Tabs */}
      <Stack display="flex" borderBottom borderColor="border-charcoal-outline" bg="bg-iron-gray/30">
        {[
          { id: 'errors', label: 'Errors', icon: AlertTriangle },
          { id: 'api', label: 'API', icon: Globe },
          { id: 'environment', label: 'Env', icon: Cpu },
          { id: 'raw', label: 'Raw', icon: FileText },
        ].map(tab => (
          <Stack
            key={tab.id}
            as="button"
            type="button"
            onClick={() => setSelectedTab(tab.id as 'errors' | 'api' | 'environment' | 'raw')}
            display="flex"
            flexGrow={1}
            alignItems="center"
            justifyContent="center"
            gap={1}
            px={2}
            py={2}
            cursor="pointer"
            transition
            bg={selectedTab === tab.id ? 'bg-deep-graphite' : ''}
            borderBottom={selectedTab === tab.id}
            borderColor={selectedTab === tab.id ? 'border-red-400' : ''}
            borderWidth={selectedTab === tab.id ? '2px' : '0'}
          >
            <Icon icon={tab.icon} size={3} color={selectedTab === tab.id ? 'text-white' : 'text-gray-400'} />
            <Text 
              size="xs" 
              weight="medium" 
              color={selectedTab === tab.id ? 'text-white' : 'text-gray-400'}
            >
              {tab.label}
            </Text>
          </Stack>
        ))}
      </Stack>

      {/* Content */}
      <Stack flexGrow={1} overflow="auto" p={4}>
        <Stack gap={4}>
          {/* Search Bar */}
          {selectedTab === 'errors' && (
            <Input
              type="text"
              placeholder="Search errors..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              icon={<Icon icon={Search} size={3} color="rgb(107, 114, 128)" />}
            />
          )}

          {/* Errors Tab */}
          {selectedTab === 'errors' && stats && (
            <Stack gap={4}>
              {/* Error Summary */}
              <Stack display="grid" gridCols={2} gap={2}>
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Text size="xs" color="text-gray-500" block>Total Errors</Text>
                  <Text size="xl" weight="bold" color="text-red-400">{stats.totalErrors}</Text>
                </Stack>
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Text size="xs" color="text-gray-500" block>Error Types</Text>
                  <Text size="xl" weight="bold" color="text-warning-amber">
                    {Object.keys(stats.errorsByType).length}
                  </Text>
                </Stack>
              </Stack>

              {/* Error Types Breakdown */}
              {Object.keys(stats.errorsByType).length > 0 && (
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Stack display="flex" alignItems="center" gap={2} mb={2}>
                    <Icon icon={Bug} size={3} color="rgb(156, 163, 175)" />
                    <Text size="xs" weight="semibold" color="text-gray-400">Error Types</Text>
                  </Stack>
                  <Stack gap={1} maxHeight="8rem" overflow="auto">
                    {Object.entries(stats.errorsByType).map(([type, count]) => (
                      <Stack key={type} display="flex" justifyContent="between">
                        <Text size="xs" color="text-gray-300">{type}</Text>
                        <Text size="xs" color="text-red-400" font="mono">{count}</Text>
                      </Stack>
                    ))}
                  </Stack>
                </Stack>
              )}

              {/* Recent Errors */}
              {filteredRecentErrors.length > 0 && (
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Stack display="flex" alignItems="center" gap={2} mb={2}>
                    <Icon icon={AlertTriangle} size={3} color="rgb(156, 163, 175)" />
                    <Text size="xs" weight="semibold" color="text-gray-400">Recent Errors</Text>
                  </Stack>
                  <Stack gap={2} maxHeight="16rem" overflow="auto">
                    {filteredRecentErrors.map((error, idx) => (
                      <Stack key={idx} bg="bg-deep-graphite" border borderColor="border-charcoal-outline" rounded="md" p={2}>
                        <Stack display="flex" justifyContent="between" alignItems="start" gap={2} mb={1}>
                          <Text size="xs" font="mono" weight="bold" color="text-red-400" truncate>{error.type}</Text>
                          <Text size="xs" color="text-gray-500" fontSize="10px">
                            {DateDisplay.formatTime(error.timestamp)}
                          </Text>
                        </Stack>
                        <Text size="xs" color="text-gray-300" block mb={1}>{error.message}</Text>
                        <Button
                          variant="ghost"
                          onClick={() => copyToClipboard(error)}
                          size="sm"
                          p={0}
                          minHeight="0"
                          icon={<Icon icon={Copy} size={3} />}
                        >
                          <Text size="xs" color="text-gray-500" fontSize="10px">Copy Details</Text>
                        </Button>
                      </Stack>
                    ))}
                  </Stack>
                </Stack>
              )}

              {/* Error Timeline */}
              {stats.errorsByTime.length > 0 && (
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Stack display="flex" alignItems="center" gap={2} mb={2}>
                    <Icon icon={Clock} size={3} color="rgb(156, 163, 175)" />
                    <Text size="xs" weight="semibold" color="text-gray-400">Last 10 Minutes</Text>
                  </Stack>
                  <Stack gap={1} maxHeight="8rem" overflow="auto">
                    {stats.errorsByTime.map((point, idx) => (
                      <Stack key={idx} display="flex" justifyContent="between">
                        <Text size="xs" color="text-gray-500">{point.time}</Text>
                        <Text size="xs" color="text-red-400" font="mono">{point.count} errors</Text>
                      </Stack>
                    ))}
                  </Stack>
                </Stack>
              )}
            </Stack>
          )}

          {/* API Tab */}
          {selectedTab === 'api' && stats && (
            <Stack gap={4}>
              {/* API Summary */}
              <Stack display="grid" gridCols={2} gap={2}>
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Text size="xs" color="text-gray-500" block>Total Requests</Text>
                  <Text size="xl" weight="bold" color="text-primary-blue">{stats.apiStats.totalRequests}</Text>
                </Stack>
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Text size="xs" color="text-gray-500" block>Success Rate</Text>
                  <Text size="xl" weight="bold" color="text-performance-green">
                    {formatPercentage(stats.apiStats.successful, stats.apiStats.totalRequests)}
                  </Text>
                </Stack>
              </Stack>

              {/* API Stats */}
              <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                <Stack display="flex" alignItems="center" gap={2} mb={2}>
                  <Icon icon={Globe} size={3} color="rgb(156, 163, 175)" />
                  <Text size="xs" weight="semibold" color="text-gray-400">API Metrics</Text>
                </Stack>
                <Stack gap={1}>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">Successful</Text>
                    <Text size="xs" color="text-performance-green" font="mono">{stats.apiStats.successful}</Text>
                  </Stack>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">Failed</Text>
                    <Text size="xs" color="text-red-400" font="mono">{stats.apiStats.failed}</Text>
                  </Stack>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">Avg Duration</Text>
                    <Text size="xs" color="text-warning-amber" font="mono">{formatDuration(stats.apiStats.averageDuration)}</Text>
                  </Stack>
                </Stack>
              </Stack>

              {/* Slowest Requests */}
              {stats.apiStats.slowestRequests.length > 0 && (
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Stack display="flex" alignItems="center" gap={2} mb={2}>
                    <Icon icon={Zap} size={3} color="rgb(156, 163, 175)" />
                    <Text size="xs" weight="semibold" color="text-gray-400">Slowest Requests</Text>
                  </Stack>
                  <Stack gap={1} maxHeight="10rem" overflow="auto">
                    {stats.apiStats.slowestRequests.map((req, idx) => (
                      <Stack key={idx} display="flex" justifyContent="between" bg="bg-deep-graphite" p={1.5} rounded="sm" border borderColor="border-charcoal-outline">
                        <Text size="xs" color="text-gray-300" truncate flexGrow={1}>{req.url}</Text>
                        <Text size="xs" color="text-red-400" font="mono" ml={2}>{formatDuration(req.duration)}</Text>
                      </Stack>
                    ))}
                  </Stack>
                </Stack>
              )}
            </Stack>
          )}

          {/* Environment Tab */}
          {selectedTab === 'environment' && stats && (
            <Stack gap={4}>
              {/* Environment Info */}
              <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                <Stack display="flex" alignItems="center" gap={2} mb={2}>
                  <Icon icon={Cpu} size={3} color="rgb(156, 163, 175)" />
                  <Text size="xs" weight="semibold" color="text-gray-400">Environment</Text>
                </Stack>
                <Stack gap={1}>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">Node Environment</Text>
                    <Text size="xs" font="mono" weight="bold" color={stats.environment.mode === 'development' ? 'text-performance-green' : 'text-warning-amber'}>
                      {stats.environment.mode}
                    </Text>
                  </Stack>
                  {stats.environment.version && (
                    <Stack display="flex" justifyContent="between">
                      <Text size="xs" color="text-gray-500">Version</Text>
                      <Text size="xs" color="text-gray-300" font="mono">{stats.environment.version}</Text>
                    </Stack>
                  )}
                  {stats.environment.buildTime && (
                    <Stack display="flex" justifyContent="between">
                      <Text size="xs" color="text-gray-500">Build Time</Text>
                      <Text size="xs" color="text-gray-500" font="mono" fontSize="10px">{stats.environment.buildTime}</Text>
                    </Stack>
                  )}
                </Stack>
              </Stack>

              {/* Browser Info */}
              <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                <Stack display="flex" alignItems="center" gap={2} mb={2}>
                  <Icon icon={Globe} size={3} color="rgb(156, 163, 175)" />
                  <Text size="xs" weight="semibold" color="text-gray-400">Browser</Text>
                </Stack>
                <Stack gap={1}>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">User Agent</Text>
                    <Text size="xs" color="text-gray-300" truncate maxWidth="150px">{navigator.userAgent}</Text>
                  </Stack>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">Language</Text>
                    <Text size="xs" color="text-gray-300" font="mono">{navigator.language}</Text>
                  </Stack>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">Platform</Text>
                    <Text size="xs" color="text-gray-300" font="mono">{navigator.platform}</Text>
                  </Stack>
                </Stack>
              </Stack>

              {/* Performance */}
              <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                <Stack display="flex" alignItems="center" gap={2} mb={2}>
                  <Icon icon={Activity} size={3} color="rgb(156, 163, 175)" />
                  <Text size="xs" weight="semibold" color="text-gray-400">Performance</Text>
                </Stack>
                <Stack gap={1}>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">Viewport</Text>
                    <Text size="xs" color="text-gray-300" font="mono">{window.innerWidth}x{window.innerHeight}</Text>
                  </Stack>
                  <Stack display="flex" justifyContent="between">
                    <Text size="xs" color="text-gray-500">Screen</Text>
                    <Text size="xs" color="text-gray-300" font="mono">{window.screen.width}x{window.screen.height}</Text>
                  </Stack>
                  {perf?.memory && (
                    <Stack display="flex" justifyContent="between">
                      <Text size="xs" color="text-gray-500">JS Heap</Text>
                      <Text size="xs" color="text-gray-300" font="mono">
                        {formatMemory(perf.memory.usedJSHeapSize)}
                      </Text>
                    </Stack>
                  )}
                </Stack>
              </Stack>

              {/* Connection */}
              {nav?.connection && (
                <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                  <Stack display="flex" alignItems="center" gap={2} mb={2}>
                    <Icon icon={Zap} size={3} color="rgb(156, 163, 175)" />
                    <Text size="xs" weight="semibold" color="text-gray-400">Network</Text>
                  </Stack>
                  <Stack gap={1}>
                    <Stack display="flex" justifyContent="between">
                      <Text size="xs" color="text-gray-500">Type</Text>
                      <Text size="xs" color="text-gray-300" font="mono">{nav.connection.effectiveType}</Text>
                    </Stack>
                    <Stack display="flex" justifyContent="between">
                      <Text size="xs" color="text-gray-500">Downlink</Text>
                      <Text size="xs" color="text-gray-300" font="mono">{nav.connection.downlink}Mbps</Text>
                    </Stack>
                    <Stack display="flex" justifyContent="between">
                      <Text size="xs" color="text-gray-500">RTT</Text>
                      <Text size="xs" color="text-gray-300" font="mono">{nav.connection.rtt}ms</Text>
                    </Stack>
                  </Stack>
                </Stack>
              )}
            </Stack>
          )}

          {/* Raw Data Tab */}
          {selectedTab === 'raw' && stats && (
            <Stack gap={3}>
              <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                <Stack display="flex" alignItems="center" gap={2} mb={2}>
                  <Icon icon={FileText} size={3} color="rgb(156, 163, 175)" />
                  <Text size="xs" weight="semibold" color="text-gray-400">Export Options</Text>
                </Stack>
                <Stack display="flex" gap={2}>
                  <Button
                    variant="primary"
                    onClick={exportAllData}
                    fullWidth
                    size="sm"
                    icon={<Icon icon={Download} size={3} />}
                  >
                    Export JSON
                  </Button>
                  <Button
                    variant="secondary"
                    onClick={() => copyToClipboard(stats)}
                    fullWidth
                    size="sm"
                    icon={<Icon icon={Copy} size={3} />}
                  >
                    Copy Stats
                  </Button>
                </Stack>
              </Stack>

              <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                <Stack display="flex" alignItems="center" gap={2} mb={2}>
                  <Icon icon={Trash2} size={3} color="rgb(156, 163, 175)" />
                  <Text size="xs" weight="semibold" color="text-gray-400">Maintenance</Text>
                </Stack>
                <Button
                  variant="danger"
                  onClick={clearAllData}
                  fullWidth
                  size="sm"
                  icon={<Icon icon={Trash2} size={3} />}
                >
                  Clear All Logs
                </Button>
              </Stack>

              <Stack bg="bg-iron-gray" border borderColor="border-charcoal-outline" rounded="md" p={3}>
                <Stack display="flex" alignItems="center" gap={2} mb={2}>
                  <Icon icon={Terminal} size={3} color="rgb(156, 163, 175)" />
                  <Text size="xs" weight="semibold" color="text-gray-400">Console Commands</Text>
                </Stack>
                <Stack gap={1} fontSize="10px">
                  <Text color="text-gray-400" font="mono">• window.__GRIDPILOT_GLOBAL_HANDLER__</Text>
                  <Text color="text-gray-400" font="mono">• window.__GRIDPILOT_API_LOGGER__</Text>
                  <Text color="text-gray-400" font="mono">• window.__GRIDPILOT_REACT_ERRORS__</Text>
                </Stack>
              </Stack>
            </Stack>
          )}
        </Stack>
      </Stack>

      {/* Footer */}
      <Stack px={4} py={2} bg="bg-iron-gray/30" borderTop borderColor="border-charcoal-outline" display="flex" justifyContent="between" alignItems="center">
        <Text size="xs" color="text-gray-500" fontSize="10px">Auto-refresh: {refreshInterval}ms</Text>
        {copied && <Text size="xs" color="text-performance-green" fontSize="10px">Copied!</Text>}
      </Stack>
    </Stack>
  );
}

/**
 * Hook for accessing error analytics programmatically
 */
export function useErrorAnalytics() {
  const globalHandler = getGlobalErrorHandler();
  const apiLogger = getGlobalApiLogger();

  return {
    getStats: () => {
      const errorStats = globalHandler.getStats();
      const apiStats = apiLogger.getStats();
      return {
        errors: errorStats,
        api: apiStats,
      };
    },
    getRecentErrors: (limit = 10) => {
      return globalHandler.getErrorHistory().slice(-limit);
    },
    getSlowestApiRequests: (limit = 5) => {
      return apiLogger.getSlowestRequests(limit);
    },
    exportData: () => {
      return {
        timestamp: new Date().toISOString(),
        errors: globalHandler.getErrorHistory(),
        apiRequests: apiLogger.getHistory(),
      };
    },
    clearAll: () => {
      globalHandler.clearHistory();
      apiLogger.clearHistory();
    },
  };
}
