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 AddBudgetCategoryDialog extends ConsumerStatefulWidget {
  const AddBudgetCategoryDialog({super.key});

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

class _AddBudgetCategoryDialogState
    extends ConsumerState<AddBudgetCategoryDialog> {
  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();
    });
    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: [
                  const Padding(
                    padding: EdgeInsets.only(bottom: 18.0),
                    child: Text('Add Category:'),
                  ),
                  Row(
                    children: [
                      const Text('Name:'),
                      const SizedBox(width: 30),
                      Container(
                        width: 120,
                        height: 30,
                        decoration: Styles.boxLavenderBubble,
                        child: TextFormField(
                          validator: (text) {
                            if (text == null || text.length < 3) {
                              return 'Invalid Category';
                            }
                            return null;
                          },
                          focusNode: categoryFocusNode,
                          textAlign: TextAlign.center,
                          cursorColor: Styles.blushingPink,
                          controller: categoryNameController,
                          decoration: Styles.inputLavenderBubble(),
                          onFieldSubmitted: (_) {
                            amountFocusNode.requestFocus();
                          },
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 18),
                  Row(
                    children: [
                      const Text('Amount:'),
                      const SizedBox(width: 30),
                      Container(
                        width: 80,
                        height: 30,
                        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),
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          );
                        },
                      ),
                    ),
                  ),
                  UiButton(
                    showLoading: true,
                    color: Styles.lavender,
                    text: 'SAVE',
                    onPressed: () =>
                        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;
    }
    final newBudget = BudgetCategory(
      id: null,
      amount: double.parse(amountController.text),
      budgetId: budget!.id!,
      color: categoryColor,
      name: categoryNameController.text,
    );

    final budgetData = await ref
        .read(apiProvider.notifier)
        .post(path: 'budget_category', data: newBudget.toJson());
    final success = budgetData != null ? budgetData['success'] as bool : false;
    if (success) {
      ref
          .read(dashboardProvider.notifier)
          .add({'budget_categories': budgetData});
    } else {
      showSnack(ref: ref, text: 'Could not add budget', type: SnackType.error);
    }
  }
}
