import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:helpers/helpers/misc_build/build_media.dart';
import 'package:helpers/helpers/print.dart';
import 'package:rluv/global/styles.dart';
import 'package:rluv/models/budget.dart';
import 'package:rluv/models/budget_category_model.dart';

import '../../../global/api.dart';
import '../../../global/store.dart';
import '../../../global/utils.dart';
import '../../../global/widgets/ui_button.dart';

class BudgetCategoryDialog extends ConsumerStatefulWidget {
  const BudgetCategoryDialog({super.key, this.category});

  final BudgetCategory? category;

  @override
  ConsumerState<BudgetCategoryDialog> createState() =>
      _AddBudgetCategoryDialogState();
}

class _AddBudgetCategoryDialogState
    extends ConsumerState<BudgetCategoryDialog> {
  late final Budget? budget;
  final categoryNameController = TextEditingController();
  final amountController = TextEditingController();

  final categoryFocusNode = FocusNode();
  final amountFocusNode = FocusNode();

  final colors = Styles.curatedColors;
  int selectedColorIndex = -1;

  final formKey = GlobalKey<FormState>();

  @override
  void initState() {
    budget = ref.read(budgetProvider);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      categoryFocusNode.requestFocus();
    });

    if (widget.category != null) {
      categoryNameController.text = widget.category!.name;
      amountController.text = widget.category!.amount.toString();
      selectedColorIndex = colors.indexOf(widget.category!.color);
    }

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    if (budget == null) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        Navigator.pop(context);
        showSnack(
          ref: ref,
          text: 'Could not get your budget',
          type: SnackType.error,
        );
      });
      return Container();
    }
    return SizedBox(
      width: BuildMedia(context).width * Styles.dialogScreenWidthFactor,
      child: Stack(
        children: [
          Padding(
            padding:
                const EdgeInsets.symmetric(vertical: 18.0, horizontal: 32.0),
            child: Form(
              key: formKey,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Padding(
                    padding: const EdgeInsets.only(bottom: 18.0),
                    child: Text(widget.category == null
                        ? 'Add Category:'
                        : 'Edit Category'),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      const Text('Name:'),
                      const SizedBox(width: 30),
                      Container(
                        width: 150,
                        height: 40,
                        decoration: Styles.boxLavenderBubble,
                        child: TextFormField(
                          validator: (text) {
                            if (text == null || text.isEmpty) {
                              return 'Cannot be blank';
                            }
                            return null;
                          },
                          focusNode: categoryFocusNode,
                          textAlign: TextAlign.center,
                          cursorColor: Styles.blushingPink,
                          controller: categoryNameController,
                          decoration: Styles.inputLavenderBubble(),
                          onFieldSubmitted: (_) {
                            amountFocusNode.requestFocus();
                          },
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 18),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      const Text('Amount:'),
                      const SizedBox(width: 30),
                      Container(
                        width: 150,
                        height: 40,
                        decoration: Styles.boxLavenderBubble,
                        child: TextFormField(
                          validator: (text) {
                            try {
                              if (text == null || text.isEmpty) {
                                return 'Invalid Amount';
                              }
                              final amount = double.tryParse(text);
                              if (amount == null) {
                                return 'Not A Number';
                              }
                              if (amount < 0) {
                                return 'Not Positive';
                              }
                              return null;
                            } catch (err) {
                              return 'Invalid input';
                            }
                          },
                          focusNode: amountFocusNode,
                          keyboardType: TextInputType.number,
                          textAlign: TextAlign.center,
                          cursorColor: Styles.blushingPink,
                          controller: amountController,
                          decoration: Styles.inputLavenderBubble(),
                        ),
                      ),
                    ],
                  ),
                  Padding(
                    padding: const EdgeInsets.symmetric(
                        vertical: 6.0, horizontal: 16.0),
                    child: SizedBox(
                      height: 76,
                      child: ListView.builder(
                        itemCount: colors.length,
                        scrollDirection: Axis.horizontal,
                        itemBuilder: (BuildContext context, int index) {
                          return GestureDetector(
                            onTap: () {
                              if (selectedColorIndex != index) {
                                setState(() => selectedColorIndex = index);
                              } else {
                                setState(() => selectedColorIndex = -1);
                              }
                              printBlue(selectedColorIndex);
                            },
                            child: Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: AnimatedContainer(
                                decoration: selectedColorIndex == index
                                    ? BoxDecoration(
                                        borderRadius:
                                            BorderRadius.circular(15.0),
                                        border: Border.all(
                                          color: Styles.washedStone,
                                          width: 2.0,
                                        ),
                                      )
                                    : BoxDecoration(
                                        borderRadius:
                                            BorderRadius.circular(5.0),
                                        border: Border.all(
                                          color: Colors.transparent,
                                          width: 2.0,
                                        ),
                                      ),
                                duration: const Duration(milliseconds: 400),
                                child: Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Stack(
                                    alignment: Alignment.center,
                                    children: [
                                      Container(
                                        height: 40,
                                        width: 40,
                                        decoration: const BoxDecoration(
                                          shape: BoxShape.circle,
                                        ),
                                      ),
                                      Container(
                                        height: 40,
                                        width: 40,
                                        decoration: BoxDecoration(
                                          color: colors[index],
                                          shape: BoxShape.circle,
                                          border: Border.all(
                                              color: Colors.black, width: 1.5),
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          );
                        },
                      ),
                    ),
                  ),
                  if (widget.category != null && widget.category?.id != null)
                    Padding(
                      padding: const EdgeInsets.only(bottom: 16.0),
                      child: UiButton(
                        showLoading: true,
                        color: Styles.expensesRed,
                        text: 'DELETE',
                        onPressed: () {
                          if (formKey.currentState != null &&
                              formKey.currentState!.validate()) {
                            removeCategory().then((success) {
                              Navigator.pop(context);
                              if (success) {
                                showSnack(
                                  ref: ref,
                                  text: 'Budget Category Removed',
                                  type: SnackType.success,
                                );
                              } else {
                                showSnack(
                                  ref: ref,
                                  text: 'Unable to Remove Budget Category',
                                  type: SnackType.error,
                                );
                              }
                            });
                          }
                        },
                      ),
                    ),
                  UiButton(
                    showLoading: true,
                    color: Styles.lavender,
                    text: 'SAVE',
                    onPressed: () {
                      if (formKey.currentState != null &&
                          formKey.currentState!.validate()) {
                        submitCategory(colors[selectedColorIndex]).then((_) {
                          Navigator.pop(context);
                          showSnack(
                            ref: ref,
                            text: 'Budget Category Added!',
                            type: SnackType.success,
                          );
                        });
                      }
                    },
                  ),
                ],
              ),
            ),
          ),
          IconButton(
            icon: const Icon(Icons.close),
            onPressed: () => Navigator.pop(context),
          ),
        ],
      ),
    );
  }

  Future submitCategory(Color categoryColor) async {
    if (formKey.currentState != null && !formKey.currentState!.validate()) {
      printPink('Failed validation');
      return;
    }
    Map<String, dynamic>? budgetData;
    bool success = false;
    if (widget.category == null) {
      final newBudget = BudgetCategory(
        id: null,
        amount: double.parse(amountController.text),
        budgetId: budget!.id!,
        color: categoryColor,
        name: categoryNameController.text,
      );

      budgetData = await ref
          .read(apiProvider.notifier)
          .post(path: 'budget_category', data: newBudget.toJson());
      success = budgetData != null ? budgetData['success'] as bool : false;
      if (success) {
        ref
            .read(dashboardProvider.notifier)
            .add({'budget_categories': budgetData});
      }
    } else {
      final newBudget =
          BudgetCategory.copyWith(category: widget.category!, data: {
        'amount': double.parse(amountController.text),
        'color': categoryColor,
        'name': categoryNameController.text
      });
      budgetData = await ref
          .read(apiProvider.notifier)
          .put(path: 'budget_category', data: newBudget.toJson());
      success = budgetData != null ? budgetData['success'] as bool : false;
      if (success) {
        ref
            .read(dashboardProvider.notifier)
            .update({'budget_categories': budgetData});
      }
    }
    if (success) {
      showSnack(
          ref: ref,
          text: widget.category == null
              ? 'Added budget category!'
              : 'Updated category!',
          type: SnackType.error);
    } else {
      showSnack(
          ref: ref,
          text: widget.category == null
              ? 'Could not add budget category'
              : 'Could not update category',
          type: SnackType.error);
    }
  }

  Future<bool> removeCategory() async {
    final res = await ref
        .read(apiProvider.notifier)
        .delete(path: 'budget_category', data: {'id': widget.category!.id});
    final success = res != null ? res['success'] as bool : false;
    if (success) {
      ref
          .read(dashboardProvider.notifier)
          .removeWithId('budget_categories', widget.category!.id!);
    }
    return success;
  }
}
