

import type { ApiRequestLogger } from '@/lib/infrastructure/ApiRequestLogger';
import { getGlobalApiLogger } from '@/lib/infrastructure/ApiRequestLogger';
import type { GlobalErrorHandler } from '@/lib/infrastructure/GlobalErrorHandler';
import { getGlobalErrorHandler } from '@/lib/infrastructure/GlobalErrorHandler';
import { Bug, Shield, X } from 'lucide-react';
import { useCallback, useEffect, useState } from 'react';
import { Box } from '@/ui/Box';
import { Button } from '@/ui/Button';
import { Icon } from '@/ui/Icon';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';

// Extend Window interface for debug globals
declare global {
  interface Window {
    __GRIDPILOT_FETCH_LOGGED__?: boolean;
    __GRIDPILOT_GLOBAL_HANDLER__?: GlobalErrorHandler;
    __GRIDPILOT_API_LOGGER__?: ApiRequestLogger;
    __GRIDPILOT_REACT_ERRORS__?: Array<{ error: unknown; componentStack?: string }>;
  }
}

interface DebugModeToggleProps {
  /**
   * Whether to show the toggle (auto-detected from environment)
   */
  show?: boolean;
}

/**
 * Debug Mode Toggle Component
 * Provides a floating interface to control debug features and view real-time metrics
 */
