import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:nut_player_example/src/common/models/option_data.dart';
import 'package:nut_player_example/src/common/views/checkmark_list_option.dart';
import 'package:nut_player_example/src/common/views/input_view.dart';
import 'package:nut_player_example/src/features/settings_screen/domain/settings_bloc.dart';
import 'package:nut_player_example/src/common/views/options_view.dart';
import 'package:nut_player_example/src/features/settings_screen/presentation/toggle_view.dart';
import 'package:package_info_plus/package_info_plus.dart';

class SettingsView extends StatelessWidget {

  const SettingsView({super.key});

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
        backgroundColor: CupertinoColors.extraLightBackgroundGray,
        navigationBar: CupertinoNavigationBar(
          key: const Key('SettingsAppBarID'),
          middle: const Text('Настройки', style: TextStyle(decoration: TextDecoration.none, color: CupertinoColors.black, fontWeight: FontWeight.w600)),
          leading: CupertinoNavigationBarBackButton(
              previousPageTitle: 'Назад',
              onPressed: () {
                final bloc = context.read<SettingsBloc>();
                bloc.add(DismissEvent());
              }
          ),
          padding: const EdgeInsetsDirectional.all(0),
          backgroundColor: CupertinoColors.white,
        ),
        child: SafeArea(
            child: SingleChildScrollView(
              child: BlocBuilder<SettingsBloc, SettingsState>(
              builder: (context, state) {
                final bloc = context.read<SettingsBloc>();
                return Column(
                children: [
                  // НАСТРОЙКИ СКИНА
                  CupertinoListSection.insetGrouped(
                    hasLeading: false,
                    header: Container(
                      padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
                      child: Text('Выбор скина'.toUpperCase(),
                          style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400)
                      ),
                    ),
                    children: _buildSkinSettings(bloc)
                  ),

                  // НАСТРОЙКИ СТАНДАРТНОГО СКИНА
                  CupertinoListSection.insetGrouped(
                      hasLeading: false,
                      header: Container(
                        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
                        child: Text('Настройки стандартного скина'.toUpperCase(),
                            style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400)
                        ),
                      ),
                      children: _buildSettingsWidgets(SettingsInitialState.standardSkinSettings, bloc)
                  ),

                  // ВОСПРОИЗВЕДЕНИЕ
                  CupertinoListSection.insetGrouped(
                      hasLeading: false,
                      header: Container(
                        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
                        child: Text('Воспроизведение'.toUpperCase(),
                            style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400)
                        ),
                      ),
                      children: _buildSettingsWidgets(SettingsInitialState.playbackOptions, bloc)
                  ),

                  // ДОПОЛНИТЕЛЬНО
                  CupertinoListSection.insetGrouped(
                      hasLeading: false,
                      header: Container(
                        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
                        child: Text('Дополнительно'.toUpperCase(),
                            style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400)
                        ),
                      ),
                      footer: Container(
                        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
                        child: const Text('Доступно только для видео в формате mp4, длительностью не более 5 мин.',
                            style: TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 12, fontWeight: FontWeight.w400)
                        ),
                      ),
                      children: _buildSettingsWidgets([SettingsInitialState.extraOption], bloc)
                  ),

                  // ЗАДЕРЖКИ
                  CupertinoListSection.insetGrouped(
                      hasLeading: false,
                      header: Container(
                        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
                        child: Text('Настройка задержек (только для HLS)'.toUpperCase(),
                            style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400)
                        ),
                      ),
                      children: _buildSettingsWidgets(SettingsInitialState.timeoutsOptions, bloc)
                  ),

