/**
 * Application principale Visual Workflow Builder V2
 * Auteur : Dom, Alice, Kiro - 09 janvier 2026
 * 
 * Interface moderne pour la création de workflows d'automatisation RPA
 * avec sélection visuelle basée sur la vision et terminologie française.
 */

import { useState, useCallback, useMemo, useEffect, Component, ErrorInfo, ReactNode } from 'react';
import {
  Box,
  CssBaseline,
  ThemeProvider,
  createTheme,
  AppBar,
  Toolbar,
  Typography,
  Tabs,
  Tab,
  Drawer,
  Alert,
  AlertTitle,
  Button,
} from '@mui/material';
import { Provider } from 'react-redux';
import { ReactFlowProvider } from '@xyflow/react';
import { store } from './store';

// Composants principaux
import Canvas from './components/Canvas';
import Palette from './components/Palette';
import PropertiesPanel from './components/PropertiesPanel';
import VariableManager from './components/VariableManager';
import DocumentationTab from './components/DocumentationTab';
import Validator from './components/Validator';
import Executor from './components/Executor';
import WorkflowManager from './components/WorkflowManager';
import ContextualHelp from './components/ContextualHelp';
import KeyboardShortcuts from './components/KeyboardShortcuts';
import AccessibilityProvider from './components/AccessibilityProvider';
import ConnectionIndicator from './components/ConnectionIndicator';
import TestCatalogLoader from './components/TestCatalogLoader';
import VWBIntegrationTest from './components/VWBIntegrationTest';

// Hooks personnalisés
import { useKeyboardNavigation } from './hooks/useKeyboardNavigation';
import { useResponsiveLayout } from './hooks/useResponsiveLayout';

// Import des types partagés
import {
  Step,
  Variable,
  StepTemplate,
  StepCategory,
  Position,
  Workflow,
  WorkflowConnection,
  StepExecutionState,
} from './types';

// Error Boundary pour gérer les erreurs de l'application
interface ErrorBoundaryState {
  hasError: boolean;
  error?: Error;
  errorInfo?: ErrorInfo;
}

class AppErrorBoundary extends Component<
  { children: ReactNode },
  ErrorBoundaryState
> {
  constructor(props: { children: ReactNode }) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    // Met à jour l'état pour afficher l'interface d'erreur
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // Log l'erreur pour le debugging
    console.error('Erreur capturée par Error Boundary:', error, errorInfo);
    this.setState({
      error,
      errorInfo,
    });
  }

  render() {
    if (this.state.hasError) {
      return (
        <Box
          sx={{
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            minHeight: '100vh',
            p: 3,
          }}
        >
          <Alert severity="error" sx={{ maxWidth: 600, mb: 2 }}>
            <AlertTitle>Une erreur inattendue s'est produite</AlertTitle>
            <Typography variant="body2" gutterBottom>
              L'application a rencontré une erreur et ne peut pas continuer.
            </Typography>
            {this.state.error && (
              <Typography variant="caption" component="pre" sx={{ mt: 1 }}>
                {this.state.error.message}
              </Typography>
            )}
          </Alert>
          <Button
            variant="contained"
            onClick={() => window.location.reload()}
            sx={{ mt: 2 }}
          >
            Recharger l'application
          </Button>
        </Box>
      );
    }

    return this.props.children;
  }
}

// Thème Material-UI personnalisé avec couleurs françaises - mémorisé pour éviter les re-créations
const theme = createTheme({
  palette: {
    primary: {
      main: '#1976d2', // Bleu français
    },
    secondary: {
      main: '#dc004e', // Rouge français
    },
    background: {
      default: '#fafafa',
      paper: '#ffffff',
    },
  },
  typography: {
    fontFamily: '"Segoe UI", "Roboto", "Helvetica", "Arial", sans-serif',
  },
  components: {
    MuiAppBar: {
      styleOverrides: {
        root: {
          backgroundColor: '#ffffff',
          color: '#1976d2',
          boxShadow: '0 1px 3px rgba(0,0,0,0.12)',
        },
      },
    },
  },
});

/**
 * Composant principal de l'application
 */
