import 'package:flutter/material.dart';
import '../services/database_helper.dart';
import '../models/palm_record.dart';
import '../constants/mpob_colors.dart';
import '../services/app_strings.dart';
import '../theme/locale_controller.dart';
import 'batch_report_screen.dart';
import 'record_detail_screen.dart';

/// A group of [PalmRecord]s that share a batchId (or the fallback
/// "ungrouped" bucket for pre-migration records with no batchId).
class _BatchGroup {
  final String? batchId;
  final List<PalmRecord> records;

  _BatchGroup({required this.batchId, required this.records});

  DateTime get latestTimestamp => records.first.timestamp;

  String get dominantClass {
    final tally = <String, int>{};
    for (final r in records) {
      tally[r.ripenessClass] = (tally[r.ripenessClass] ?? 0) + 1;
    }
    return tally.entries.reduce((a, b) => a.value >= b.value ? a : b).key;
  }
}

/// A single record paired with the batch group it belongs to, so a flat
/// (ungrouped) list item can still open [RecordDetailScreen] with the full
/// batch as navigable frames.
class _FlatRecord {
  final PalmRecord record;
  final _BatchGroup group;
  _FlatRecord({required this.record, required this.group});
}

class HistoryScreen extends StatefulWidget {
  const HistoryScreen({super.key});

  @override
  State<HistoryScreen> createState() => _HistoryScreenState();
}

class _HistoryScreenState extends State<HistoryScreen> {
  final DatabaseHelper _dbHelper = DatabaseHelper();
  List<_BatchGroup> _allGroups = [];
  List<_BatchGroup> _groups = [];
  bool _isLoading = true;

  bool _sortAscending = false; // false = latest first (default)
  DateTimeRange? _dateRange;
  bool _flatView = false;

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

  Future<void> _loadHistory() async {
    final records = await _dbHelper.getAllRecords(); // already ordered timestamp DESC
    final Map<String, List<PalmRecord>> byBatch = {};
    for (final record in records) {
      final key = record.batchId ?? '__ungrouped__';
      byBatch.putIfAbsent(key, () => []).add(record);
    }

    final groups = byBatch.entries
        .map((e) => _BatchGroup(batchId: e.key == '__ungrouped__' ? null : e.key, records: e.value))
        .toList();

    setState(() {
      _allGroups = groups;
      _isLoading = false;
    });
    _applyFilters();
  }

  void _applyFilters() {
    var filtered = _allGroups;
    if (_dateRange != null) {
      filtered = filtered.where((g) {
        final d = g.latestTimestamp;
        return !d.isBefore(_dateRange!.start) && d.isBefore(_dateRange!.end.add(const Duration(days: 1)));
      }).toList();
    }
    filtered = [...filtered]
      ..sort((a, b) => _sortAscending
          ? a.latestTimestamp.compareTo(b.latestTimestamp)
          : b.latestTimestamp.compareTo(a.latestTimestamp));
    setState(() => _groups = filtered);
  }

  void _clearFilters() {
    setState(() {
      _sortAscending = false;
      _dateRange = null;
    });
    _applyFilters();
  }

