import 'package:flutter/material.dart';
import '../control_plane_status_client.dart';

class RuntimePanel extends StatefulWidget {
  final List<FleetEdgeView> edges;
  final String? selectedEdgeId;
  final ValueChanged<String> onSelectEdge;
  final ControlPlaneStatusRepository statusRepository;

  const RuntimePanel({
    super.key,
    required this.edges,
    required this.selectedEdgeId,
    required this.onSelectEdge,
    required this.statusRepository,
  });

  @override
  State<RuntimePanel> createState() => _RuntimePanelState();
}

class _RuntimePanelState extends State<RuntimePanel> {
  bool _isLoading = false;
  String? _error;
  EdgeOperationsResponseView? _operations;
  String? _lastCommandStatus;

  @override
  void initState() {
    super.initState();
    _fetchOperations();
  }

  @override
  void didUpdateWidget(RuntimePanel oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.selectedEdgeId != widget.selectedEdgeId) {
      _fetchOperations();
    }
  }

  Future<void> _fetchOperations() async {
    final edgeId = widget.selectedEdgeId;
    if (edgeId == null) return;
    setState(() {
      _isLoading = true;
      _error = null;
      _operations = null;
    });
    try {
      final ops = await widget.statusRepository.fetchEdgeOperations(edgeId);
      if (mounted && widget.selectedEdgeId == edgeId) {
        setState(() {
          _operations = ops;
          _isLoading = false;
        });
      }
    } catch (e) {
      if (mounted && widget.selectedEdgeId == edgeId) {
        setState(() {
          _error = e.toString();
          _isLoading = false;
        });
      }
    }
  }

  Future<void> _sendCommand(String operation) async {
    final edgeId = widget.selectedEdgeId;
    if (edgeId == null) return;
    setState(() {
      _isLoading = true;
      _lastCommandStatus = null;
    });
    try {
      final resp = await widget.statusRepository.sendEdgeCommand(edgeId, operation);
      if (mounted) {
        final isError = resp.status.toLowerCase() == 'error' ||
                        resp.status.toLowerCase() == 'failed' ||
                        resp.status.toLowerCase() == 'unsupported' ||
                        resp.error.isNotEmpty;
        setState(() {
          if (isError) {
            _lastCommandStatus = 'Failed: ${resp.status} - ${resp.error.isNotEmpty ? resp.error : resp.summary}';
          } else {
            _lastCommandStatus = 'Success: Command accepted (${resp.status}) - ID: ${resp.commandId}';
          }
          _isLoading = false;
        });
        _fetchOperations();
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _lastCommandStatus = 'Failed: ${e.toString()}';
          _isLoading = false;
        });
      }
    }
  }

  void _showAgentCommandDialog() {
    final selectorController = TextEditingController();
    final commandController = TextEditingController();

    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          backgroundColor: const Color(0xFF1E293B),
          title: const Text('Send Agent Command', style: TextStyle(color: Colors.white)),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: selectorController,
                style: const TextStyle(color: Colors.white),
                decoration: const InputDecoration(
                  labelText: 'Target Selector (e.g. node-1)',
                  labelStyle: TextStyle(color: Color(0xFF94A3B8)),
                ),
              ),
              const SizedBox(height: 12),
              TextField(
                controller: commandController,
                style: const TextStyle(color: Colors.white),
                decoration: const InputDecoration(
                  labelText: 'Command Name (parameters.command)',
                  labelStyle: TextStyle(color: Color(0xFF94A3B8)),
                ),
              ),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('Cancel', style: TextStyle(color: Color(0xFF94A3B8))),
            ),
            ElevatedButton(
              onPressed: () {
                final selector = selectorController.text.trim();
                final cmd = commandController.text.trim();
                if (selector.isNotEmpty && cmd.isNotEmpty) {
                  Navigator.pop(context);
                  _sendAgentCommand(selector, cmd);
                }
              },
              child: const Text('Send'),
            ),
          ],
        );
      },
    );
  }

  Future<void> _sendAgentCommand(String selector, String command) async {
    final edgeId = widget.selectedEdgeId;
    if (edgeId == null) return;
    if (selector.isEmpty || command.isEmpty) return;
    setState(() {
      _isLoading = true;
      _lastCommandStatus = null;
    });
    try {
      final resp = await widget.statusRepository.sendEdgeCommand(
        edgeId,
        'agent.command',
        targetSelector: selector,
        parameters: {'command': command},
      );
      if (mounted) {
        final isError = resp.status.toLowerCase() == 'error' ||
                        resp.status.toLowerCase() == 'failed' ||
                        resp.status.toLowerCase() == 'unsupported' ||
                        resp.error.isNotEmpty;
        setState(() {
          if (isError) {
            _lastCommandStatus = 'Failed: ${resp.status} - ${resp.error.isNotEmpty ? resp.error : resp.summary}';
          } else {
            _lastCommandStatus = 'Success: Command accepted (${resp.status}) - ID: ${resp.commandId}';
          }
          _isLoading = false;
        });
        _fetchOperations();
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _lastCommandStatus = 'Failed: ${e.toString()}';
          _isLoading = false;
        });
      }
    }
  }

  void _showAgentStatusDialog() {
    final selectorController = TextEditingController();

    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          backgroundColor: const Color(0xFF1E293B),
          title: const Text('Get Agent Status', style: TextStyle(color: Colors.white)),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: selectorController,
                style: const TextStyle(color: Colors.white),
                decoration: const InputDecoration(
                  labelText: 'Target Selector (e.g. node-1)',
                  labelStyle: TextStyle(color: Color(0xFF94A3B8)),
                ),
              ),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('Cancel', style: TextStyle(color: Color(0xFF94A3B8))),
            ),
            ElevatedButton(
              onPressed: () {
                final selector = selectorController.text.trim();
                if (selector.isNotEmpty) {
                  Navigator.pop(context);
                  _sendAgentStatus(selector);
                }
              },
              child: const Text('Send'),
            ),
          ],
        );
      },
    );
  }

  Future<void> _sendAgentStatus(String selector) async {
    final edgeId = widget.selectedEdgeId;
    if (edgeId == null) return;
    if (selector.isEmpty) return;
    setState(() {
      _isLoading = true;
      _lastCommandStatus = null;
    });
    try {
      final resp = await widget.statusRepository.sendEdgeCommand(
        edgeId,
        'agent.status',
        targetSelector: selector,
      );
      if (mounted) {
        final isError = resp.status.toLowerCase() == 'error' ||
                        resp.status.toLowerCase() == 'failed' ||
                        resp.status.toLowerCase() == 'unsupported' ||
                        resp.error.isNotEmpty;
        setState(() {
          if (isError) {
            _lastCommandStatus = 'Failed: ${resp.status} - ${resp.error.isNotEmpty ? resp.error : resp.summary}';
          } else {
            _lastCommandStatus = 'Success: Command accepted (${resp.status}) - ID: ${resp.commandId}';
          }
          _isLoading = false;
        });
        _fetchOperations();
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _lastCommandStatus = 'Failed: ${e.toString()}';
          _isLoading = false;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    if (widget.edges.isEmpty) {
      return const Center(
        child: Text(
          'Please connect and register at least one Edge first.',
          style: TextStyle(color: Color(0xFF94A3B8), fontSize: 14),
        ),
      );
    }

    final currentEdgeId = widget.selectedEdgeId ?? widget.edges.first.edgeId;
    final hasCurrentEdge = widget.edges.any((e) => e.edgeId == currentEdgeId);
    final dropdownValue = hasCurrentEdge ? currentEdgeId : (widget.edges.isNotEmpty ? widget.edges.first.edgeId : null);
    final selectedEdge = hasCurrentEdge ? widget.edges.firstWhere((e) => e.edgeId == currentEdgeId) : widget.edges.first;


    return Container(
      padding: const EdgeInsets.all(24),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          LayoutBuilder(
            builder: (context, headerConstraints) {
              final isNarrow = headerConstraints.maxWidth < 500;
              final headerTitle = const Text(
                'Operations & Domain Agents',
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white),
                overflow: TextOverflow.ellipsis,
              );
              final headerControls = Wrap(
                crossAxisAlignment: WrapCrossAlignment.center,
                spacing: 8,
                runSpacing: 8,
                children: [
                  if (widget.edges.isNotEmpty && dropdownValue != null) ...[
                    const Text('Active Edge: ', style: TextStyle(color: Color(0xFF94A3B8))),
                    DropdownButton<String>(
                      value: dropdownValue,
                      dropdownColor: const Color(0xFF1E293B),
                      style: const TextStyle(color: Colors.white),
                      underline: const SizedBox(),
                      items: widget.edges.map((e) {
                        return DropdownMenuItem<String>(
                          value: e.edgeId,
                          child: Text(e.edgeName.isNotEmpty ? e.edgeName : e.edgeId),
                        );
                      }).toList(),
                      onChanged: (val) {
                        if (val != null) widget.onSelectEdge(val);
                      },
                    ),
                  ],
                  IconButton(
                    icon: const Icon(Icons.refresh, color: Color(0xFF6366F1)),
                    onPressed: _fetchOperations,
                  ),
                ],
              );

              if (isNarrow) {
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    headerTitle,
                    const SizedBox(height: 12),
                    headerControls,
                  ],
                );
              } else {
                return Row(
                  children: [
                    Expanded(child: headerTitle),
                    const SizedBox(width: 16),
                    headerControls,
                  ],
                );
              }
            },
          ),
          const SizedBox(height: 24),
          if (_lastCommandStatus != null) ...[
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
              decoration: BoxDecoration(
                color: _lastCommandStatus!.startsWith('Success')
                    ? const Color(0xFF10B981).withValues(alpha: 0.1)
                    : const Color(0xFFEF4444).withValues(alpha: 0.1),
                borderRadius: BorderRadius.circular(8),
                border: Border.all(
                  color: _lastCommandStatus!.startsWith('Success')
                      ? const Color(0xFF10B981).withValues(alpha: 0.3)
                      : const Color(0xFFEF4444).withValues(alpha: 0.3),
                ),
              ),
              child: Row(
                children: [
                  Icon(
                    _lastCommandStatus!.startsWith('Success') ? Icons.check_circle_outline : Icons.error_outline,
                    color: _lastCommandStatus!.startsWith('Success') ? const Color(0xFF10B981) : const Color(0xFFEF4444),
                    size: 20,
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Text(
                      _lastCommandStatus!,
                      style: TextStyle(
                        color: _lastCommandStatus!.startsWith('Success') ? const Color(0xFFD1FAE5) : const Color(0xFFFEE2E2),
                        fontSize: 13,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                  ),
                  IconButton(
                    icon: const Icon(Icons.close, size: 16, color: Color(0xFF94A3B8)),
                    onPressed: () {
                      setState(() {
                        _lastCommandStatus = null;
                      });
                    },
                  ),
                ],
              ),
            ),
            const SizedBox(height: 20),
          ],
          Expanded(
            child: SingleChildScrollView(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text(
                    'System Gated Operations',
                    style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white),
                  ),
                  const SizedBox(height: 12),
                  Wrap(
                    spacing: 12,
                    runSpacing: 12,
                    children: [
                      ElevatedButton.icon(
                        onPressed: _isLoading ? null : () => _sendCommand('health.check'),
                        icon: const Icon(Icons.health_and_safety_outlined, size: 16),
                        label: const Text('Health Check'),
                        style: ElevatedButton.styleFrom(
                          backgroundColor: const Color(0xFF10B981),
                          foregroundColor: Colors.white,
                        ),
                      ),
                      ElevatedButton.icon(
                        onPressed: _isLoading ? null : _showAgentStatusDialog,
                        icon: const Icon(Icons.info_outline, size: 16),
                        label: const Text('Agent Status'),
                        style: ElevatedButton.styleFrom(
                          backgroundColor: const Color(0xFF3B82F6),
                          foregroundColor: Colors.white,
                        ),
                      ),
                      ElevatedButton.icon(
                        onPressed: _isLoading ? null : _showAgentCommandDialog,
                        icon: const Icon(Icons.terminal_outlined, size: 16),
                        label: const Text('Agent Command'),
                        style: ElevatedButton.styleFrom(
                          backgroundColor: const Color(0xFF6366F1),
                          foregroundColor: Colors.white,
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 32),
                  const Text(
                    'Domain Agents',
                    style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white),
                  ),
                  const SizedBox(height: 12),
                  _buildDomainAgentsGrid(selectedEdge),
                  const SizedBox(height: 32),
                  const Text(
                    'Operations Execution History',
                    style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white),
                  ),
                  const SizedBox(height: 12),
                  _buildOperationsHistory(),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildDomainAgentsGrid(FleetEdgeView edge) {
    final agents = edge.domainAgents;
    if (agents.isEmpty) {
      return Container(
        padding: const EdgeInsets.all(24),
        width: double.infinity,
        decoration: BoxDecoration(
          color: const Color(0xFF1E293B),
          borderRadius: BorderRadius.circular(12),
        ),
        child: const Center(
          child: Text(
            'No Domain Agents reported for this Edge.',
            style: TextStyle(color: Color(0xFF94A3B8), fontSize: 13),
          ),
        ),
      );
    }

    return LayoutBuilder(
      builder: (context, constraints) {
        final crossAxisCount = constraints.maxWidth > 600 ? 2 : 1;
        return GridView.builder(
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          itemCount: agents.length,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: crossAxisCount,
            crossAxisSpacing: 16,
            mainAxisSpacing: 16,
            mainAxisExtent: 150,
          ),
          itemBuilder: (context, index) {
            final agent = agents[index];
            final stateColor = _getLifecycleStateColor(agent.lifecycleState);

            return Card(
              color: const Color(0xFF1E293B),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12),
                side: BorderSide(color: stateColor.withValues(alpha: 0.3)),
              ),
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Expanded(
                          child: Text(
                            agent.agentKind.toUpperCase(),
                            style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Colors.white),
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                        const SizedBox(width: 8),
                        Container(
                          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
                          decoration: BoxDecoration(
                            color: stateColor.withValues(alpha: 0.15),
                            borderRadius: BorderRadius.circular(20),
                          ),
                          child: Text(
                            agent.lifecycleState.toUpperCase(),
                            style: TextStyle(color: stateColor, fontSize: 10, fontWeight: FontWeight.bold),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: 8),
                    Text(
                      agent.summary.isNotEmpty ? agent.summary : 'Available: ${agent.available}',
                      style: const TextStyle(color: Color(0xFF94A3B8), fontSize: 12),
                      maxLines: 2,
                      overflow: TextOverflow.ellipsis,
                    ),
                    if (agent.activeCommandId.isNotEmpty) ...[
                      const SizedBox(height: 6),
                      Text(
                        'Active Command: ${agent.activeCommandId}',
                        style: const TextStyle(color: Color(0xFF818CF8), fontSize: 11, fontFamily: 'monospace'),
                        overflow: TextOverflow.ellipsis,
                      ),
                    ],
                    const Spacer(),
                  ],
                ),
              ),
            );
          },
        );
      },
    );
  }

  Widget _buildOperationsHistory() {
    if (_isLoading && _operations == null) {
      return const Center(
        child: Padding(
          padding: EdgeInsets.all(24.0),
          child: CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation<Color>(Color(0xFF6366F1)),
          ),
        ),
      );
    }

    if (_error != null) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(24.0),
          child: Text('Error: $_error', style: const TextStyle(color: Color(0xFFEF4444))),
        ),
      );
    }

    final ops = _operations?.operations ?? [];
    if (ops.isEmpty) {
      return Container(
        padding: const EdgeInsets.all(24),
        width: double.infinity,
        decoration: BoxDecoration(
          color: const Color(0xFF1E293B),
          borderRadius: BorderRadius.circular(12),
        ),
        child: const Center(
          child: Text(
            'No operation executions recorded.',
            style: TextStyle(color: Color(0xFF94A3B8), fontSize: 13),
          ),
        ),
      );
    }

    return ListView.builder(
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      itemCount: ops.length,
      itemBuilder: (context, index) {
        final op = ops[index];
        final opColor = _getOpStatusColor(op.status);

        return Card(
          color: const Color(0xFF1E293B),
          margin: const EdgeInsets.only(bottom: 12),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
            side: BorderSide(color: const Color(0xFF334155)),
          ),
          child: ListTile(
            leading: Icon(
              op.status.toLowerCase() == 'success' ? Icons.check_circle : Icons.pending,
              color: opColor,
            ),
            title: Text(op.operation, style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.white)),
            subtitle: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const SizedBox(height: 4),
                Text(
                  'ID: ${op.commandId} | Selector: ${op.targetSelector.isNotEmpty ? op.targetSelector : "all"}',
                  style: const TextStyle(color: Color(0xFF64748B), fontSize: 11),
                ),
                if (op.summary.isNotEmpty) ...[
                  const SizedBox(height: 4),
                  Text(op.summary, style: const TextStyle(color: Color(0xFF94A3B8), fontSize: 12)),
                ],
                if (op.error.isNotEmpty) ...[
                  const SizedBox(height: 4),
                  Text('Error: ${op.error}', style: const TextStyle(color: Color(0xFFEF4444), fontSize: 12)),
                ],
              ],
            ),
            trailing: Container(
              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
              decoration: BoxDecoration(
                color: opColor.withValues(alpha: 0.1),
                borderRadius: BorderRadius.circular(4),
              ),
              child: Text(
                op.status.toUpperCase(),
                style: TextStyle(color: opColor, fontSize: 10, fontWeight: FontWeight.bold),
              ),
            ),
          ),
        );
      },
    );
  }

  Color _getLifecycleStateColor(String state) {
    switch (state.toLowerCase()) {
      case 'ready':
      case 'success':
        return const Color(0xFF10B981);
      case 'busy':
      case 'running':
        return const Color(0xFFF59E0B);
      case 'error':
      case 'failed':
        return const Color(0xFFEF4444);
      case 'unknown':
      default:
        return const Color(0xFF94A3B8);
    }
  }

  Color _getOpStatusColor(String status) {
    switch (status.toLowerCase()) {
      case 'success':
        return const Color(0xFF10B981);
      case 'accepted':
      case 'pending':
        return const Color(0xFFF59E0B);
      case 'error':
      case 'failed':
        return const Color(0xFFEF4444);
      default:
        return const Color(0xFF94A3B8);
    }
  }
}
