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 { Button } from '@/ui/Button';
import { Icon } from '@/ui/Icon';
import { Text } from '@/ui/Text';
import { FloatingAction } from '@/ui/FloatingAction';
import { DebugPanel } from '@/ui/DebugPanel';
import { StatGrid } from '@/ui/StatGrid';
import { Stack } from '@/ui/Stack';
import { ButtonGroup } from '@/ui/ButtonGroup';
import { Bug, Shield } from 'lucide-react';
import React, { useCallback, useEffect, useState } from 'react';

// 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 Error & { type?: string }).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.__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 (
    <React.Fragment>
      {/* Main Toggle Button */}
      {!isOpen && (
        <FloatingAction
          onClick={() => setIsOpen(true)}
          variant={debugEnabled ? 'primary' : 'secondary'}
          title={debugEnabled ? 'Debug Mode Active' : 'Enable Debug Mode'}
        >
          <Icon icon={Bug} size={5} />
        </FloatingAction>
      )}

      {/* Debug Panel */}
      {isOpen && (
        <DebugPanel 
          title="Debug Control" 
          onClose={() => setIsOpen(false)}
          icon={<Icon icon={Bug} size={4} intent="success" />}
        >
          <Stack gap={4}>
            {/* Debug Toggle */}
            <Stack align="center" justify="between">
              <ButtonGroup gap={2}>
                <Icon icon={Shield} size={4} intent={debugEnabled ? 'success' : 'low'} />
                <Text size="sm" weight="medium">Debug Mode</Text>
              </ButtonGroup>
              <Button
                onClick={toggleDebug}
                size="sm"
                variant={debugEnabled ? 'primary' : 'secondary'}
              >
                {debugEnabled ? 'ON' : 'OFF'}
              </Button>
            </Stack>

            {/* Metrics */}
            {debugEnabled && (
              <StatGrid
                variant="box"
                columns={3}
                stats={[
                  { label: 'Errors', value: metrics.errors, intent: 'critical', icon: Bug },
                  { label: 'API', value: metrics.apiRequests, intent: 'primary', icon: Bug },
                  { label: 'Failures', value: metrics.apiFailures, intent: 'warning', icon: Bug },
                ]}
              />
            )}

            {/* Actions */}
            {debugEnabled && (
              <Stack gap={2}>
                <Text size="xs" weight="semibold" variant="low" uppercase>Test Actions</Text>
                <ButtonGroup gap={2}>
                  <Button onClick={triggerTestError} variant="danger" size="sm" fullWidth>Test Error</Button>
                  <Button onClick={triggerTestApiCall} size="sm" fullWidth>Test API</Button>
                </ButtonGroup>

                <Text size="xs" weight="semibold" variant="low" uppercase>Utilities</Text>
                <ButtonGroup gap={2}>
                  <Button onClick={copyDebugInfo} variant="secondary" size="sm" fullWidth>Copy Info</Button>
                  <Button onClick={clearAllLogs} variant="secondary" size="sm" fullWidth>Clear Logs</Button>
                </ButtonGroup>
              </Stack>
            )}

            {/* Quick Links */}
            {debugEnabled && (
              <Stack gap={1}>
                <Text size="xs" weight="semibold" variant="low" uppercase>Quick Access</Text>
                <Stack gap={0.5}>
                  <Text size="xs" variant="low" font="mono">• window.__GRIDPILOT_GLOBAL_HANDLER__</Text>
                  <Text size="xs" variant="low" font="mono">• window.__GRIDPILOT_API_LOGGER__</Text>
                  <Text size="xs" variant="low" font="mono">• window.__GRIDPILOT_REACT_ERRORS__</Text>
                </Stack>
              </Stack>
            )}

            {/* Status */}
            <Stack align="center">
              <Text size="xs" variant="low">
                {debugEnabled ? 'Debug features active' : 'Debug mode disabled'}
                {isDev && ' • Development Environment'}
              </Text>
            </Stack>
          </Stack>
        </DebugPanel>
      )}
    </React.Fragment>
  );
}

/**
 * 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.__GRIDPILOT_FETCH_LOGGED__) {
      const loggedFetch = apiLogger.createLoggedFetch();
      window.fetch = loggedFetch as typeof fetch;
      window.__GRIDPILOT_FETCH_LOGGED__ = true;
    }

    window.__GRIDPILOT_GLOBAL_HANDLER__ = globalHandler;
    window.__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,
  };
}