  Future<void> _resetHistory() async {
    final errorColor = Theme.of(context).colorScheme.error;
    final confirm = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(AppStrings.t('history_reset_title')),
        content: Text(AppStrings.t('history_reset_message')),
        actions: [
          TextButton(onPressed: () => Navigator.pop(context, false), child: Text(AppStrings.t('cancel_button'))),
          TextButton(
            onPressed: () => Navigator.pop(context, true),
            child: Text(AppStrings.t('reset_button'), style: TextStyle(color: errorColor)),
          ),
        ],
      ),
    );

    if (confirm == true) {
      await _dbHelper.clearAllRecords();
      _loadHistory();
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text(AppStrings.t('history_cleared_snackbar'))),
        );
      }
    }
  }

  Future<bool> _confirmDelete(String message) async {
    final errorColor = Theme.of(context).colorScheme.error;
    final confirm = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(AppStrings.t('delete_button')),
        content: Text(message),
        actions: [
          TextButton(onPressed: () => Navigator.pop(context, false), child: Text(AppStrings.t('cancel_button'))),
          TextButton(
            onPressed: () => Navigator.pop(context, true),
            child: Text(AppStrings.t('delete_button'), style: TextStyle(color: errorColor)),
          ),
        ],
      ),
    );
    return confirm ?? false;
  }

  Future<void> _deleteGroup(_BatchGroup group) async {
    if (group.batchId != null) {
      await _dbHelper.deleteBatch(group.batchId!);
    } else {
      await _dbHelper.deleteRecord(group.records.first);
    }
    _loadHistory();
  }

  List<_FlatRecord> get _flatRecords {
    final all = <_FlatRecord>[
      for (final g in _groups)
        for (final r in g.records) _FlatRecord(record: r, group: g),
    ];
    all.sort((a, b) => _sortAscending
        ? a.record.timestamp.compareTo(b.record.timestamp)
        : b.record.timestamp.compareTo(a.record.timestamp));
    return all;
  }

  Future<void> _deleteSingleRecord(PalmRecord record) async {
    await _dbHelper.deleteRecord(record);
    _loadHistory();
  }

  bool get _hasActiveFilter => _dateRange != null || _sortAscending;

  Future<void> _openFilterSheet() async {
    await showModalBottomSheet(
      context: context,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      builder: (sheetContext) {
        return StatefulBuilder(
          builder: (sheetContext, setSheetState) {
            final colorScheme = Theme.of(sheetContext).colorScheme;
            return Padding(
              padding: const EdgeInsets.all(24),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(AppStrings.t('filter_sort_title'), style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
                      TextButton(
                        onPressed: () {
                          _clearFilters();
                          setSheetState(() {});
                        },
                        child: Text(AppStrings.t('reset_button')),
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(AppStrings.t('sort_order_label'), style: const TextStyle(fontWeight: FontWeight.w600)),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      Expanded(
                        child: ChoiceChip(
                          label: Text(AppStrings.t('sort_latest_first')),
                          selected: !_sortAscending,
                          selectedColor: colorScheme.primary,
                          labelStyle: TextStyle(color: !_sortAscending ? colorScheme.onPrimary : colorScheme.onSurface),
                          onSelected: (_) {
                            setState(() => _sortAscending = false);
                            setSheetState(() {});
                            _applyFilters();
                          },
                        ),
                      ),
                      const SizedBox(width: 12),
                      Expanded(
                        child: ChoiceChip(
                          label: Text(AppStrings.t('sort_oldest_first')),
                          selected: _sortAscending,
                          selectedColor: colorScheme.primary,
                          labelStyle: TextStyle(color: _sortAscending ? colorScheme.onPrimary : colorScheme.onSurface),
                          onSelected: (_) {
                            setState(() => _sortAscending = true);
                            setSheetState(() {});
                            _applyFilters();
                          },
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 24),
                  Text(AppStrings.t('date_range_label'), style: const TextStyle(fontWeight: FontWeight.w600)),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      Expanded(
                        child: OutlinedButton.icon(
                          icon: const Icon(Icons.date_range),
                          label: Text(
                            _dateRange == null
                                ? AppStrings.t('all_dates_label')
                                : "${_formatDate(_dateRange!.start)} – ${_formatDate(_dateRange!.end)}",
                          ),
                          onPressed: () async {
                            final now = DateTime.now();
                            final picked = await showDateRangePicker(
                              context: sheetContext,
                              firstDate: DateTime(now.year - 5),
                              lastDate: now,
                              initialDateRange: _dateRange,
                            );
                            if (picked != null) {
                              setState(() => _dateRange = picked);
                              setSheetState(() {});
                              _applyFilters();
                            }
                          },
                        ),
                      ),
                      if (_dateRange != null)
                        IconButton(
                          icon: const Icon(Icons.clear),
                          tooltip: AppStrings.t('clear_date_range_tooltip'),
                          onPressed: () {
                            setState(() => _dateRange = null);
                            setSheetState(() {});
                            _applyFilters();
                          },
                        ),
                    ],
                  ),
                  const SizedBox(height: 8),
                ],
              ),
            );
          },
        );
      },
    );
  }

  String _formatDate(DateTime d) => "${d.year}-${d.month.toString().padLeft(2, '0')}-${d.day.toString().padLeft(2, '0')}";

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<String>(
      valueListenable: LocaleController.localeCode,
      builder: (context, _, _) => _buildScaffold(context),
    );
  }

  Widget _buildScaffold(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppStrings.t('history_vault_title')),
        actions: [
          IconButton(
            icon: Icon(_flatView ? Icons.collections_bookmark : Icons.view_list),
            tooltip: _flatView ? AppStrings.t('view_toggle_batches_tooltip') : AppStrings.t('view_toggle_flat_tooltip'),
            onPressed: () => setState(() => _flatView = !_flatView),
          ),
          IconButton(
            icon: Icon(_hasActiveFilter ? Icons.filter_alt : Icons.filter_list),
            tooltip: AppStrings.t('filter_sort_title'),
            onPressed: _openFilterSheet,
          ),
          if (_allGroups.isNotEmpty)
            IconButton(
              icon: const Icon(Icons.delete_sweep),
              tooltip: AppStrings.t('reset_history_tooltip'),
              onPressed: _resetHistory,
            ),
        ],
      ),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : _groups.isEmpty
              ? _buildEmptyState()
              : _flatView
                  ? _buildFlatList()
                  : ListView.builder(
                      itemCount: _groups.length,
                      padding: const EdgeInsets.all(12),
                      itemBuilder: (context, index) => _buildGroupCard(_groups[index]),
                    ),
    );
  }

  Widget _buildFlatList() {
    final flat = _flatRecords;
    return ListView.builder(
      itemCount: flat.length,
      padding: const EdgeInsets.all(12),
      itemBuilder: (context, index) => _buildFlatTile(flat[index]),
    );
  }

  Widget _buildFlatTile(_FlatRecord entry) {
    final record = entry.record;
    final statusColor = getStatusColor(record.ripenessClass);
    return Dismissible(
      key: ValueKey('flat_${record.id}'),
      direction: DismissDirection.endToStart,
      background: _buildDeleteBackground(),
      confirmDismiss: (_) => _confirmDelete(AppStrings.t('history_delete_record_confirm')),
      onDismissed: (_) => _deleteSingleRecord(record),
      child: Card(
        margin: const EdgeInsets.only(bottom: 12),
        elevation: 3,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
        child: ListTile(
          leading: CircleAvatar(
            backgroundColor: statusColor.withValues(alpha: 0.2),
            child: Icon(Icons.spa, color: statusColor),
          ),
          title: Text(
            AppStrings.className(record.ripenessClass),
            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
          ),
          subtitle: Text(
            AppStrings.tp('record_conf_timestamp', {
              'percent': (record.confidence * 100).toStringAsFixed(1),
              'timestamp': record.timestamp.toString().split('.')[0],
            }),
            style: const TextStyle(fontSize: 12),
          ),
          trailing: const Icon(Icons.chevron_right),
          isThreeLine: true,
          onTap: () => Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => RecordDetailScreen(
                frames: entry.group.records,
                initialIndex: entry.group.records.indexOf(record),
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildEmptyState() {
    if (_allGroups.isEmpty) {
      return Center(child: Text(AppStrings.t('history_empty_no_records')));
    }
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text(AppStrings.t('history_empty_no_matches')),
          const SizedBox(height: 12),
          TextButton(onPressed: _clearFilters, child: Text(AppStrings.t('clear_filters_button'))),
        ],
      ),
    );
  }

  Widget _buildDeleteBackground() {
    final colorScheme = Theme.of(context).colorScheme;
    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      decoration: BoxDecoration(
        color: colorScheme.error,
        borderRadius: BorderRadius.circular(15),
      ),
      alignment: Alignment.centerRight,
      padding: const EdgeInsets.symmetric(horizontal: 24),
      child: Icon(Icons.delete, color: colorScheme.onError, size: 28),
    );
  }

  Widget _buildGroupCard(_BatchGroup group) {
    final key = ValueKey(group.batchId ?? 'record_${group.records.first.id}');

    // A single ungrouped legacy record: render exactly as before, no batch chrome.
    if (group.batchId == null && group.records.length == 1) {
      return Dismissible(
        key: key,
        direction: DismissDirection.endToStart,
        background: _buildDeleteBackground(),
        confirmDismiss: (_) => _confirmDelete(AppStrings.t('history_delete_record_confirm')),
        onDismissed: (_) => _deleteGroup(group),
        child: _buildRecordTile(group.records.first),
      );
    }

    final statusColor = getStatusColor(group.dominantClass);
    final start = group.records.last.timestamp;
    final end = group.records.first.timestamp;
    final timeRange = start.difference(end).inSeconds.abs() < 1
        ? _formatTime(end)
        : "${_formatTime(start)} – ${_formatTime(end)}";

    return Dismissible(
      key: key,
      direction: DismissDirection.endToStart,
      background: _buildDeleteBackground(),
      confirmDismiss: (_) => _confirmDelete(AppStrings.tp('history_delete_batch_confirm', {'count': '${group.records.length}'})),
      onDismissed: (_) => _deleteGroup(group),
      child: Card(
        margin: const EdgeInsets.only(bottom: 12),
        elevation: 3,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
        child: ListTile(
          leading: CircleAvatar(
            backgroundColor: statusColor.withValues(alpha: 0.2),
            child: Icon(Icons.collections_bookmark, color: statusColor),
          ),
          title: Text(
            group.batchId == null
                ? AppStrings.t('ungrouped_scans_label')
                : AppStrings.tp('batch_scans_label', {'count': '${group.records.length}'}),
            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
          ),
          subtitle: Text(
            AppStrings.tp('majority_label', {'className': AppStrings.className(group.dominantClass), 'timeRange': timeRange}),
            style: const TextStyle(fontSize: 12),
          ),
          trailing: const Icon(Icons.chevron_right),
          isThreeLine: true,
          onTap: group.batchId == null
              ? null
              : () => Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => BatchReportScreen(batchId: group.batchId!)),
                  ),
        ),
      ),
    );
  }

  Widget _buildRecordTile(PalmRecord record) {
    final statusColor = getStatusColor(record.ripenessClass);
    return Card(
      margin: const EdgeInsets.only(bottom: 12),
      elevation: 3,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: statusColor.withValues(alpha: 0.2),
          child: Icon(Icons.spa, color: statusColor),
        ),
        title: Text(
          AppStrings.className(record.ripenessClass),
          style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
        ),
        subtitle: Text(
          AppStrings.tp('record_conf_timestamp', {
            'percent': (record.confidence * 100).toStringAsFixed(1),
            'timestamp': record.timestamp.toString().split('.')[0],
          }),
          style: const TextStyle(fontSize: 12),
        ),
        trailing: const Icon(Icons.chevron_right),
        isThreeLine: true,
        onTap: () => Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => RecordDetailScreen(frames: [record], initialIndex: 0)),
        ),
      ),
    );
  }

  String _formatTime(DateTime t) => t.toString().split('.')[0];
}
