import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'dart:math';

import '../data/disease_data.dart';
import '../logic/fuzzy_mamdani.dart';
import '../models/disease.dart';
import '../models/symptom.dart';
import 'result_page.dart';

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

  @override
  State<DiagnosisPage> createState() => _DiagnosisPageState();
}

class _DiagnosisPageState extends State<DiagnosisPage>
    with TickerProviderStateMixin {
  final FuzzyMamdani fuzzyMamdani = FuzzyMamdani();
  Map<String, double> selectedSymptoms = {};
  List<Symptom> filteredSymptoms = symptoms;
  final TextEditingController _searchController = TextEditingController();
  final TextEditingController _historySearchController =
      TextEditingController();
  bool isLoading = false;
  List<Map<String, dynamic>> history = [];
  List<Map<String, dynamic>> filteredHistory = [];
  late AnimationController _scaleController;
  late AnimationController _dotController;
  late AnimationController _textScaleController;
  late Animation<double> _scaleAnimation;
  late Animation<int> _dotAnimation;
  late Animation<double> _textScaleAnimation;
  late AnimationController _countScaleController;
  late Animation<double> _countScaleAnimation;
  late TabController _tabController;
  final List<AnimationController> _fadeControllers = [];
  final List<AnimationController> _slideControllers = [];
  String sortOrder = 'Terbaru';
  final List<String> loadingMessages = [
    'Menganalisis gejala...',
    'Memeriksa tanaman...',
    'Mendiagnosis...',
    'Memproses data...',
  ];
  final Map<int, bool> expandedSymptoms = {};

  @override
  void initState() {
    super.initState();
    _searchController.addListener(filterAndSortSymptoms);
    _historySearchController.addListener(filterHistory);

    _tabController = TabController(length: 2, vsync: this);
    _tabController.addListener(() {
      if (mounted) setState(() {});
    });

    _scaleController = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );
    _scaleAnimation = Tween<double>(begin: 0.5, end: 1.0).animate(
      CurvedAnimation(parent: _scaleController, curve: Curves.easeOutBack),
    );

    _dotController = AnimationController(
      duration: const Duration(milliseconds: 1500),
      vsync: this,
    )..repeat();
    _dotAnimation = IntTween(begin: 0, end: 3).animate(
      CurvedAnimation(parent: _dotController, curve: Curves.linear),
    );

    _textScaleController = AnimationController(
      duration: const Duration(milliseconds: 600),
      vsync: this,
    )..repeat(reverse: true);
    _textScaleAnimation = Tween<double>(begin: 0.9, end: 1.1).animate(
      CurvedAnimation(parent: _textScaleController, curve: Curves.easeInOut),
    );

    _countScaleController = AnimationController(
      duration: const Duration(milliseconds: 200),
      vsync: this,
    );
    _countScaleAnimation = Tween<double>(begin: 1.0, end: 1.2).animate(
      CurvedAnimation(parent: _countScaleController, curve: Curves.elasticOut),
    );

    _loadHistory();
  }

  Future<void> _loadHistory() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final historyData = prefs.getStringList('diagnosis_history') ?? [];
      List<Map<String, dynamic>> tempHistory = [];
      for (var item in historyData) {
        var entry = jsonDecode(item) as Map<String, dynamic>;
        var results = entry['results'] as Map<String, dynamic>;
        var updatedResults = Map<String, Map<String, dynamic>>.from(results);
        for (var resultEntry in updatedResults.entries) {
          if (!resultEntry.value.containsKey('matchedSymptoms')) {
            resultEntry.value['matchedSymptoms'] =
                (entry['selectedSymptoms'] as Map<String, dynamic>)
                    .keys
                    .toList();
          }
          resultEntry.value['confidence'] =
              resultEntry.value['confidence'] ?? 0.0;
          resultEntry.value['matchPercentage'] =
              resultEntry.value['matchPercentage'] ?? 0.0;
          resultEntry.value['recommendation'] =
              resultEntry.value['recommendation'] ?? '';
          resultEntry.value['totalWeight'] =
              resultEntry.value['totalWeight'] ?? 0.0;
        }
        entry['results'] = updatedResults;
        tempHistory.add(entry);
      }
      if (mounted) {
        setState(() {
          history = tempHistory;
          filteredHistory = List.from(history);
          sortHistory();
          _fadeControllers.clear();
          _slideControllers.clear();
          for (var i = 0; i < history.length; i++) {
            final fadeController = AnimationController(
              duration: const Duration(milliseconds: 500),
              vsync: this,
            )..forward();
            final slideController = AnimationController(
              duration: const Duration(milliseconds: 500),
              vsync: this,
            )..forward();
            _fadeControllers.add(fadeController);
            _slideControllers.add(slideController);
          }
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          history = [];
          filteredHistory = [];
        });
      }
    }
  }

  Future<void> _saveHistory(Map<String, Map<String, dynamic>> results) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final timestamp = DateTime.now().toIso8601String();
      final updatedResults = Map<String, Map<String, dynamic>>.from(results);
      for (var entry in updatedResults.entries) {
        if (!entry.value.containsKey('matchedSymptoms')) {
          entry.value['matchedSymptoms'] = selectedSymptoms.keys.toList();
        }
      }
      final historyEntry = {
        'timestamp': timestamp,
        'selectedSymptoms': selectedSymptoms.map((key, value) =>
            MapEntry(key, symptoms.firstWhere((s) => s.id == key).description)),
        'results': updatedResults.map(
            (key, value) => MapEntry(key, Map<String, dynamic>.from(value))),
      };
      final historyData = prefs.getStringList('diagnosis_history') ?? [];
      historyData.add(jsonEncode(historyEntry));
      if (historyData.length > 50) historyData.removeAt(0);
      await prefs.setStringList('diagnosis_history', historyData);
      await _loadHistory();
    } catch (e) {}
  }

  Future<void> _deleteHistoryEntry(int index) async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        shape:
            RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
        backgroundColor: Colors.white,
        elevation: 10,
        title: Row(
          children: const [
            Icon(Icons.warning_rounded, color: Color(0xFFAC2B36), size: 28.0),
            SizedBox(width: 10),
            Text('Konfirmasi',
                style: TextStyle(
                    fontSize: 20.0,
                    fontWeight: FontWeight.bold,
                    color: Color(0xFFAC2B36))),
          ],
        ),
        content: const Text('Apakah Anda yakin ingin menghapus riwayat ini?',
            style:
                TextStyle(fontSize: 16.0, color: Colors.black87, height: 1.5)),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: const Text('Batal',
                style: TextStyle(fontSize: 16.0, color: Colors.grey)),
          ),
          ElevatedButton(
            onPressed: () => Navigator.pop(context, true),
            style: ElevatedButton.styleFrom(
              backgroundColor: const Color(0xFFAC2B36),
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10.0)),
            ),
            child: const Text('Hapus',
                style: TextStyle(fontSize: 16.0, color: Colors.white)),
          ),
        ],
      ),
    );

    if (confirmed == true) {
      try {
        final prefs = await SharedPreferences.getInstance();
        final historyData = prefs.getStringList('diagnosis_history') ?? [];
        final reversedIndex = history.length - 1 - index;
        historyData.removeAt(reversedIndex);
        await prefs.setStringList('diagnosis_history', historyData);
        await _loadHistory();
      } catch (e) {}
    }
  }

  Future<void> _clearHistory() async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        shape:
            RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
        backgroundColor: Colors.white,
        elevation: 10,
        title: Row(
          children: const [
            Icon(Icons.warning_rounded, color: Color(0xFFAC2B36), size: 28.0),
            SizedBox(width: 10),
            Text('Konfirmasi',
                style: TextStyle(
                    fontSize: 20.0,
                    fontWeight: FontWeight.bold,
                    color: Color(0xFFAC2B36))),
          ],
        ),
        content: const Text('Apakah Anda yakin ingin menghapus semua riwayat?',
            style:
                TextStyle(fontSize: 16.0, color: Colors.black87, height: 1.5)),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: const Text('Batal',
                style: TextStyle(fontSize: 16.0, color: Colors.grey)),
          ),
          ElevatedButton(
            onPressed: () => Navigator.pop(context, true),
            style: ElevatedButton.styleFrom(
              backgroundColor: const Color(0xFFAC2B36),
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10.0)),
            ),
            child: const Text('Hapus',
                style: TextStyle(fontSize: 16.0, color: Colors.white)),
          ),
        ],
      ),
    );

    if (confirmed == true) {
      try {
        final prefs = await SharedPreferences.getInstance();
        await prefs.remove('diagnosis_history');
        if (mounted) {
          setState(() {
            history = [];
            filteredHistory = [];
            _fadeControllers.clear();
            _slideControllers.clear();
          });
        }
      } catch (e) {}
    }
  }

  void filterAndSortSymptoms() {
    final query = _searchController.text.trim().toLowerCase();
    if (mounted) {
      setState(() {
        filteredSymptoms = query.isEmpty
            ? symptoms
            : symptoms
                .where((symptom) =>
                    symptom.description.toLowerCase().contains(query))
                .toList();
      });
    }
  }

  void filterHistory() {
    final query = _historySearchController.text.trim().toLowerCase();
    if (mounted) {
      setState(() {
        filteredHistory = query.isEmpty
            ? List.from(history)
            : history.where((entry) {
                final results = entry['results'] as Map<String, dynamic>;
                final topDisease = results.entries
                    .where((e) => e.value['confidence'] >= 10)
                    .toList()
                  ..sort((a, b) =>
                      b.value['confidence'].compareTo(a.value['confidence']));
                final diseaseName = topDisease.isNotEmpty
                    ? diseases
                        .firstWhere(
                          (d) => d.id == topDisease[0].key,
                          orElse: () => Disease(
                              id: '',
                              name: 'Tidak Diketahui',
                              symptomIds: [],
                              solutions: []),
                        )
                        .name
                        .toLowerCase()
                    : 'tidak diketahui';
                return diseaseName.contains(query);
              }).toList();
        sortHistory();
      });
    }
  }

  void sortHistory() {
    if (mounted) {
      setState(() {
        filteredHistory.sort((a, b) {
          final dateA = DateTime.parse(a['timestamp']);
          final dateB = DateTime.parse(b['timestamp']);
          return sortOrder == 'Terbaru'
              ? dateB.compareTo(dateA)
              : dateA.compareTo(dateB);
        });
      });
    }
  }

  void toggleSymptom(Symptom symptom) {
    if (mounted) {
      setState(() {
        if (selectedSymptoms.containsKey(symptom.id)) {
          selectedSymptoms.remove(symptom.id);
        } else {
          selectedSymptoms[symptom.id] = symptom.weight;
        }
        _countScaleController.forward(from: 0.0);
      });
    }
  }

  void onDiagnose() async {
    if (selectedSymptoms.isEmpty) {
      _scaleController.forward(from: 0.0);
      await showDialog(
        context: context,
        builder: (context) => ScaleTransition(
          scale: _scaleAnimation,
          child: AlertDialog(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(15.0)),
            backgroundColor: Colors.white,
            elevation: 10,
            title: Row(
              children: const [
                Icon(Icons.local_florist, color: Color(0xFFAC2B36), size: 28.0),
                SizedBox(width: 10),
                Text(
                  'Peringatan',
                  style: TextStyle(
                      fontSize: 20.0,
                      fontWeight: FontWeight.bold,
                      color: Color(0xFFAC2B36)),
                ),
              ],
            ),
            content: const Text(
              'Pilih setidaknya satu gejala untuk melanjutkan.',
              style:
                  TextStyle(fontSize: 16.0, color: Colors.black87, height: 1.5),
            ),
            actions: [
              Padding(
                padding: const EdgeInsets.only(right: 8.0, bottom: 8.0),
                child: ElevatedButton(
                  onPressed: () => Navigator.pop(context),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: const Color(0xFF4CAF50),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10.0)),
                  ),
                  child: const Text(
                    'OK',
                    style: TextStyle(
                        fontSize: 16.0,
                        color: Colors.white,
                        fontWeight: FontWeight.bold),
                  ),
                ),
              ),
            ],
          ),
        ),
      );
      return;
    }

    setState(() {
      isLoading = true;
    });

    _scaleController.forward(from: 0.0);
    _textScaleController.forward(from: 0.0);

    final randomMessage =
        loadingMessages[Random().nextInt(loadingMessages.length)];

    showDialog(
      context: context,
      barrierDismissible: false,
      barrierColor: Colors.black.withOpacity(0.2),
      builder: (context) => Dialog(
        backgroundColor: Colors.transparent,
        elevation: 0,
        child: FadeTransition(
          opacity: _scaleAnimation,
          child: Container(
            width: 180,
            padding: const EdgeInsets.all(12.0),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(12.0),
              border: Border.all(color: const Color(0xFFAC2B36), width: 1.0),
              boxShadow: [
                BoxShadow(
                  color: Colors.black.withOpacity(0.1),
                  blurRadius: 6,
                  offset: const Offset(0, 2),
                ),
              ],
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const CircularProgressIndicator(
                    color: Color(0xFFAC2B36), strokeWidth: 2.5),
                const SizedBox(height: 8),
                AnimatedBuilder(
                  animation: _textScaleController,
                  builder: (context, child) {
                    String dots = '.' * (_dotAnimation.value % 4);
                    return Transform.scale(
                      scale: _textScaleAnimation.value,
                      child: Text(
                        '$randomMessage$dots',
                        style: const TextStyle(
                            fontSize: 13.0,
                            fontWeight: FontWeight.w600,
                            color: Color(0xFFAC2B36)),
                        textAlign: TextAlign.center,
                      ),
                    );
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );

    final results = fuzzyMamdani.diagnose(selectedSymptoms);
    await _saveHistory(results);
    await Future.delayed(const Duration(seconds: 3));

    Navigator.pop(context);

    setState(() {
      isLoading = false;
    });

    final shouldRefresh = await Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => ResultPage(results: results)),
    );

    if (mounted) {
      setState(() {
        if (shouldRefresh == true) {
          selectedSymptoms.clear();
          _countScaleController.forward(from: 0.0);
        }
        sortHistory();
        if (_tabController.index == 1) filterHistory();
      });
    }
  }

  Future<bool> _showExitConfirmation() async {
    return await showDialog<bool>(
          context: context,
          builder: (context) => AlertDialog(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(15.0)),
            backgroundColor: Colors.white,
            elevation: 10,
            title: Row(
              children: const [
                Icon(Icons.warning_rounded,
                    color: Color(0xFFAC2B36), size: 28.0),
                SizedBox(width: 10),
                Text('Konfirmasi Keluar',
                    style: TextStyle(
                        fontSize: 20.0,
                        fontWeight: FontWeight.bold,
                        color: Color(0xFFAC2B36))),
              ],
            ),
            content: const Text(
              'Apakah Anda yakin ingin keluar dari aplikasi? Perubahan yang belum disimpan akan hilang.',
              style:
                  TextStyle(fontSize: 16.0, color: Colors.black87, height: 1.5),
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context, false),
                child: const Text('Batal',
                    style: TextStyle(fontSize: 16.0, color: Colors.grey)),
              ),
              ElevatedButton(
                onPressed: () => Navigator.pop(context, true),
                style: ElevatedButton.styleFrom(
                  backgroundColor: const Color(0xFFAC2B36),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10.0)),
                ),
                child: const Text('Keluar',
                    style: TextStyle(fontSize: 16.0, color: Colors.white)),
              ),
            ],
          ),
        ) ??
        false;
  }

  @override
  void dispose() {
    _searchController.dispose();
    _historySearchController.dispose();
    _scaleController.dispose();
    _dotController.dispose();
    _textScaleController.dispose();
    _countScaleController.dispose();
    _tabController.dispose();
    for (var controller in _fadeControllers) controller.dispose();
    for (var controller in _slideControllers) controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      onPopInvokedWithResult: (didPop, result) async {
        if (didPop) return;
        final shouldExit = await _showExitConfirmation();
        if (shouldExit && mounted) SystemNavigator.pop();
      },
      child: DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.white,
            elevation: 2,
            iconTheme: const IconThemeData(color: Colors.black),
            title: const Text('RawitCare',
                style: TextStyle(
                    fontSize: 24.0,
                    fontWeight: FontWeight.bold,
                    color: Colors.black)),
            centerTitle: true,
            bottom: TabBar(
              controller: _tabController,
              labelColor: const Color(0xFFAC2B36),
              unselectedLabelColor: Colors.grey,
              indicatorColor: const Color(0xFFAC2B36),
              tabs: const [
                Tab(text: 'Diagnosis'),
                Tab(text: 'Riwayat'),
              ],
            ),
          ),
          body: TabBarView(
            controller: _tabController,
            children: [
              Column(
                children: [
                  Padding(
                    padding: const EdgeInsets.symmetric(
                        horizontal: 16.0, vertical: 8.0),
                    child: TextField(
                      controller: _searchController,
                      decoration: InputDecoration(
                        hintText: 'Cari gejala...',
                        prefixIcon:
                            const Icon(Icons.search, color: Colors.grey),
                        suffixIcon: _searchController.text.isNotEmpty
                            ? IconButton(
                                icon:
                                    const Icon(Icons.clear, color: Colors.grey),
                                onPressed: () => _searchController.clear(),
                              )
                            : null,
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10.0),
                          borderSide: const BorderSide(color: Colors.grey),
                        ),
                        focusedBorder: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10.0),
                          borderSide:
                              const BorderSide(color: Color(0xFF4CAF50)),
                        ),
                        contentPadding:
                            const EdgeInsets.symmetric(vertical: 10.0),
                      ),
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 16.0),
                    child: ScaleTransition(
                      scale: _countScaleAnimation,
                      child: Text(
                        'Gejala yang dipilih: ${selectedSymptoms.length}',
                        style:
                            const TextStyle(fontSize: 14.0, color: Colors.grey),
                      ),
                    ),
                  ),
                  Expanded(
                    child: ListView.builder(
                      physics: const BouncingScrollPhysics(),
                      padding: const EdgeInsets.all(16.0),
                      itemCount: filteredSymptoms.length,
                      itemBuilder: (context, index) {
                        final symptom = filteredSymptoms[index];
                        final isSelected =
                            selectedSymptoms.containsKey(symptom.id);
                        return Padding(
                          padding: const EdgeInsets.symmetric(vertical: 8.0),
                          child: GestureDetector(
                            onTap: () => toggleSymptom(symptom),
                            child: Container(
                              padding: const EdgeInsets.symmetric(
                                  vertical: 16.0, horizontal: 20.0),
                              decoration: BoxDecoration(
                                color: isSelected
                                    ? const Color(0xFF4CAF50)
                                    : Colors.white,
                                borderRadius: BorderRadius.circular(10.0),
                                border: Border.all(
                                    color: const Color(0xFF4CAF50), width: 1.0),
                              ),
                              child: Row(
                                children: [
                                  Icon(
                                    isSelected
                                        ? Icons.check_circle
                                        : Icons.circle_outlined,
                                    color:
                                        isSelected ? Colors.white : Colors.grey,
                                  ),
                                  const SizedBox(width: 10),
                                  Expanded(
                                    child: Text(
                                      symptom.description,
                                      style: TextStyle(
                                          fontSize: 16.0,
                                          color: isSelected
                                              ? Colors.white
                                              : Colors.black),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        );
                      },
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: SizedBox(
                      width: double.infinity,
                      height: 50.0,
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                          backgroundColor: const Color(0xFFAC2B36),
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(10.0)),
                        ),
                        onPressed: isLoading
                            ? null
                            : () {
                                HapticFeedback.lightImpact();
                                onDiagnose();
                              },
                        child: const Text('Diagnosa',
                            style:
                                TextStyle(fontSize: 16.0, color: Colors.white)),
                      ),
                    ),
                  ),
                ],
              ),
              Column(
                children: [
                  Padding(
                    padding: const EdgeInsets.symmetric(
                        horizontal: 16.0, vertical: 8.0),
                    child: Row(
                      children: [
                        Expanded(
                          child: TextField(
                            controller: _historySearchController,
                            decoration: InputDecoration(
                              hintText: 'Cari penyakit...',
                              prefixIcon:
                                  const Icon(Icons.search, color: Colors.grey),
                              suffixIcon:
                                  _historySearchController.text.isNotEmpty
                                      ? IconButton(
                                          icon: const Icon(Icons.clear,
                                              color: Colors.grey),
                                          onPressed: () =>
                                              _historySearchController.clear(),
                                        )
                                      : null,
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(10.0),
                                borderSide:
                                    const BorderSide(color: Colors.grey),
                              ),
                              focusedBorder: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(10.0),
                                borderSide:
                                    const BorderSide(color: Color(0xFF4CAF50)),
                              ),
                              contentPadding:
                                  const EdgeInsets.symmetric(vertical: 10.0),
                            ),
                          ),
                        ),
                        const SizedBox(width: 8),
                        DropdownButton<String>(
                          value: sortOrder,
                          items: ['Terbaru', 'Terlama'].map((order) {
                            return DropdownMenuItem(
                              value: order,
                              child: Text(
                                order,
                                style: TextStyle(
                                  fontSize: 14.0,
                                  color: Colors.black87,
                                  fontWeight: sortOrder == order
                                      ? FontWeight.bold
                                      : FontWeight.normal,
                                ),
                              ),
                            );
                          }).toList(),
                          onChanged: (value) {
                            if (mounted) {
                              setState(() {
                                sortOrder = value!;
                                sortHistory();
                              });
                            }
                          },
                          underline: Container(),
                          icon:
                              const Icon(Icons.sort, color: Color(0xFFAC2B36)),
                          dropdownColor: Colors.white,
                          borderRadius: BorderRadius.circular(10.0),
                        ),
                      ],
                    ),
                  ),
                  if (filteredHistory.isNotEmpty)
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 16.0),
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                          backgroundColor: const Color(0xFFAC2B36),
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(10.0)),
                        ),
                        onPressed: _clearHistory,
                        child: const Text('Hapus Semua Riwayat',
                            style:
                                TextStyle(fontSize: 16.0, color: Colors.white)),
                      ),
                    ),
                  Expanded(
                    child: filteredHistory.isEmpty
                        ? Center(
                            child: Text(
                              _historySearchController.text.isEmpty
                                  ? 'Belum ada riwayat diagnosis.'
                                  : 'Tidak ada riwayat yang cocok dengan pencarian.',
                              style: const TextStyle(
                                  fontSize: 16.0, color: Colors.grey),
                            ),
                          )
                        : ListView.builder(
                            padding: const EdgeInsets.all(16.0),
                            itemCount: filteredHistory.length,
                            itemBuilder: (context, index) {
                              final entry = filteredHistory[index];
                              final results =
                                  entry['results'] as Map<String, dynamic>;
                              final topDisease = results.entries
                                  .where((e) => e.value['confidence'] >= 10)
                                  .toList()
                                ..sort((a, b) => b.value['confidence']
                                    .compareTo(a.value['confidence']));
                              final diseaseName = topDisease.isNotEmpty
                                  ? diseases
                                      .firstWhere(
                                        (d) => d.id == topDisease[0].key,
                                        orElse: () => Disease(
                                            id: '',
                                            name: 'Tidak Diketahui',
                                            symptomIds: [],
                                            solutions: []),
                                      )
                                      .name
                                  : 'Tidak Diketahui';
                              final confidence = topDisease.isNotEmpty
                                  ? topDisease[0].value['confidence']
                                  : 0.0;
                              final confidenceStr =
                                  confidence.toStringAsFixed(1);
                              final symptomsList = (entry['selectedSymptoms']
                                      as Map<String, dynamic>)
                                  .values
                                  .toList();
                              final isExpanded =
                                  expandedSymptoms[index] ?? false;

                              return FadeTransition(
                                opacity: _fadeControllers[index]
                                    .drive(Tween(begin: 0.0, end: 1.0)),
                                child: SlideTransition(
                                  position: _slideControllers[index].drive(
                                      Tween<Offset>(
                                          begin: const Offset(0.1, 0),
                                          end: Offset.zero)),
                                  child: Card(
                                    elevation: 3,
                                    shape: RoundedRectangleBorder(
                                        borderRadius:
                                            BorderRadius.circular(10.0)),
                                    margin: const EdgeInsets.symmetric(
                                        vertical: 8.0),
                                    child: Container(
                                      decoration: BoxDecoration(
                                        color: Colors.white,
                                        borderRadius:
                                            BorderRadius.circular(10.0),
                                      ),
                                      child: Column(
                                        children: [
                                          ListTile(
                                            contentPadding:
                                                const EdgeInsets.all(16.0),
                                            leading: Tooltip(
                                              message: confidence >= 70
                                                  ? 'Risiko Tinggi'
                                                  : 'Kondisi Stabil',
                                              child: Icon(
                                                confidence >= 70
                                                    ? Icons
                                                        .local_fire_department
                                                    : Icons.local_florist,
                                                color: confidence >= 70
                                                    ? const Color(0xFFAC2B36)
                                                    : const Color(0xFF4CAF50),
                                                size: 28.0,
                                              ),
                                            ),
                                            title: Text(
                                              '$diseaseName ($confidenceStr%)',
                                              style: const TextStyle(
                                                  fontSize: 18.0,
                                                  fontWeight: FontWeight.bold,
                                                  color: Colors.black87),
                                            ),
                                            subtitle: Column(
                                              crossAxisAlignment:
                                                  CrossAxisAlignment.start,
                                              children: [
                                                const SizedBox(height: 8),
                                                Container(
                                                  padding: const EdgeInsets
                                                      .symmetric(
                                                      horizontal: 8.0,
                                                      vertical: 4.0),
                                                  decoration: BoxDecoration(
                                                    color:
                                                        const Color(0xFFAC2B36)
                                                            .withOpacity(0.1),
                                                    borderRadius:
                                                        BorderRadius.circular(
                                                            6.0),
                                                  ),
                                                  child: Text(
                                                    'Tanggal: ${DateTime.parse(entry['timestamp']).toLocal().toString().substring(0, 16)}',
                                                    style: const TextStyle(
                                                        fontSize: 14.0,
                                                        color: Colors.black87,
                                                        fontWeight:
                                                            FontWeight.w500),
                                                  ),
                                                ),
                                                const SizedBox(height: 4),
                                                Text(
                                                  'Gejala: ${symptomsList.join(', ')}',
                                                  style: const TextStyle(
                                                      fontSize: 14.0,
                                                      color: Colors.black54),
                                                  maxLines:
                                                      isExpanded ? null : 2,
                                                  overflow: isExpanded
                                                      ? null
                                                      : TextOverflow.ellipsis,
                                                ),
                                              ],
                                            ),
                                            trailing: IconButton(
                                              icon: const Icon(Icons.delete,
                                                  color: Color(0xFFAC2B36)),
                                              onPressed: () =>
                                                  _deleteHistoryEntry(index),
                                            ),
                                            onTap: () {
                                              Navigator.push(
                                                context,
                                                MaterialPageRoute(
                                                  builder: (context) => ResultPage(
                                                      results: Map<
                                                              String,
                                                              Map<String,
                                                                  dynamic>>.from(
                                                          results)),
                                                ),
                                              ).catchError((error) {
                                                ScaffoldMessenger.of(context)
                                                    .showSnackBar(
                                                  SnackBar(
                                                      content: Text(
                                                          'Gagal membuka detail: $error'),
                                                      backgroundColor:
                                                          Colors.red),
                                                );
                                              });
                                            },
                                          ),
                                          if (symptomsList.join(', ').length >
                                              50)
                                            Padding(
                                              padding: const EdgeInsets.only(
                                                  bottom: 8.0),
                                              child: TextButton(
                                                onPressed: () {
                                                  if (mounted) {
                                                    setState(() {
                                                      expandedSymptoms[index] =
                                                          !isExpanded;
                                                    });
                                                  }
                                                },
                                                child: Text(
                                                  isExpanded
                                                      ? 'Sembunyikan'
                                                      : 'Lihat Selengkapnya',
                                                  style: const TextStyle(
                                                      color: Color(0xFF4CAF50),
                                                      fontSize: 14.0),
                                                ),
                                              ),
                                            ),
                                        ],
                                      ),
                                    ),
                                  ),
                                ),
                              );
                            },
                          ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}
