import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:share_plus/share_plus.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:meshcore_client/meshcore_client.dart';
import '../l10n/app_localizations.dart';

class PacketLogScreen extends StatefulWidget {
  final MeshCoreBleService bleService;

  const PacketLogScreen({super.key, required this.bleService});

  @override
  State<PacketLogScreen> createState() => _PacketLogScreenState();
}

class _PacketLogScreenState extends State<PacketLogScreen> {
  bool _autoScroll = true;
  final ScrollController _scrollController = ScrollController();
  String _searchQuery = '';
  PacketDirection? _filterDirection;

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  List<BlePacketLog> get _filteredLogs {
    var logs = widget.bleService.packetLogs;

    // Filter by direction
    if (_filterDirection != null) {
      logs = logs.where((log) => log.direction == _filterDirection).toList();
    }

    // Filter by search query
    if (_searchQuery.isNotEmpty) {
      final query = _searchQuery.toLowerCase();
      logs = logs.where((log) {
        return log.hexData.toLowerCase().contains(query) ||
            (log.description?.toLowerCase().contains(query) ?? false) ||
            log.summary.toLowerCase().contains(query);
      }).toList();
    }

    return logs;
  }

  Future<void> _exportLogs(BuildContext context) async {
    try {
      final logs = _filteredLogs;
      if (logs.isEmpty) {
        if (context.mounted) {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('No logs to export')));
        }
        return;
      }

      // Create CSV content
      final buffer = StringBuffer();
      buffer.writeln(
        'Timestamp,Direction,Size (bytes),Opcode Name,Code,Hex Data,Description',
      );
      for (final log in logs) {
        buffer.writeln(log.toCsvRow());
      }

      // Save to temporary file
      final tempDir = await getTemporaryDirectory();
      if (!context.mounted) return;
      final file = File(
        '${tempDir.path}/ble_packets_${DateTime.now().millisecondsSinceEpoch}.csv',
      );
      await file.writeAsString(buffer.toString());