function App() {
  // États principaux
  const [selectedStep, setSelectedStep] = useState<Step | null>(null);
  const [variables, setVariables] = useState<Variable[]>([]);
  const [searchTerm, setSearchTerm] = useState('');
  const [activeDocTab, setActiveDocTab] = useState(0);
  const [isDocDrawerOpen, setIsDocDrawerOpen] = useState(false);
  const [showKeyboardShortcuts, setShowKeyboardShortcuts] = useState(false);
  
  // Hooks d'accessibilité et responsivité
  const responsiveLayout = useResponsiveLayout();
  
  // État du workflow
  const [workflow, setWorkflow] = useState<Workflow>({
    id: 'workflow_1',
    name: 'Nouveau Workflow',
    description: 'Workflow créé avec le Visual Workflow Builder V2',
    steps: [],
    connections: [],
    variables: [],
    createdAt: new Date(),
    updatedAt: new Date(),
  });

  // Configuration de la navigation au clavier
  const keyboardNavigation = useKeyboardNavigation({
    onStepSelect: (stepId: string) => {
      const step = workflow.steps.find(s => s.id === stepId);
      if (step) handleStepSelect(step);
    },
    onStepMove: (stepId: string, direction: 'up' | 'down' | 'left' | 'right') => {
      const step = workflow.steps.find(s => s.id === stepId);
      if (step) {
        const moveDistance = 20;
        const newPosition = { ...step.position };
        
        switch (direction) {
          case 'up': newPosition.y -= moveDistance; break;
          case 'down': newPosition.y += moveDistance; break;
          case 'left': newPosition.x -= moveDistance; break;
          case 'right': newPosition.x += moveDistance; break;
        }
        
        handleStepMove(stepId, newPosition);
      }
    },
    onStepDelete: (stepId: string) => handleStepDelete(stepId),
    onSave: () => console.log('Sauvegarde via clavier'),
    onHelp: () => setShowKeyboardShortcuts(true),
    selectedStepId: selectedStep?.id,
    availableStepIds: workflow.steps.map(s => s.id),
    isEnabled: true,
  });

  // Gestionnaires d'événements optimisés avec useCallback
  const handleStepSelect = useCallback((step: Step | null) => {
    setSelectedStep(step);
  }, []);

  // Synchroniser selectedStep avec le workflow quand celui-ci change
  // Ceci corrige le bug où les paramètres (visual_anchor) ne sont pas persistés dans l'UI
  useEffect(() => {
    if (selectedStep) {
      const updatedStep = workflow.steps.find(s => s.id === selectedStep.id);
      if (updatedStep) {
        // Vérifier si les données ont changé avant de mettre à jour
        const currentDataStr = JSON.stringify(selectedStep.data);
        const updatedDataStr = JSON.stringify(updatedStep.data);
        if (currentDataStr !== updatedDataStr) {
          setSelectedStep(updatedStep);
        }
      }
    }
  }, [workflow.steps, selectedStep?.id]);

  const handleStepMove = useCallback((stepId: string, position: Position) => {
    console.log('Déplacement étape:', stepId, position);
    setWorkflow(prev => ({
      ...prev,
      steps: prev.steps.map(step => 
        step.id === stepId ? { ...step, position } : step
      ),
      updatedAt: new Date(),
    }));
  }, []);

  const handleConnection = (source: string, target: string) => {
    console.log('Connexion:', source, '->', target);
    const newConnection: WorkflowConnection = {
      id: `conn_${Date.now()}`,
      source,
      target,
    };
    setWorkflow(prev => ({
      ...prev,
      connections: [...prev.connections, newConnection],
      updatedAt: new Date(),
    }));
  };

  const handleStepAdd = (stepData: Omit<Step, 'id'>) => {
    console.log('Ajout étape:', stepData);
    const newStep: Step = {
      ...stepData,
      id: `step_${Date.now()}`,
      executionState: StepExecutionState.IDLE,
      validationErrors: [],
    };
    
    setWorkflow(prev => ({
      ...prev,
      steps: [...prev.steps, newStep],
      updatedAt: new Date(),
    }));
  };

  const handleStepDelete = (stepId: string) => {
    console.log('Suppression étape:', stepId);
    setWorkflow(prev => ({
      ...prev,
      steps: prev.steps.filter(step => step.id !== stepId),
      connections: prev.connections.filter(conn =>
        conn.source !== stepId && conn.target !== stepId
      ),
      updatedAt: new Date(),
    }));

    // Désélectionner l'étape si elle était sélectionnée
    if (selectedStep?.id === stepId) {
      setSelectedStep(null);
    }
  };

  const handleConnectionDelete = (connectionId: string) => {
    console.log('Suppression connexion:', connectionId);
    setWorkflow(prev => ({
      ...prev,
      connections: prev.connections.filter(conn => conn.id !== connectionId),
      updatedAt: new Date(),
    }));
  };

  const handleParameterChange = (stepId: string, param: string, value: any) => {
    console.log('Changement paramètre:', stepId, param, value);
    setWorkflow(prev => ({
      ...prev,
      steps: prev.steps.map(step => 
        step.id === stepId 
          ? { 
              ...step, 
              data: { 
                ...step.data, 
                parameters: { 
                  ...step.data.parameters, 
                  [param]: value 
                } 
              } 
            }
          : step
      ),
      updatedAt: new Date(),
    }));
  };

  const handleVisualSelection = (stepId: string) => {
    console.log('Sélection visuelle pour étape:', stepId);
    // La sélection visuelle est maintenant gérée par le VisualSelector dans PropertiesPanel
  };

  const handleStepHighlight = (stepId: string, highlight: boolean) => {
    // Mise en évidence des étapes pour la validation
    console.log('Mise en évidence étape:', stepId, highlight ? 'activée' : 'désactivée');
  };

  const handleStepStateChange = (stepId: string, state: StepExecutionState) => {
    setWorkflow(prev => ({
      ...prev,
      steps: prev.steps.map(step => 
        step.id === stepId ? { ...step, executionState: state } : step
      ),
      updatedAt: new Date(),
    }));
  };

  const handleExecutionComplete = (success: boolean, summary: any) => {
    console.log('Exécution terminée:', success ? 'Succès' : 'Échec', summary);
  };

  const handleWorkflowLoad = (loadedWorkflow: Workflow) => {
    console.log('📥 [App] Chargement workflow:', {
      name: loadedWorkflow.name,
      stepsCount: loadedWorkflow.steps?.length || 0,
      connectionsCount: loadedWorkflow.connections?.length || 0,
      steps: loadedWorkflow.steps,
    });

    // S'assurer que les étapes ont des positions valides
    const workflowWithPositions: Workflow = {
      ...loadedWorkflow,
      steps: (loadedWorkflow.steps || []).map((step, index) => ({
        ...step,
        position: step.position || { x: 100 + (index % 3) * 200, y: 100 + Math.floor(index / 3) * 150 },
      })),
    };

    setWorkflow(workflowWithPositions);
    // Charger les variables du workflow
    setVariables(workflowWithPositions.variables || []);
    setSelectedStep(null);
    console.log('✅ [App] Workflow appliqué avec', workflowWithPositions.steps.length, 'étapes et', (workflowWithPositions.variables || []).length, 'variables');
  };

  const handleWorkflowSave = (savedWorkflow: Workflow) => {
    setWorkflow(savedWorkflow);
    console.log('Workflow sauvegardé:', savedWorkflow.name);
  };

  const handleStepDrag = (stepTemplate: StepTemplate) => {
    console.log('Début drag étape:', stepTemplate);
    // Cette fonction est appelée quand le drag commence depuis la palette
    // La logique de drop est gérée dans le Canvas
  };

  // Gestion des variables
  const handleVariableCreate = (variable: Omit<Variable, 'id'>) => {
    const newVariable: Variable = {
      ...variable,
      id: `var_${Date.now()}`,
    };
    const updatedVariables = [...variables, newVariable];
    setVariables(updatedVariables);
    // Synchroniser avec le workflow pour la sauvegarde
    setWorkflow(prev => ({ ...prev, variables: updatedVariables, updatedAt: new Date() }));
  };

  const handleVariableUpdate = (id: string, updates: Partial<Variable>) => {
    const updatedVariables = variables.map(v => v.id === id ? { ...v, ...updates } : v);
    setVariables(updatedVariables);
    // Synchroniser avec le workflow pour la sauvegarde
    setWorkflow(prev => ({ ...prev, variables: updatedVariables, updatedAt: new Date() }));
  };

  const handleVariableDelete = (id: string) => {
    const updatedVariables = variables.filter(v => v.id !== id);
    setVariables(updatedVariables);
    // Synchroniser avec le workflow pour la sauvegarde
    setWorkflow(prev => ({ ...prev, variables: updatedVariables, updatedAt: new Date() }));
  };

  // Onglets de documentation
  const docTabs = [
    { id: 'canvas', label: 'Canvas', toolName: 'canvas' },
    { id: 'palette', label: 'Palette', toolName: 'palette' },
    { id: 'properties', label: 'Propriétés', toolName: 'properties' },
    { id: 'test', label: 'Test Catalogue', toolName: 'test' },
    { id: 'vwb-test', label: 'Test VWB', toolName: 'vwb-test' },
  ];

  // Mode 100% Visuel - Pas de catégories par défaut
  // Seules les actions VisionOnly du catalogue sont utilisées
  const defaultCategories: StepCategory[] = [];

  return (
    <AppErrorBoundary>
        <AccessibilityProvider>
          <Provider store={store}>
            <ThemeProvider theme={theme}>
              <ReactFlowProvider>
              <CssBaseline />
              <Box sx={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
                {/* Barre d'application */}
                <AppBar position="static" elevation={1}>
                  <Toolbar>
                    <Typography variant="h6" component="h1" sx={{ flexGrow: 1 }}>
                      Visual Workflow Builder V2
                    </Typography>
                    
                    {/* Gestionnaire de workflows */}
                    <Box sx={{ mr: 2 }}>
                      <WorkflowManager
                        currentWorkflow={workflow}
                        onWorkflowLoad={handleWorkflowLoad}
                        onWorkflowSave={handleWorkflowSave}
                      />
                    </Box>
                    
                    {/* Indicateur de connexion API */}
                    <Box sx={{ mr: 2 }}>
                      <ConnectionIndicator compact showRefreshButton />
                    </Box>
                    
                    <Tabs
                      value={activeDocTab}
                      onChange={(_, newValue) => {
                        setActiveDocTab(newValue);
                        setIsDocDrawerOpen(true);
                      }}
                      textColor="inherit"
                      indicatorColor="secondary"
                    >
                      <Tab label="Aide Canvas" />
                      <Tab label="Aide Palette" />
                      <Tab label="Aide Propriétés" />
                      <Tab label="Test Catalogue" />
                      <Tab label="Test VWB" />
                    </Tabs>
                  </Toolbar>
                </AppBar>

                {/* Interface principale */}
                <Box sx={{ display: 'flex', flex: 1, overflow: 'hidden' }}>
                  {/* Palette d'étapes - Responsive */}
                  <Box 
                    sx={responsiveLayout.getResponsiveStyles('palette')}
                    role="complementary"
                    aria-label="Palette d'étapes disponibles"
                  >
                    <Palette
                      categories={defaultCategories}
                      searchTerm={searchTerm}
                      onSearch={setSearchTerm}
                      onStepDrag={handleStepDrag}
                    />
                  </Box>

                  {/* Canvas principal */}
                  <Box 
                    sx={{ flex: 1, display: 'flex', flexDirection: 'column' }}
                    role="main"
                    aria-label="Zone principale de création de workflow"
                  >
                    {/* Validateur et Exécuteur en haut */}
                    <Box sx={{ 
                      display: 'flex', 
                      borderBottom: '1px solid #e0e0e0', 
                      backgroundColor: '#ffffff',
                      flexDirection: responsiveLayout.isMobile ? 'column' : 'row'
                    }}
                    role="toolbar"
                    aria-label="Outils de validation et d'exécution"
                    >
                      {/* Validateur */}
                      <Box sx={{ 
                        flex: 1, 
                        p: responsiveLayout.isMobile ? 1 : 2, 
                        borderRight: responsiveLayout.isMobile ? 'none' : '1px solid #e0e0e0',
                        borderBottom: responsiveLayout.isMobile ? '1px solid #e0e0e0' : 'none'
                      }}
                      role="region"
                      aria-label="Validation du workflow"
                      >
                        <Validator
                          workflow={workflow}
                          variables={variables}
                          onStepHighlight={handleStepHighlight}
                        />
                      </Box>
                      
                      {/* Exécuteur */}
                      <Box 
                        sx={{ flex: 1, p: responsiveLayout.isMobile ? 1 : 2 }}
                        role="region"
                        aria-label="Exécution du workflow"
                      >
                        <Executor
                          workflow={workflow}
                          canExecute={workflow.steps.length > 0}
                          onStepStateChange={handleStepStateChange}
                          onExecutionComplete={handleExecutionComplete}
                        />
                      </Box>
                    </Box>
                    
                    <Canvas
                      workflow={workflow}
                      selectedStep={selectedStep}
                      onStepSelect={handleStepSelect}
                      onStepMove={handleStepMove}
                      onConnection={handleConnection}
                      onConnectionDelete={handleConnectionDelete}
                      onStepAdd={handleStepAdd}
                      onStepDelete={handleStepDelete}
                    />
                    
                    {/* Gestionnaire de variables - Responsive */}
                    <Box sx={{
                      ...responsiveLayout.getResponsiveStyles('variables'),
                      borderTop: '1px solid #e0e0e0',
                      backgroundColor: '#ffffff',
                      p: responsiveLayout.isMobile ? 1 : 2,
                      overflow: 'auto',
                    }}
                    role="region"
                    aria-label="Gestionnaire de variables"
                    >
                      <VariableManager
                        variables={variables}
                        onVariableCreate={handleVariableCreate}
                        onVariableUpdate={handleVariableUpdate}
                        onVariableDelete={handleVariableDelete}
                      />
                    </Box>
                  </Box>

                  {/* Panneau de propriétés - Responsive */}
                  <Box 
                    sx={responsiveLayout.getResponsiveStyles('properties')}
                    role="complementary"
                    aria-label="Panneau de propriétés de l'étape sélectionnée"
                  >
                    <PropertiesPanel
                      selectedStep={selectedStep}
                      variables={variables}
                      onParameterChange={handleParameterChange}
                      onVisualSelection={handleVisualSelection}
                    />
                  </Box>
                </Box>

                {/* Tiroir de documentation */}
                <Drawer
                  anchor="right"
                  open={isDocDrawerOpen}
                  onClose={() => setIsDocDrawerOpen(false)}
                  sx={{
                    '& .MuiDrawer-paper': {
                      width: responsiveLayout.isMobile ? '100%' : 400,
                      boxSizing: 'border-box',
                    },
                  }}
                >
                  {activeDocTab === 3 ? (
                    <TestCatalogLoader />
                  ) : activeDocTab === 4 ? (
                    <VWBIntegrationTest />
                  ) : (
                    <DocumentationTab
                      toolName={docTabs[activeDocTab]?.toolName || 'canvas'}
                      isActive={isDocDrawerOpen}
                      onActivate={() => setIsDocDrawerOpen(true)}
                    />
                  )}
                </Drawer>

                {/* Aide contextuelle */}
                <ContextualHelp
                  context={selectedStep ? 'properties' : 'canvas'}
                  selectedStepType={selectedStep?.type}
                  currentErrors={[]} // TODO: Intégrer avec le validateur
                  isVisible={!responsiveLayout.isMobile} // Masquer sur mobile pour éviter l'encombrement
                />

                {/* Dialogue des raccourcis clavier */}
                <KeyboardShortcuts
                  open={showKeyboardShortcuts}
                  onClose={() => setShowKeyboardShortcuts(false)}
                  shortcuts={keyboardNavigation.shortcuts}
                />
              </Box>
            </ReactFlowProvider>
          </ThemeProvider>
        </Provider>
      </AccessibilityProvider>
    </AppErrorBoundary>
  );
}

export default App;