export function DebugModeToggle({ show }: DebugModeToggleProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [debugEnabled, setDebugEnabled] = useState(false);
  const [metrics, setMetrics] = useState({
    errors: 0,
    apiRequests: 0,
    apiFailures: 0,
  });

  const isDev = process.env.NODE_ENV === 'development';
  const shouldShow = show ?? isDev;

  const updateMetrics = useCallback(() => {
    if (!debugEnabled) return;

    const globalHandler = getGlobalErrorHandler();
    const apiLogger = getGlobalApiLogger();

    const errorStats = globalHandler.getStats();
    const apiStats = apiLogger.getStats();

    setMetrics({
      errors: errorStats.total,
      apiRequests: apiStats.total,
      apiFailures: apiStats.failed,
    });
  }, [debugEnabled]);

  const initializeDebugFeatures = useCallback(() => {
    const globalHandler = getGlobalErrorHandler();
    const apiLogger = getGlobalApiLogger();

    // Initialize global error handler
    globalHandler.initialize();

    // Override fetch with logging
    if (!window.__GRIDPILOT_FETCH_LOGGED__) {
      const loggedFetch = apiLogger.createLoggedFetch();
      window.fetch = loggedFetch as typeof fetch;
      window.__GRIDPILOT_FETCH_LOGGED__ = true;
    }

    // Expose to window for easy access
    window.__GRIDPILOT_GLOBAL_HANDLER__ = globalHandler;
    window.__GRIDPILOT_API_LOGGER__ = apiLogger;

    console.log('%c[DEBUG MODE] Enabled', 'color: #00ff88; font-weight: bold; font-size: 14px;');
  }, []);

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

    // Load debug state from localStorage
    const saved = localStorage.getItem('gridpilot_debug_enabled');
    if (saved === 'true') {
      setDebugEnabled(true);
      initializeDebugFeatures();
    }

    // Update metrics every 2 seconds
    const interval = setInterval(updateMetrics, 2000);
    return () => clearInterval(interval);
  }, [shouldShow, initializeDebugFeatures, updateMetrics]);

  useEffect(() => {
    // Save debug state
    if (shouldShow) {
      localStorage.setItem('gridpilot_debug_enabled', debugEnabled.toString());
    }
  }, [debugEnabled, shouldShow]);

  const toggleDebug = () => {
    const newEnabled = !debugEnabled;
    setDebugEnabled(newEnabled);

    if (newEnabled) {
      initializeDebugFeatures();
    } else {
      // Disable debug features
      const globalHandler = getGlobalErrorHandler();
      globalHandler.destroy();

      console.log('%c[DEBUG MODE] Disabled', 'color: #ff4444; font-weight: bold; font-size: 14px;');
    }
  };

  const triggerTestError = () => {
    if (!debugEnabled) return;

    // Trigger a test API error
    const testError = new Error('This is a test error for debugging');
    (testError as any).type = 'TEST_ERROR';
    
    const globalHandler = getGlobalErrorHandler();
    globalHandler.report(testError, { test: true, timestamp: Date.now() });

    console.log('%c[TEST] Error triggered', 'color: #ffaa00; font-weight: bold;', testError);
  };

  const triggerTestApiCall = async () => {
    if (!debugEnabled) return;

    try {
      // This will fail and be logged
      await fetch('https://httpstat.us/500');
    } catch (error) {
      // Already logged by interceptor
      console.log('%c[TEST] API call completed', 'color: #00aaff; font-weight: bold;');
    }
  };

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

    globalHandler.clearHistory();
    apiLogger.clearHistory();

    setMetrics({ errors: 0, apiRequests: 0, apiFailures: 0 });

    console.log('%c[DEBUG] All logs cleared', 'color: #00ff88; font-weight: bold;');
  };

  const copyDebugInfo = async () => {
    const globalHandler = getGlobalErrorHandler();
    const apiLogger = getGlobalApiLogger();

    const debugInfo = {
      timestamp: new Date().toISOString(),
      environment: {
        mode: process.env.NODE_ENV,
        version: process.env.NEXT_PUBLIC_APP_VERSION,
      },
      browser: {
        userAgent: navigator.userAgent,
        language: navigator.language,
        platform: navigator.platform,
      },
      errors: globalHandler.getStats(),
      api: apiLogger.getStats(),
      reactErrors: (window as any).__GRIDPILOT_REACT_ERRORS__ || [],
    };

    try {
      await navigator.clipboard.writeText(JSON.stringify(debugInfo, null, 2));
      console.log('%c[DEBUG] Debug info copied to clipboard', 'color: #00ff88; font-weight: bold;');
    } catch (err) {
      console.error('Failed to copy:', err);
    }
  };

  if (!shouldShow) {
    return null;
  }

  return (
    <Box position="fixed" bottom="4" left="4" zIndex={50}>
      {/* Main Toggle Button */}
      {!isOpen && (
        <Box
          as="button"
          onClick={() => setIsOpen(true)}
          p={3}
          rounded="full"
          shadow="lg"
          bg={debugEnabled ? 'bg-green-600' : 'bg-iron-gray'}
          color="text-white"
          className="transition-all hover:scale-110"
          title={debugEnabled ? 'Debug Mode Active' : 'Enable Debug Mode'}
        >
          <Icon icon={Bug} size={5} />
        </Box>
      )}

      {/* Debug Panel */}
      {isOpen && (
        <Box width="80" bg="bg-deep-graphite" border={true} borderColor="border-charcoal-outline" rounded="xl" shadow="2xl" overflow="hidden">
          {/* Header */}
          <Box display="flex" alignItems="center" justifyContent="between" px={3} py={2} bg="bg-iron-gray/50" borderBottom={true} borderColor="border-charcoal-outline">
            <Stack direction="row" align="center" gap={2}>
              <Icon icon={Bug} size={4} color="text-green-400" />
              <Text size="sm" weight="semibold" color="text-white">Debug Control</Text>
            </Stack>
            <Box
              as="button"
              onClick={() => setIsOpen(false)}
              p={1}
              className="hover:bg-charcoal-outline rounded"
            >
              <Icon icon={X} size={4} color="text-gray-400" />
            </Box>
          </Box>

          {/* Content */}
          <Box p={3}>
            <Stack gap={3}>
              {/* Debug Toggle */}
              <Box display="flex" alignItems="center" justifyContent="between" bg="bg-iron-gray/30" p={2} rounded="md" border={true} borderColor="border-charcoal-outline">
                <Stack direction="row" align="center" gap={2}>
                  <Icon icon={Shield} size={4} color={debugEnabled ? 'text-green-400' : 'text-gray-500'} />
                  <Text size="sm" weight="medium">Debug Mode</Text>
                </Stack>
                <Button
                  onClick={toggleDebug}
                  size="sm"
                  variant={debugEnabled ? 'primary' : 'secondary'}
                  className={debugEnabled ? 'bg-green-600 hover:bg-green-700' : ''}
                >
                  {debugEnabled ? 'ON' : 'OFF'}
                </Button>
              </Box>

              {/* Metrics */}
              {debugEnabled && (
                <Box display="grid" gridCols={3} gap={2}>
                  <Box bg="bg-iron-gray" border={true} borderColor="border-charcoal-outline" rounded="md" p={2} textAlign="center">
                    <Text size="xs" color="text-gray-500" block style={{ fontSize: '10px' }}>Errors</Text>
                    <Text size="lg" weight="bold" color="text-red-400" block>{metrics.errors}</Text>
                  </Box>
                  <Box bg="bg-iron-gray" border={true} borderColor="border-charcoal-outline" rounded="md" p={2} textAlign="center">
                    <Text size="xs" color="text-gray-500" block style={{ fontSize: '10px' }}>API</Text>
                    <Text size="lg" weight="bold" color="text-blue-400" block>{metrics.apiRequests}</Text>
                  </Box>
                  <Box bg="bg-iron-gray" border={true} borderColor="border-charcoal-outline" rounded="md" p={2} textAlign="center">
                    <Text size="xs" color="text-gray-500" block style={{ fontSize: '10px' }}>Failures</Text>
                    <Text size="lg" weight="bold" color="text-yellow-400" block>{metrics.apiFailures}</Text>
                  </Box>
                </Box>
              )}

              {/* Actions */}
              {debugEnabled && (
                <Stack gap={2}>
                  <Text size="xs" weight="semibold" color="text-gray-400">Test Actions</Text>
                  <Box display="grid" gridCols={2} gap={2}>
                    <Button
                      onClick={triggerTestError}
                      variant="danger"
                      size="sm"
                    >
                      Test Error
                    </Button>
                    <Button
                      onClick={triggerTestApiCall}
                      size="sm"
                    >
                      Test API
                    </Button>
                  </Box>

                  <Text size="xs" weight="semibold" color="text-gray-400" mt={2}>Utilities</Text>
                  <Box display="grid" gridCols={2} gap={2}>
                    <Button
                      onClick={copyDebugInfo}
                      variant="secondary"
                      size="sm"
                    >
                      Copy Info
                    </Button>
                    <Button
                      onClick={clearAllLogs}
                      variant="secondary"
                      size="sm"
                    >
                      Clear Logs
                    </Button>
                  </Box>
                </Stack>
              )}

              {/* Quick Links */}
              {debugEnabled && (
                <Stack gap={1}>
                  <Text size="xs" weight="semibold" color="text-gray-400">Quick Access</Text>
                  <Box color="text-gray-500" font="mono" style={{ fontSize: '10px' }}>
                    <Text block>• window.__GRIDPILOT_GLOBAL_HANDLER__</Text>
                    <Text block>• window.__GRIDPILOT_API_LOGGER__</Text>
                    <Text block>• window.__GRIDPILOT_REACT_ERRORS__</Text>
                  </Box>
                </Stack>
              )}

              {/* Status */}
              <Box textAlign="center" pt={2} borderTop={true} borderColor="border-charcoal-outline">
                <Text size="xs" color="text-gray-500" style={{ fontSize: '10px' }}>
                  {debugEnabled ? 'Debug features active' : 'Debug mode disabled'}
                  {isDev && ' • Development Environment'}
                </Text>
              </Box>
            </Stack>
          </Box>
        </Box>
      )}
    </Box>
  );
}

