import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';

import 'package:get/get.dart';
import 'package:http/http.dart' as http;

import 'package:f0ckapp/controller/mediacontroller.dart';
import 'package:f0ckapp/models/suggestion.dart';

class CustomSearchDelegate extends SearchDelegate<String> {
  final MediaController controller = Get.find<MediaController>();
  Timer? _debounceTimer;
  List<Suggestion>? _suggestions;
  bool _isLoading = false;
  String? _error;
  String _lastFetchedQuery = "";

  @override
  List<Widget> buildActions(BuildContext context) {
    return [
      IconButton(
        icon: const Icon(Icons.clear),
        onPressed: () {
          query = '';
          _clearResults();
          showSuggestions(context);
        },
      ),
    ];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      icon: const Icon(Icons.arrow_back),
      onPressed: () {
        _debounceTimer?.cancel();
        close(context, 'null');
      },
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    return Center(child: Text('Suchergebnisse für: "$query"'));
  }

  Future<List<Suggestion>> fetchSuggestions(String query) async {
    final Uri uri = Uri.parse('https://api.f0ck.me/search/?q=$query');
    try {
      final http.Response response = await http
          .get(uri)
          .timeout(const Duration(seconds: 5));

      if (response.statusCode == 200) {
        final dynamic decoded = jsonDecode(response.body);
        if (decoded is List) {
          final suggestions = decoded
              .map((item) => Suggestion.fromJson(item as Map<String, dynamic>))
              .toList();
          suggestions.sort((a, b) => b.score.compareTo(a.score));
          return suggestions;
        } else {
          throw Exception('Unerwartetes Format: Es wurde eine Liste erwartet.');
        }
      } else if (response.statusCode == 400) {
        final dynamic error = jsonDecode(response.body);
        final String message = error is Map<String, dynamic>
            ? error['detail']?.toString() ?? 'Unbekannter Fehler.'
            : 'Unbekannter Fehler.';
        throw Exception('Client-Fehler 400: $message');
      } else {
        throw Exception(
          'Fehler beim Abrufen der Vorschläge: ${response.statusCode}',
        );
      }
    } on TimeoutException {
      throw Exception('Anfrage an die API hat zu lange gedauert.');
    } catch (e) {
      throw Exception('Fehler bei der Verarbeitung der Anfrage: $e');
    }
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    return StatefulBuilder(
      builder: (BuildContext context, void Function(void Function()) setState) {
        if (query.isEmpty) {
          _debounceTimer?.cancel();
          return Container(
            padding: const EdgeInsets.all(16.0),
            child: const Text(''),
          );
        }

        if (query != _lastFetchedQuery) {
          _debounceTimer?.cancel();
          _isLoading = true;
          _error = null;
          _suggestions = null;

          _debounceTimer = Timer(Duration(milliseconds: 500), () async {
            try {
              final List<Suggestion> results = await fetchSuggestions(query);
              _lastFetchedQuery = query;
              setState(() {
                _suggestions = results;
                _isLoading = false;
              });
            } catch (e) {
              _lastFetchedQuery = query;
              setState(() {
                _error = e.toString();
                _suggestions = [];
                _isLoading = false;
              });
            }
          });

          return Center(child: _buildLoadingIndicator());
        }

        if (_isLoading) {
          return Center(child: _buildLoadingIndicator());
        }

        if (_error != null) {
          return Center(child: Text("Fehler: $_error"));
        }

        if (_suggestions == null || _suggestions!.isEmpty) {
          return Center(child: const Text("Keine Ergebnisse gefunden."));
        }

        return ListView.builder(
          itemCount: _suggestions!.length,
          itemBuilder: (BuildContext context, int index) {
            final Suggestion suggestion = _suggestions![index];
            return ListTile(
              title: Text(suggestion.tag),
              subtitle: Text(
                'Getaggt: ${suggestion.tagged}x • Score: ${suggestion.score.toStringAsFixed(2)}',
                style: TextStyle(fontSize: 12),
              ),
              onTap: () {
                controller.setTag(suggestion.tag);
                close(context, suggestion.tag);
              },
            );
          },
        );
      },
    );
  }

  Widget _buildLoadingIndicator() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        const CircularProgressIndicator(strokeWidth: 3.0),
        const SizedBox(height: 12),
        const Text(
          'Vorschläge werden geladen...',
          style: TextStyle(fontStyle: FontStyle.italic),
        ),
      ],
    );
  }

  void _clearResults() {
    _debounceTimer?.cancel();
    _suggestions = null;
    _isLoading = false;
    _error = null;
    _lastFetchedQuery = "";
  }

  @override
  void close(BuildContext context, String result) {
    _debounceTimer?.cancel();
    super.close(context, result);
  }
}
