import 'package:flutter/material.dart';

import 'package:flutter_custom_toolbox/flutter_toolbox.dart';

class ApplicationConfigDefinition {
  final String appTitle;
  final List<ApplicationSettingsParameter> activitySettings;
  final bool autoStartActivity;
  final void Function(BuildContext context) startNewActivity;
  final void Function(BuildContext context) quitCurrentActivity;
  final void Function(BuildContext context) deleteCurrentActivity;
  final void Function(BuildContext context) resumeActivity;
  final ApplicationNavigation navigation;

  const ApplicationConfigDefinition({
    required this.appTitle,
    required this.activitySettings,
    this.autoStartActivity = false,
    required this.startNewActivity,
    required this.quitCurrentActivity,
    required this.deleteCurrentActivity,
    required this.resumeActivity,
    required this.navigation,
  });

  ApplicationSettingsParameter getFromCode(String paramCode) {
    final List<ApplicationSettingsParameter> settings = activitySettings;

    return settings.where((setting) => setting.code == paramCode).firstOrNull ??
        ApplicationSettingsParameter.empty();
  }
}

class ApplicationSettingsParameter {
  final String code;
  final bool displayedOnTop;
  final List<ApplicationSettingsParameterItemValue> values;
  final Widget Function({
    required BuildContext context,
    required double size,
    required ApplicationSettingsParameterItemValue itemValue,
    required VoidCallback onPressed,
  })? builder;
  final CustomPainter Function(BuildContext context, String value)? customPainter;
  final int Function(String value)? intValueGetter;
  final Color Function(String value)? colorGetter;

  const ApplicationSettingsParameter({
    required this.code,
    this.displayedOnTop = true,
    required this.values,
    this.builder,
    this.customPainter,
    this.colorGetter,
    this.intValueGetter,
  });

  List<String> get allowedValues {
    return values.map((ApplicationSettingsParameterItemValue item) => item.value).toList();
  }

  String get defaultValue => values.firstWhere((element) => element.isDefault).value;

  factory ApplicationSettingsParameter.empty() {
    return ApplicationSettingsParameter(
      code: '',
      values: [
        ApplicationSettingsParameterItemValue.empty(),
      ],
      intValueGetter: (value) => 0,
    );
  }

  Widget buildParameterItem({
    required BuildContext context,
    required ApplicationSettingsParameter parameter,
    required ApplicationSettingsParameterItemValue itemValue,
    required double size,
    required VoidCallback? onPressed,
  }) {
    final Color buttonColorActive = (onPressed != null) ? Colors.blue : Colors.grey;
    final Color buttonColorInactive = Theme.of(context).colorScheme.surface;
    const double buttonBorderWidth = 4.0;
    const double buttonBorderRadius = 12.0;

    final ActivitySettingsCubit activitySettingsCubit =
        BlocProvider.of<ActivitySettingsCubit>(context);
    final String currentValue = activitySettingsCubit.get(code);

    final bool isSelected = (currentValue == itemValue.value);

    final Color buttonColor = isSelected ? buttonColorActive : buttonColorInactive;

    Widget content = SizedBox.shrink();

    if (builder != null) {
      content = builder!(
        context: context,
        size: size,
        itemValue: itemValue,
        onPressed: onPressed ?? () {},
      );
    } else {
      if (customPainter != null) {
        content = StyledButton(
          color: itemValue.color ?? Colors.grey,
          onPressed: onPressed ?? () {},
          child: CustomPaint(
            size: Size(size, size),
            willChange: false,
            painter: customPainter!(context, itemValue.value),
            isComplex: true,
          ),
        );
      } else {
        content = StyledButton.text(
          color: itemValue.color ?? Colors.grey,
          caption: itemValue.text ?? itemValue.value,
          onPressed: onPressed ?? () {},
        );
      }
    }

    return Container(
      decoration: BoxDecoration(
        color: buttonColor,
        borderRadius: BorderRadius.circular(buttonBorderRadius),
        border: Border.all(
          color: buttonColor,
          width: buttonBorderWidth,
        ),
      ),
      child: content,
    );
  }
}

class ApplicationSettingsParameterItemValue {
  final String value;
  final bool isDefault;
  final Color? color;
  final String? text;

  const ApplicationSettingsParameterItemValue({
    required this.value,
    this.isDefault = false,
    this.color,
    this.text,
  });

  factory ApplicationSettingsParameterItemValue.empty() {
    return ApplicationSettingsParameterItemValue(
      value: '',
      isDefault: true,
    );
  }

  @override
  String toString() {
    return value;
  }
}