/**
 * Hook for programmatic debug control
 */
export function useDebugMode() {
  const [debugEnabled, setDebugEnabled] = useState(false);

  useEffect(() => {
    const saved = localStorage.getItem('gridpilot_debug_enabled');
    setDebugEnabled(saved === 'true');
  }, []);

  const enable = useCallback(() => {
    setDebugEnabled(true);
    localStorage.setItem('gridpilot_debug_enabled', 'true');
    
    // Initialize debug features
    const globalHandler = getGlobalErrorHandler();
    globalHandler.initialize();

    const apiLogger = getGlobalApiLogger();
    if (!(window as any).__GRIDPILOT_FETCH_LOGGED__) {
      const loggedFetch = apiLogger.createLoggedFetch();
      window.fetch = loggedFetch as any;
      (window as any).__GRIDPILOT_FETCH_LOGGED__ = true;
    }

    (window as any).__GRIDPILOT_GLOBAL_HANDLER__ = globalHandler;
    (window as any).__GRIDPILOT_API_LOGGER__ = apiLogger;
  }, []);

  const disable = useCallback(() => {
    setDebugEnabled(false);
    localStorage.setItem('gridpilot_debug_enabled', 'false');
    
    const globalHandler = getGlobalErrorHandler();
    globalHandler.destroy();
  }, []);

  const toggle = useCallback(() => {
    if (debugEnabled) {
      disable();
    } else {
      enable();
    }
  }, [debugEnabled, enable, disable]);

  return {
    enabled: debugEnabled,
    enable,
    disable,
    toggle,
  };
}
