import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';

import '../../about/external/data/Goal.dart';
import '../../about/external/initial/GoalRequest.dart';
import '../../about/internal/application/CommitmentClass.dart';
import '../../about/internal/application/TextType.dart';
import '../../configs/Navigator.dart';
import '../../designs/Component.dart';
import '../../designs/Responsive.dart';
import '../../designs/Shell.dart';
import '../../designs/buttons/Buttons.dart';
import '../../designs/input/InputFields.dart';
import '../../designs/text/Text.dart';
import '../../utils/Colors.dart';
import '../../utils/CommonUtils.dart';
import '../../utils/Validators.dart';
import 'ConnectGoals.dart';
import 'GoalDetail.dart';
import 'Goals.dart';
import 'ViewGoals.dart';

class GoalsState extends State<Goals> implements ConnectGoals {
  ViewGoals? _model;

  List<Goal> _goals = <Goal>[];

  @override
  Widget build(BuildContext context) {
    return ViewModelBuilder<ViewGoals>.reactive(
      viewModelBuilder: () => ViewGoals(context, this),
      onViewModelReady: (viewModel) {
        _model = viewModel;
        _initiate();
      },
      builder: (context, viewModel, child) => LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
          return Responsive(
            mobile: _mobileView(constraints),
            tablet: _mobileView(constraints),
            desktop: _mobileView(constraints),
          );
        },
      ),
    );
  }

  void _initiate() {
    _model?.loadGoals();
  }

  void _onBack() {
    Navigator.pop(context);
  }

  void _onOpenGoal(Goal goal) async {
    final result = await GroundedNavigation()
        .navigateToPageWithData(GoalDetail(goal: goal), context);

    if (result == true) {
      _model?.loadGoals();
    }
  }

  void _onNewGoal() {
    _openGoalSheet();
  }

  /// Goals are lightweight on purpose — a name and a default class. The
  /// weight lives on the tasks inside them.
  void _openGoalSheet() {
    final TextEditingController title = TextEditingController();
    final TextEditingController description = TextEditingController();
    final GlobalKey<FormState> formKey = GlobalKey<FormState>();

    CommitmentClass defaultClass = CommitmentClass.Standard;

    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      barrierColor: colorPrimaryDark.withValues(alpha: 0.6),
      builder: (BuildContext sheetContext) {
        return StatefulBuilder(
          builder: (BuildContext sheetContext, StateSetter setSheetState) {
            return Padding(
              padding: EdgeInsets.only(
                bottom: MediaQuery.of(sheetContext).viewInsets.bottom,
              ),
              child: Container(
                decoration: BoxDecoration(
                  color: colorSheetBackground,
                  borderRadius: const BorderRadius.only(
                    topLeft: Radius.circular(28),
                    topRight: Radius.circular(28),
                  ),
                ),
                child: SingleChildScrollView(
                  padding: const EdgeInsets.fromLTRB(24, 16, 24, 32),
                  child: Form(
                    key: formKey,
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        Center(
                          child: Container(
                            width: 36,
                            height: 4,
                            margin: const EdgeInsets.only(bottom: 20),
                            decoration: BoxDecoration(
                              color: colorGrey.withValues(alpha: 0.35),
                              borderRadius: BorderRadius.circular(999),
                            ),
                          ),
                        ),
                        text("NEW GOAL", 9, TextType.Bold,
                            color: colorGrey2, letterSpacing: 1.2),
                        const SizedBox(height: 10),
                        text("What are you\nworking toward?", 26,
                            TextType.Light,
                            color: colorPrimaryDark, height: 1.2),
                        const SizedBox(height: 20),
                        inputField(
                          "Goal",
                          title,
                          hint: "Workout, thesis, get the flat sorted…",
                          validator: Validators.title,
                        ),
                        const SizedBox(height: 18),
                        inputField(
                          "Why it matters",
                          description,
                          hint: "Optional, but it helps on the bad days",
                          maxLines: 3,
                        ),
                        const SizedBox(height: 20),
                        text("TASKS DEFAULT TO", 9, TextType.Bold,
                            color: colorGrey2, letterSpacing: 1.0),
                        const SizedBox(height: 10),
                        segmentedSelector<CommitmentClass>(
                          options: CommitmentClass.values,
                          selected: defaultClass,
                          label: classLabel,
                          onSelected: (value) => setSheetState(() {
                            defaultClass = value;
                          }),
                          activeColor: classColor(defaultClass),
                        ),
                        const SizedBox(height: 24),
                        roundedCornerButton(
                          "Create goal",
                          () {
                            if (formKey.currentState?.validate() != true) {
                              return;
                            }
                            Navigator.pop(sheetContext);
                            _model?.save(GoalRequest(
                              title: title.text.trim(),
                              description: description.text.trim(),
                              defaultClass: defaultClass.name,
                              startDate: DateTime.now().toIso8601String(),
                            ));
                          },
                          icon: CupertinoIcons.add,
                        ),
                        const SizedBox(height: 8),
                        Center(
                          child: textButton("Cancel",
                              () => Navigator.pop(sheetContext),
                              textSize: 13),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            );
          },
        );
      },
    );
  }

  Widget _mobileView(BoxConstraints constraints) {
    return Sheet(
      eyebrow: "Grounded",
      title: "Goals",
      onBack: _onBack,
      action: chromeAction(CupertinoIcons.add, _onNewGoal),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        mainAxisSize: MainAxisSize.min,
        children: [
          displayTitle("What you are\nworking toward."),
          const SizedBox(height: 14),
          text(
            "A goal holds the tasks that get you there. The goal never carries debt — the tasks inside it do.",
            14,
            TextType.Regular,
            color: colorGrey2,
            height: 1.55,
          ),
          const SizedBox(height: 28),
          if (_goals.isEmpty)
            emptyState(
              CupertinoIcons.flag,
              "No goals yet",
              "Create one — Workout, say — then put the actual sessions inside it.",
            )
          else
            ..._goals.map(_goalCard),
          const SizedBox(height: 24),
          roundedCornerButton("New goal", _onNewGoal,
              icon: CupertinoIcons.add),
        ],
      ),
    );
  }

  Widget _goalCard(Goal goal) {
    final Color accent =
        goal.slipping ? colorStandingGrounded : colorPrimaryDark;

    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      child: card(
        onTap: () => _onOpenGoal(goal),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: [
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      text(goal.title, 19, TextType.Light,
                          color: colorPrimaryDark,
                          maxLines: 2,
                          overflow: TextOverflow.ellipsis),
                      if (goal.description.isNotEmpty) ...[
                        const SizedBox(height: 6),
                        text(goal.description, 12, TextType.Regular,
                            color: colorGrey2,
                            maxLines: 2,
                            overflow: TextOverflow.ellipsis),
                      ],
                    ],
                  ),
                ),
                const SizedBox(width: 10),
                if (goal.overdueTasks > 0)
                  pill("${goal.overdueTasks} late", colorStandingGrounded,
                      colorStandingGroundedBg, textSize: 9),
              ],
            ),
            const SizedBox(height: 18),
            meter(goal.progress, fill: accent),
            const SizedBox(height: 12),
            Row(
              children: [
                Expanded(
                  child: labelled(
                    "Done",
                    "${goal.completedTasks} of ${goal.totalTasks}",
                    valueSize: 13,
                  ),
                ),
                Expanded(
                  child: labelled(
                    "Remaining",
                    "${goal.remainingTasks}",
                    valueSize: 13,
                  ),
                ),
                Expanded(
                  child: labelled(
                    "Debt",
                    formatDebt(goal.debtContribution),
                    valueSize: 13,
                    valueColor: goal.debtContribution > 0
                        ? colorStandingGrounded
                        : colorPrimaryDark,
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  @override
  void onGoalsLoaded(List<Goal> goals) {
    setState(() {
      _goals = goals;
    });
  }

  @override
  void onGoalSaved() {
    _model?.loadGoals();
  }
}