                  // Логирование
                  CupertinoListSection.insetGrouped(
                      hasLeading: false,
                      header: Container(
                        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
                        child: Text('Логирование'.toUpperCase(),
                            style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400)
                        ),
                      ),
                      children: [
                        Container(
                            width: double.infinity,
                            decoration: BoxDecoration(
                                color: CupertinoColors.systemGrey3,
                                border: Border.all(color: CupertinoColors.systemGrey3)
                            ),
                            child: _buildLog(context)
                        ),
                      ]
                  ),

                  // FIREBASE
                  CupertinoListSection.insetGrouped(
                      hasLeading: false,
                      header: Container(
                        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
                        child: Text('Firebase'.toUpperCase(),
                            style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400)
                        ),
                      ),
                      children: [
                        SizedBox(
                          width: double.infinity,
                          child: CupertinoButton(
                            alignment: Alignment.centerLeft,
                              borderRadius: const BorderRadius.all(Radius.circular(10)),
                              padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
                              child: const Text('Проверка падения приложения', style: TextStyle(decoration: TextDecoration.none, color: CupertinoColors.black, fontSize: 17, fontWeight: FontWeight.w400)),
                              onPressed: () { bloc.add(CrashEvent()); }
                          )
                        )
                      ]
                  ),
                  
                  // ВЕРСИЯ
                  Container(
                    margin: const EdgeInsets.only(top: 20),
                    child: FutureBuilder(
                        future: PackageInfo.fromPlatform(),
                        builder: (context, snapshot) {
                          return _buildVersion(snapshot, bloc.state);
                        })
                  )
                ]
              );
              },
            )
            )
        )
    );
  }

  Widget _buildVersion(AsyncSnapshot<PackageInfo> packageInfo, SettingsState state) {
    const textStyle = TextStyle(
        decoration: TextDecoration.none,
        color: CupertinoColors.systemGrey,
        fontSize: 13,
        fontWeight: FontWeight.w400);

    if (packageInfo.hasData) {
      var versions = [Text('ВЕРСИЯ ПРИЛОЖЕНИЯ ${packageInfo.requireData.version}', style: textStyle)];

      final settingsState = state;
      if (settingsState is! SettingsInitialState) { return Column(children: versions); }
      versions.add(Text('ВЕРСИЯ NUT.PLAYER ${settingsState.playerVersion}', style: textStyle));
      return Column(children: versions);
    } else if (packageInfo.hasError) {
      return Text(packageInfo.error.toString(), style: textStyle);
    } else {
      return _buildLoader();
    }
  }

  Widget _buildLoader() {
    return Container(
      margin: const EdgeInsets.all(10),
      width: double.infinity,
      height: 80,
      child: const CupertinoActivityIndicator(radius: 20),
    );
  }

  List<Widget> _buildSkinSettings(SettingsBloc bloc) {
    return <Widget>[...SettingsInitialState.skinSettings.map((setting) {
      final isSelected = bloc.isSelected(setting);
      return CheckmarkListOption(
        setting.title,
        isSelected, () {
          final event = setting.onChange?.call(!isSelected);
          if (event != null) {
            bloc.add(event);
          }
        }, key: setting.key,
      );
    }).toList()];
  }

  List<Widget> _buildSettingsWidgets(List<Object> objects, SettingsBloc bloc) {
    return <Widget>[...objects.map((setting) {
      if (setting is OptionDataContainer) {
        final selectedIndex = bloc.selectedIndex(setting);
        return OptionsView(
          setting.title,
          setting.options,
          selectedIndex,
          (selectedIndex) {
            final selectedOption = setting.options[selectedIndex];
            final event = setting.onSelectedOption?.call(selectedOption);
            if (event != null) {
              bloc.add(event);
            }
          },
          key: setting.key,
        );
      } else if (setting is BoolOptionData) {
        final isSelected = bloc.isSelected(setting);
        return ToggleView(
            title: setting.title,
            isSelected: isSelected,
            onChange: (isOn) {
              final event = setting.onChange?.call(isOn);
              if (event != null) {
                bloc.add(event);
              }
            }, key: setting.key,
        );
      } else if (setting is NumericOptionData) {
        final currentValue = bloc.currentNumericValue(setting);
        return InputView(
            setting.title,
            currentValue,
            (newTime) {
              final event = setting.onChange?.call(newTime);
              if (event != null) {
                bloc.add(event);
              }
            }, key: setting.key,
        );
      } else {
        return const Text('not implemented');
      }
    }).toList()];
  }

  Widget? _buildLog(BuildContext context) {
    final bloc = context.read<SettingsBloc>();
    final settingsState = bloc.state;
    if (settingsState is! SettingsInitialState) { return null; }

    return CupertinoSlidingSegmentedControl<LogType>(
      backgroundColor: CupertinoColors.extraLightBackgroundGray,
      groupValue: settingsState.log,
      onValueChanged: (LogType? value) {
        if (value != null) {
          bloc.add(LogTypeChangedEvent(value));
        }
      },
      children: <LogType, Widget>{
        LogType.off: _buildLogSegment(SettingsInitialState.logOptions[LogType.off.toString()]!),
        LogType.info: _buildLogSegment(SettingsInitialState.logOptions[LogType.info.toString()]!),
        LogType.debug: _buildLogSegment(SettingsInitialState.logOptions[LogType.debug.toString()]!),
      },
    );
  }

  Padding _buildLogSegment(OptionData data) {
    return Padding(
      key: data.key,
      padding: const EdgeInsets.symmetric(vertical: 6),
      child: Text(data.title,
          style: const TextStyle(
              decoration: TextDecoration.none,
              fontSize: 16,
              color: CupertinoColors.black,
              fontWeight: FontWeight.normal)
      ),
    );
  }
}
