import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/common_widgets/app_loading_manager.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/views/widgets/bottom_sheets/selection_bottom_sheet.dart';

import '../../models/base.dart';
import '../app_style/app_color.dart';

class SingleItemDropDownMenu<T extends Base, X extends LoadingListNotifier>
    extends StatefulWidget {
  final BuildContext context;
  final Function(T) onSelect;
  final T initialValue;
  final bool enabled;
  final bool showAsBottomSheet;
  final List<T> staticData;
  final String title;
  final Color backgroundColor;
  final bool loading;

  /// To use a static data (without calling API)
  /// just send [NullableLoadingProvider] as generic data type and fill the [staticData]
  const SingleItemDropDownMenu({
    Key key,
    @required this.context,
    @required this.title,
    this.onSelect,
    this.initialValue,
    this.enabled = true,
    this.showAsBottomSheet = false,
    this.staticData,
    this.backgroundColor,
    this.loading,
  }) : super(key: key);

  @override
  State<SingleItemDropDownMenu<T, X>> createState() =>
      _SingleItemDropDownMenuState<T, X>();
}

class _SingleItemDropDownMenuState<T extends Base,
    X extends LoadingListNotifier> extends State<SingleItemDropDownMenu<T, X>> {
  T _selectedItem;
  X provider;

  @override
  void initState() {
    if (X != NullableLoadingProvider) {
      provider = Provider.of<X>(widget.context);
    }
    if (widget.initialValue != null) {
      final result =
          (X == NullableLoadingProvider ? widget.staticData : provider.items)
              ?.where((element) {
        return element.identifier == widget.initialValue.identifier;
      });
      if (result?.isNotEmpty ?? false) _selectedItem = result.first;
      if (widget.onSelect != null &&
          (widget.initialValue?.identifier ?? "") !=
              (_selectedItem?.identifier ?? "")) {
        widget.onSelect(_selectedItem);
      }
    }
    super.initState();
  }

  @override
  void setState(VoidCallback fn) {
    if (mounted) super.setState(fn);
  }

  @override
  void didUpdateWidget(covariant SingleItemDropDownMenu<T, X> oldWidget) {
    if (widget.initialValue != null) {
      final result =
          (X == NullableLoadingProvider ? widget.staticData : provider.items)
              ?.where((element) {
        return element.identifier == widget.initialValue.identifier;
      });
      if (result?.isNotEmpty ?? false) {
        _selectedItem = result.first;
      } else {
        _selectedItem = null;
      }
      if (widget.onSelect != null &&
          (widget.initialValue?.identifier ?? "") !=
              (_selectedItem?.identifier ?? "")) {
        widget.onSelect(_selectedItem);
      }
    } else {
      _selectedItem = null;
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    bool isEmpty =
        ((X == NullableLoadingProvider ? widget.staticData : provider.items)
                ?.isEmpty ??
            true);
    return AppLoadingManager(
      isLoading: widget.loading ??
          ((X == NullableLoadingProvider) ? false : provider.loading),
      isFailedLoading:
          (X == NullableLoadingProvider) ? false : provider.items == null,
      stateCode: (X == NullableLoadingProvider) ? 200 : provider.stateCode,
      onRefresh: () async {
        if (X != NullableLoadingProvider) {
          provider?.reset();
          await provider?.getDate();
        }
      },
      child: Container(
        height: 60.toScreenHeight,
        padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
        decoration: BoxDecoration(
          color: context.isDark && (widget.enabled == false || isEmpty)
              ? AppColor.neutral50
              : (widget.enabled == false || isEmpty)
                  ? AppColor.neutral40
                  : widget.backgroundColor ?? AppColor.background(context),
          borderRadius: BorderRadius.circular(10),
          boxShadow: [
            BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)
          ],
        ),
        child: Stack(
          alignment: Alignment.center,
          children: [
            if (widget.enabled)
              const PositionedDirectional(
                  end: 0, child: Icon(Icons.keyboard_arrow_down_rounded)),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  widget.title,
                  style: Theme.of(context).textTheme.bodySmall?.copyWith(
                      color: context.isDark ? null : AppColor.neutral20,
                      fontWeight: FontWeight.w500),
                ),
                DropdownButton<T>(
                  value: _selectedItem,
                  iconSize: 24,
                  isDense: true,
                  icon: const SizedBox.shrink(),
                  elevation: 0,
                  isExpanded: true,
                  hint: Text(
                    isEmpty || widget.enabled == false
                        ? context.translation.noDataFound
                        : context.translation.select,
                    style: Theme.of(context).textTheme.bodyLarge,
                  ),
                  style: TextStyle(color: Theme.of(context).primaryColor),
                  underline: const SizedBox.shrink(),
                  onChanged: (widget.enabled == false || widget.showAsBottomSheet)
                      ? null
                      : (T newValue) {
                          final isNull = newValue.identifier == "-1";
                          setState(() {
                            _selectedItem = isNull ? null : newValue;
                          });
                          widget.onSelect(isNull ? null : newValue);
                        },
                  items: ((X == NullableLoadingProvider)
                          ? widget.staticData
                          : provider.items)
                      ?.map<DropdownMenuItem<T>>((value) {
                    return DropdownMenuItem<T>(
                      value: value,
                      child: Text(
                        value?.name ?? "",
                        style: Theme.of(context).textTheme.bodyLarge,
                      ),
                    );
                  })?.toList(),
                ).onPress(widget.showAsBottomSheet ? () async{

                  T _selectedT = (await showModalBottomSheet(
                  context: context,
                  isScrollControlled: true,
                  shape: const RoundedRectangleBorder(
                  borderRadius: BorderRadius.vertical(
                      top: Radius.circular(20),
                  ),
                  ),
                  clipBehavior: Clip.antiAliasWithSaveLayer,
                  builder: (BuildContext context) => SelectionBottomSheet(
                  items: ((X == NullableLoadingProvider)
                      ? widget.staticData
                      : provider.items),
                  selectedItem: _selectedItem,
                  title: widget.title,
                  builderString: (emp) => emp?.name ?? "",
                  ),
                  )) as T;
                  if(_selectedT !=null) {
                    widget.onSelect(_selectedT);
                  }

                } : null),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
