import 'dart:async';
import 'package:collection/collection.dart';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_event.dart';
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_state.dart';
import 'package:hl_lieferservice/feature/scan/presentation/scanner.dart';
import 'package:hl_lieferservice/feature/settings/bloc/settings_bloc.dart';
import 'package:hl_lieferservice/feature/settings/bloc/settings_state.dart';
import 'package:hl_lieferservice/model/article.dart';
import 'package:hl_lieferservice/model/car.dart';
import 'package:hl_lieferservice/model/delivery.dart';
import 'package:hl_lieferservice/model/tour.dart';
import 'package:hl_lieferservice/widget/operations/bloc/operation_bloc.dart';
import 'package:hl_lieferservice/widget/operations/bloc/operation_event.dart';

import '../../delivery/overview/bloc/tour_bloc.dart';

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

  @override
  State<ArticleScanningScreen> createState() => _ArticleScanningScreenState();
}

class _ArticleScanningScreenState extends State<ArticleScanningScreen> {
  final FocusNode _focusNode = FocusNode();
  String _buffer = '';
  Timer? _bufferTimer;
  int _selectedDelivery = 0;
  int? _selectedCarId;

  @override
  void initState() {
    super.initState();
    // Focus anfordern, um Keyboard-Events zu empfangen
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _focusNode.requestFocus();
    });

    final state = context.read<TourBloc>().state;

    if (state is TourLoaded) {
      setState(() {
        _selectedCarId = state.tour.deliveries[_selectedDelivery].carId;
      });
    }
  }

  @override
  void dispose() {
    _focusNode.dispose();
    _bufferTimer?.cancel();
    super.dispose();
  }

  void _handleKey(KeyEvent event) {
    if (event is KeyDownEvent) {
      if (event.logicalKey == LogicalKeyboardKey.enter) {
        // Enter = Scan abgeschlossen
        _bufferTimer?.cancel();
        if (_buffer.isNotEmpty) {
          _handleBarcodeScanned(_buffer);
          _buffer = '';
        }
      } else {
        // Zeichen zum Buffer hinzufügen
        final character = event.character;
        if (character != null && character.isNotEmpty) {
          _buffer += character;

          // Timer zurücksetzen
          _bufferTimer?.cancel();
          _bufferTimer = Timer(Duration(milliseconds: 1000), () {
            // Nach 1 Sekunde ohne neue Eingabe: Buffer verarbeiten
            if (_buffer.isNotEmpty) {
              _handleBarcodeScanned(_buffer);
              _buffer = '';
            }
          });
        }
      }
    }
  }

  void _handleBarcodeScanned(String barcode) {
    if (_selectedCarId == null) {
      context.read<OperationBloc>().add(
        FailOperation(message: "Wählen Sie zu erst ein Fahrzeug aus"),
      );
      return;
    }

    final state = context.read<TourBloc>().state as TourLoaded;

    context.read<TourBloc>().add(
      ScanArticleEvent(
        articleNumber: barcode,
        carId: _selectedCarId!.toString(),
        deliveryId: state.tour.deliveries[_selectedDelivery].id,
      ),
    );
  }

  Widget _carSelection(List<Car> cars, List<Delivery> deliveries) {
    return Padding(
      padding: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            "Fahrzeug auswählen",
            style: Theme.of(context).textTheme.headlineSmall,
          ),
          Padding(
            padding: const EdgeInsets.only(top: 10),
            child: SizedBox(
              width: double.infinity,
              height: 50,
              child: ListView(
                scrollDirection: Axis.horizontal,
                children:
                    cars.map((car) {
                      Color? backgroundColor;
                      Color? iconColor = Theme.of(context).primaryColor;
                      Color? textColor;

                      if (_selectedCarId == car.id) {
                        backgroundColor = Theme.of(context).primaryColor;
                        textColor = Theme.of(context).colorScheme.onSecondary;
                        iconColor = Theme.of(context).colorScheme.onSecondary;
                      }

                      return Padding(
                        padding: const EdgeInsets.only(right: 8),
                        child: GestureDetector(
                          onTap: () {
                            context.read<TourBloc>().add(
                              AssignCarEvent(
                                deliveryId: deliveries[_selectedDelivery].id,
                                carId: car.id.toString(),
                              ),
                            );

                            setState(() {
                              _selectedCarId = car.id;
                            });
                          },
                          child: Chip(
                            backgroundColor: backgroundColor,
                            label: Row(
                              children: [
                                Icon(
                                  Icons.local_shipping,
                                  color: iconColor,
                                  size: 20,
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(left: 5),
                                  child: Text(
                                    car.plate,
                                    style: TextStyle(
                                      color: textColor,
                                      fontSize: 12,
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      );
                    }).toList(),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _articles(List<Article> articles) {
    List<Article> scannableArticles =
        articles.where((article) => article.scannable).toList();

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(left: 20, bottom: 20),
          child: Text(
            "Artikel",
            style: Theme.of(context).textTheme.headlineSmall,
          ),
        ),
        scannableArticles.isEmpty
            ? Center(
              child: Text(
                'Keine Artikel zum Scannen vorhanden',
                style: TextStyle(fontSize: 18),
              ),
            )
            : ListView.separated(
              shrinkWrap: true,
              physics: NeverScrollableScrollPhysics(),
              itemCount: scannableArticles.length,
              separatorBuilder:
                  (context, index) => Divider(
                    height: 0,
                    color:
                        Theme.of(context).colorScheme.surfaceContainerHighest,
                  ),
              itemBuilder: (context, index) {
                final article = scannableArticles[index];

                return ListTile(
                  leading:
                      article.scannedAmount == article.amount
                          ? Icon(
                            Icons.check_circle,
                            color: Colors.green,
                            size: 32,
                          )
                          : Container(
                            width: 32,
                            alignment: Alignment.center,
                            child: Text(
                              '${article.scannedAmount}/${article.amount}',
                              style: TextStyle(
                                fontSize: 16,
                                fontWeight: FontWeight.bold,
                                color:
                                    article.scannedAmount > 0
                                        ? Colors.blue
                                        : Colors.grey,
                              ),
                            ),
                          ),
                  title: Text(
                    article.name,
                    style: TextStyle(fontWeight: FontWeight.w500),
                  ),
                  subtitle: Text("Artikelnr. ${article.articleNumber}"),
                  tileColor:
                      article.scannedAmount == article.amount
                          ? Colors.green.withValues(alpha: 0.1)
                          : Theme.of(context).colorScheme.onSecondary,
                );
              },
            ),
      ],
    );
  }

  void _selectDelivery(int? index) {
    setState(() {
      _selectedDelivery = index!;
    });
  }

  Widget _navigation(List<Delivery> deliveries) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        OutlinedButton(
          onPressed:
              _selectedDelivery > 0
                  ? () => {
                    if (_selectedDelivery > 0)
                      {
                        setState(() {
                          _selectedDelivery -= 1;
                          _selectedCarId = deliveries[_selectedDelivery].carId;
                        }),
                      },
                  }
                  : null,
          child: Text("zurück"),
        ),
        Expanded(
          child: Padding(
            padding: const EdgeInsets.only(left: 20, right: 20),
            child: DropdownButton(
              menuWidth: MediaQuery.of(context).size.width,
              isExpanded: true,
              items:
                  deliveries
                      .mapIndexed(
                        (index, delivery) => DropdownMenuItem(
                          value: index,
                          child: Text(
                            delivery.customer.name,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                      )
                      .toList(),
              onChanged: _selectDelivery,
              value: _selectedDelivery,
            ),
          ),
        ),
        OutlinedButton(
          onPressed:
              _selectedDelivery < deliveries.length - 1
                  ? () => {
                    if (_selectedDelivery + 1 < deliveries.length)
                      {
                        setState(() {
                          _selectedDelivery += 1;
                          _selectedCarId = deliveries[_selectedDelivery].carId;
                        }),
                      },
                  }
                  : null,
          child: Text("weiter"),
        ),
      ],
    );
  }

  Widget _deliveryStepper(Tour tour) {
    final settingsState = context.read<SettingsBloc>().state;
    Widget scannerWidget = BarcodeScannerWidget(
      onBarcodeDetected: _handleBarcodeScanned,
    );

    if (settingsState is AppSettingsFailed) {
      context.read<OperationBloc>().add(
        FailOperation(
          message:
              "Einstellungen konnten nicht geladen werden. Nutze Kamera-Scanner.",
        ),
      );
    }

    if (settingsState is AppSettingsLoaded) {
      if (settingsState.settings.useHardwareScanner) {
        scannerWidget = Container();
      }
    }

    return Padding(
      padding: const EdgeInsets.all(0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          scannerWidget,
          _carSelection(tour.driver.cars, tour.deliveries),
          _articles(tour.deliveries[_selectedDelivery].articles),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TourBloc, TourState>(
      builder: (context, state) {
        if (state is TourLoaded) {
          Delivery delivery = state.tour.deliveries[_selectedDelivery];

          return Scaffold(
            appBar: AppBar(
              title: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    delivery.customer.name,
                    style: TextStyle(
                      color: Theme.of(context).colorScheme.onSecondary,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                  Text(
                    delivery.customer.address.toString(),
                    style: TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.normal,
                      color: Theme.of(context).colorScheme.onSecondary,
                    ),
                  ),
                ],
              ),
              backgroundColor: Theme.of(context).primaryColor,
            ),
            bottomNavigationBar: Padding(
              padding: const EdgeInsets.all(25),
              child: _navigation(state.tour.deliveries),
            ),
            body: KeyboardListener(
              focusNode: _focusNode,
              onKeyEvent: _handleKey,
              child: _deliveryStepper(state.tour),
            ),
          );
        }

        return Container();
      },
    );
  }
}