      // Share the file
      if (!context.mounted) return;
      await SharePlus.instance.share(
        ShareParams(
          files: [XFile(file.path)],
          subject: 'MeshCore BLE Packet Logs',
          text: 'Exported ${logs.length} BLE packets from MeshCore SAR app',
        ),
      );
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Export failed: $e')));
      }
    }
  }

  Future<void> _exportAsText(BuildContext context) async {
    try {
      final logs = _filteredLogs;
      if (logs.isEmpty) {
        if (context.mounted) {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('No logs to export')));
        }
        return;
      }

      // Create text content
      final buffer = StringBuffer();
      buffer.writeln('MeshCore BLE Packet Logs');
      buffer.writeln('=' * 80);
      buffer.writeln('Exported: ${DateTime.now().toIso8601String()}');
      buffer.writeln('Total packets: ${logs.length}');
      buffer.writeln('=' * 80);
      buffer.writeln();

      for (final log in logs) {
        buffer.writeln(log.toLogString());
      }

      // Save to temporary file
      final tempDir = await getTemporaryDirectory();
      if (!context.mounted) return;
      final file = File(
        '${tempDir.path}/ble_packets_${DateTime.now().millisecondsSinceEpoch}.txt',
      );
      await file.writeAsString(buffer.toString());

      // Share the file
      if (!context.mounted) return;
      await SharePlus.instance.share(
        ShareParams(
          files: [XFile(file.path)],
          subject: 'MeshCore BLE Packet Logs',
          text: 'Exported ${logs.length} BLE packets from MeshCore SAR app',
        ),
      );
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Export failed: $e')));
      }
    }
  }

  void _copyToClipboard(BuildContext context, BlePacketLog log) {
    Clipboard.setData(ClipboardData(text: log.hexData));
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('Hex data copied to clipboard'),
        duration: Duration(seconds: 1),
      ),
    );
  }

  void _clearLogs(BuildContext context) {
    final parentContext = context; // Store parent context for setState
    showDialog(
      context: context,
      builder: (dialogContext) => AlertDialog(
        title: Text(AppLocalizations.of(dialogContext)!.clearAllData),
        content: const Text(
          'Are you sure you want to clear all packet logs? This cannot be undone.',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(dialogContext),
            child: Text(AppLocalizations.of(dialogContext)!.cancel),
          ),
          TextButton(
            onPressed: () {
              widget.bleService.clearPacketLogs();
              Navigator.pop(dialogContext);
              if (!mounted) return;
              setState(() {});
              if (parentContext.mounted) {
                ScaffoldMessenger.of(parentContext).showSnackBar(
                  const SnackBar(content: Text('Packet logs cleared')),
                );
              }
            },
            style: TextButton.styleFrom(foregroundColor: Colors.red),
            child: Text(AppLocalizations.of(dialogContext)!.clear),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final logs = _filteredLogs;

    return Scaffold(
      appBar: AppBar(
        title: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text('BLE Packet Logs'),
            Text(
              '${logs.length} packets',
              style: Theme.of(context).textTheme.bodySmall,
            ),
          ],
        ),
        actions: [
          // Direction filter
          PopupMenuButton<PacketDirection?>(
            icon: Icon(
              _filterDirection == null
                  ? Icons.filter_list
                  : _filterDirection == PacketDirection.rx
                  ? Icons.arrow_downward
                  : Icons.arrow_upward,
            ),
            tooltip: 'Filter by direction',
            onSelected: (direction) {
              setState(() {
                _filterDirection = direction;
              });
            },
            itemBuilder: (context) => [
              PopupMenuItem(
                value: null,
                child: Row(
                  children: [
                    Icon(
                      Icons.filter_list,
                      color: _filterDirection == null
                          ? Theme.of(context).colorScheme.primary
                          : null,
                    ),
                    const SizedBox(width: 8),
                    Text(
                      'All',
                      style: TextStyle(
                        fontWeight: _filterDirection == null
                            ? FontWeight.bold
                            : FontWeight.normal,
                      ),
                    ),
                  ],
                ),
              ),
              PopupMenuItem(
                value: PacketDirection.rx,
                child: Row(
                  children: [
                    Icon(
                      Icons.arrow_downward,
                      color: _filterDirection == PacketDirection.rx
                          ? Theme.of(context).colorScheme.primary
                          : null,
                    ),
                    const SizedBox(width: 8),
                    Text(
                      'RX (Received)',
                      style: TextStyle(
                        fontWeight: _filterDirection == PacketDirection.rx
                            ? FontWeight.bold
                            : FontWeight.normal,
                      ),
                    ),
                  ],
                ),
              ),
              PopupMenuItem(
                value: PacketDirection.tx,
                child: Row(
                  children: [
                    Icon(
                      Icons.arrow_upward,
                      color: _filterDirection == PacketDirection.tx
                          ? Theme.of(context).colorScheme.primary
                          : null,
                    ),
                    const SizedBox(width: 8),
                    Text(
                      'TX (Sent)',
                      style: TextStyle(
                        fontWeight: _filterDirection == PacketDirection.tx
                            ? FontWeight.bold
                            : FontWeight.normal,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
          // Auto-scroll toggle
          IconButton(
            icon: Icon(
              _autoScroll
                  ? Icons.vertical_align_bottom
                  : Icons.vertical_align_center,
            ),
            tooltip: _autoScroll ? 'Disable auto-scroll' : 'Enable auto-scroll',
            onPressed: () {
              setState(() {
                _autoScroll = !_autoScroll;
              });
            },
          ),
          // Export menu
          PopupMenuButton(
            icon: const Icon(Icons.share),
            tooltip: 'Export logs',
            itemBuilder: (context) => [
              const PopupMenuItem(
                value: 'csv',
                child: Row(
                  children: [
                    Icon(Icons.table_chart),
                    SizedBox(width: 8),
                    Text('Export as CSV'),
                  ],
                ),
              ),
              const PopupMenuItem(
                value: 'txt',
                child: Row(
                  children: [
                    Icon(Icons.text_snippet),
                    SizedBox(width: 8),
                    Text('Export as Text'),
                  ],
                ),
              ),
            ],
            onSelected: (value) {
              if (value == 'csv') {
                _exportLogs(context);
              } else if (value == 'txt') {
                _exportAsText(context);
              }
            },
          ),
          // Clear logs
          IconButton(
            icon: const Icon(Icons.delete_outline),
            tooltip: 'Clear logs',
            onPressed: () => _clearLogs(context),
          ),
        ],
      ),
      body: Column(
        children: [
          // Search bar
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              decoration: InputDecoration(
                hintText: 'Search logs...',
                prefixIcon: const Icon(Icons.search),
                suffixIcon: _searchQuery.isNotEmpty
                    ? IconButton(
                        icon: const Icon(Icons.clear),
                        onPressed: () {
                          setState(() {
                            _searchQuery = '';
                          });
                        },
                      )
                    : null,
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(8),
                ),
              ),
              onChanged: (value) {
                setState(() {
                  _searchQuery = value;
                });
              },
            ),
          ),
          // Logs list
          Expanded(
            child: logs.isEmpty
                ? Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(Icons.list_alt, size: 64, color: Colors.grey[400]),
                        const SizedBox(height: 16),
                        Text(
                          _searchQuery.isNotEmpty || _filterDirection != null
                              ? 'No matching packets found'
                              : 'No packets logged yet',
                          style: TextStyle(
                            fontSize: 16,
                            color: Colors.grey[600],
                          ),
                        ),
                        if (_searchQuery.isNotEmpty ||
                            _filterDirection != null) ...[
                          const SizedBox(height: 8),
                          TextButton.icon(
                            onPressed: () {
                              setState(() {
                                _searchQuery = '';
                                _filterDirection = null;
                              });
                            },
                            icon: const Icon(Icons.clear_all),
                            label: const Text('Clear filters'),
                          ),
                        ],
                      ],
                    ),
                  )
                : ListView.builder(
                    controller: _scrollController,
                    itemCount: logs.length,
                    itemBuilder: (context, index) {
                      final log = logs[index];

                      // Auto-scroll to bottom
                      if (_autoScroll && index == logs.length - 1) {
                        WidgetsBinding.instance.addPostFrameCallback((_) {
                          if (!mounted) return;
                          if (_scrollController.hasClients) {
                            _scrollController.animateTo(
                              _scrollController.position.maxScrollExtent,
                              duration: const Duration(milliseconds: 200),
                              curve: Curves.easeOut,
                            );
                          }
                        });
                      }

                      return _PacketLogCard(
                        log: log,
                        onCopy: () => _copyToClipboard(context, log),
                      );
                    },
                  ),
          ),
        ],
      ),
    );
  }
}

class _PacketLogCard extends StatelessWidget {
  final BlePacketLog log;
  final VoidCallback onCopy;

  const _PacketLogCard({required this.log, required this.onCopy});

  @override
  Widget build(BuildContext context) {
    final isRx = log.direction == PacketDirection.rx;
    final directionColor = isRx ? Colors.green : Colors.blue;
    final rxInfo = log.logRxDataInfo;

    return Card(
      margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
      child: ExpansionTile(
        leading: CircleAvatar(
          backgroundColor: directionColor.withValues(alpha: 0.2),
          child: Icon(
            isRx ? Icons.arrow_downward : Icons.arrow_upward,
            color: directionColor,
            size: 20,
          ),
        ),
        title: Row(
          children: [
            Text(
              isRx ? 'RX' : 'TX',
              style: TextStyle(
                fontWeight: FontWeight.bold,
                color: directionColor,
                fontSize: 12,
              ),
            ),
            const SizedBox(width: 8),
            Flexible(
              child: Text(
                log.responseCode != null ? log.opcodeName : 'N/A',
                style: const TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.w600,
                ),
                overflow: TextOverflow.ellipsis,
              ),
            ),
          ],
        ),
        subtitle: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const SizedBox(height: 4),
            Text(
              '${log.rawData.length} bytes • ${_formatTimestamp(log.timestamp)}',
              style: TextStyle(fontSize: 12, color: Colors.grey[600]),
            ),
          ],
        ),
        children: [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Wrap(
                  spacing: 10,
                  runSpacing: 10,
                  children: [
                    _FactCard(
                      icon: isRx ? Icons.call_received : Icons.call_made,
                      label: 'Direction',
                      value: isRx ? 'RX' : 'TX',
                      accent: directionColor,
                    ),
                    _FactCard(
                      icon: Icons.data_object,
                      label: 'Size',
                      value: '${log.rawData.length} bytes',
                    ),
                    _FactCard(
                      icon: Icons.schedule,
                      label: 'Captured',
                      value: _formatTimestamp(log.timestamp),
                    ),
                    if (log.responseCode != null)
                      _FactCard(
                        icon: Icons.sell,
                        label: 'Opcode',
                        value: log.opcodeName,
                      ),
                  ],
                ),
                if (rxInfo?.rssiDbm != null || rxInfo?.snrDb != null) ...[
                  const SizedBox(height: 12),
                  Container(
                    padding: const EdgeInsets.all(12),
                    decoration: BoxDecoration(
                      color: Theme.of(context)
                          .colorScheme
                          .surfaceContainerHighest
                          .withValues(alpha: 0.5),
                      borderRadius: BorderRadius.circular(10),
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const Text(
                          'Link Quality',
                          style: TextStyle(
                            fontWeight: FontWeight.w700,
                            fontSize: 12,
                          ),
                        ),
                        const SizedBox(height: 10),
                        if (rxInfo?.rssiDbm != null)
                          _SignalMeter(
                            label: 'RSSI',
                            valueLabel: '${rxInfo!.rssiDbm} dBm',
                            normalized: _normalizeRssi(
                              rxInfo.rssiDbm!.toDouble(),
                            ),
                            color: _rssiColor(rxInfo.rssiDbm!.toDouble()),
                          ),
                        if (rxInfo?.snrDb != null) ...[
                          const SizedBox(height: 8),
                          _SignalMeter(
                            label: 'SNR',
                            valueLabel:
                                '${rxInfo!.snrDb!.toStringAsFixed(1)} dB',
                            normalized: _normalizeSnr(rxInfo.snrDb!),
                            color: _snrColor(rxInfo.snrDb!),
                          ),
                        ],
                      ],
                    ),
                  ),
                ],
                const SizedBox(height: 12),
                Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(10),
                    border: Border.all(
                      color: Theme.of(
                        context,
                      ).dividerColor.withValues(alpha: 0.5),
                    ),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          const Icon(Icons.grid_view_rounded, size: 16),
                          const SizedBox(width: 6),
                          const Text(
                            'Hex Explorer',
                            style: TextStyle(fontWeight: FontWeight.w700),
                          ),
                          const Spacer(),
                          IconButton(
                            onPressed: onCopy,
                            tooltip: 'Copy full hex',
                            icon: const Icon(Icons.copy_all_rounded, size: 18),
                            visualDensity: VisualDensity.compact,
                          ),
                        ],
                      ),
                      const SizedBox(height: 8),
                      Wrap(
                        spacing: 6,
                        runSpacing: 6,
                        children: [
                          for (var i = 0; i < log.rawData.length; i++)
                            _HexByteChip(
                              index: i,
                              value: log.rawData[i],
                              onTap: () {
                                _copyText(
                                  context,
                                  log.rawData[i]
                                      .toRadixString(16)
                                      .padLeft(2, '0')
                                      .toUpperCase(),
                                  'Byte ${i.toString().padLeft(2, '0')} copied',
                                );
                              },
                            ),
                        ],
                      ),
                      const SizedBox(height: 8),
                      ExpansionTile(
                        tilePadding: EdgeInsets.zero,
                        dense: true,
                        visualDensity: VisualDensity.compact,
                        title: const Text(
                          'Raw stream',
                          style: TextStyle(
                            fontSize: 12,
                            fontWeight: FontWeight.w600,
                          ),
                        ),
                        children: [
                          Container(
                            width: double.infinity,
                            padding: const EdgeInsets.all(10),
                            decoration: BoxDecoration(
                              color: Theme.of(context)
                                  .colorScheme
                                  .surfaceContainerHighest
                                  .withValues(alpha: 0.35),
                              borderRadius: BorderRadius.circular(8),
                            ),
                            child: SelectableText(
                              log.hexData,
                              style: const TextStyle(
                                fontFamily: 'monospace',
                                fontSize: 12,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  String _formatTimestamp(DateTime timestamp) {
    final now = DateTime.now();
    final diff = now.difference(timestamp);

    if (diff.inSeconds < 60) {
      return '${diff.inSeconds}s ago';
    } else if (diff.inMinutes < 60) {
      return '${diff.inMinutes}m ago';
    } else if (diff.inHours < 24) {
      return '${diff.inHours}h ago';
    } else {
      return '${timestamp.hour.toString().padLeft(2, '0')}:${timestamp.minute.toString().padLeft(2, '0')}:${timestamp.second.toString().padLeft(2, '0')}';
    }
  }

  static void _copyText(BuildContext context, String text, String message) {
    Clipboard.setData(ClipboardData(text: text));
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        duration: const Duration(milliseconds: 900),
      ),
    );
  }

  static double _normalizeRssi(double rssi) {
    return ((rssi + 120.0) / 70.0).clamp(0.0, 1.0);
  }

  static double _normalizeSnr(double snr) {
    return ((snr + 20.0) / 40.0).clamp(0.0, 1.0);
  }

  static Color _rssiColor(double rssi) {
    if (rssi >= -80) return Colors.green;
    if (rssi >= -95) return Colors.amber;
    return Colors.redAccent;
  }

  static Color _snrColor(double snr) {
    if (snr >= 10) return Colors.green;
    if (snr >= 0) return Colors.amber;
    return Colors.redAccent;
  }
}

class _FactCard extends StatelessWidget {
  final IconData icon;
  final String label;
  final String value;
  final Color? accent;

  const _FactCard({
    required this.icon,
    required this.label,
    required this.value,
    this.accent,
  });

  @override
  Widget build(BuildContext context) {
    final tileColor = accent ?? Theme.of(context).colorScheme.primary;
    return Container(
      constraints: const BoxConstraints(minWidth: 108),
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
      decoration: BoxDecoration(
        color: tileColor.withValues(alpha: 0.1),
        borderRadius: BorderRadius.circular(10),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(icon, size: 14, color: tileColor),
          const SizedBox(width: 8),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(
                label,
                style: TextStyle(fontSize: 10, color: Colors.grey[700]),
              ),
              Text(
                value,
                style: const TextStyle(
                  fontSize: 12,
                  fontWeight: FontWeight.w700,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class _SignalMeter extends StatelessWidget {
  final String label;
  final String valueLabel;
  final double normalized;
  final Color color;

  const _SignalMeter({
    required this.label,
    required this.valueLabel,
    required this.normalized,
    required this.color,
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        SizedBox(
          width: 42,
          child: Text(
            label,
            style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 12),
          ),
        ),
        Expanded(
          child: ClipRRect(
            borderRadius: BorderRadius.circular(5),
            child: LinearProgressIndicator(
              minHeight: 8,
              value: normalized,
              backgroundColor: color.withValues(alpha: 0.15),
              valueColor: AlwaysStoppedAnimation<Color>(color),
            ),
          ),
        ),
        const SizedBox(width: 10),
        SizedBox(
          width: 74,
          child: Text(
            valueLabel,
            textAlign: TextAlign.right,
            style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600),
          ),
        ),
      ],
    );
  }
}

class _HexByteChip extends StatelessWidget {
  final int index;
  final int value;
  final VoidCallback onTap;

  const _HexByteChip({
    required this.index,
    required this.value,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    final text = value.toRadixString(16).padLeft(2, '0').toUpperCase();
    return Tooltip(
      message: 'Byte $index',
      waitDuration: const Duration(milliseconds: 250),
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(7),
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 5),
          decoration: BoxDecoration(
            color: Theme.of(
              context,
            ).colorScheme.surfaceContainerHighest.withValues(alpha: 0.8),
            borderRadius: BorderRadius.circular(7),
          ),
          child: Text(
            text,
            style: const TextStyle(
              fontFamily: 'monospace',
              fontSize: 11,
              fontWeight: FontWeight.w700,
            ),
          ),
        ),
      ),
    );
  }
}
