// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

part of '../focus_flow_app.dart';

/// Private implementation type for `_TodayScreenScaffoldState` in this library.
/// It keeps supporting state and behavior scoped to the owning file so the public API stays focused on the scheduler concepts that callers use directly.
class _TodayScreenScaffoldState extends State<_TodayScreenScaffold> {
  /// Shared constant value for `_modalScrimTopInset`.
  /// The constant gives this repeated scheduler or UI value one documented source of truth instead of scattering literals across call sites.
  static const _modalScrimTopInset = 96.0;

  /// Private state stored as `_timelineScrollTargetCardId` for this implementation.
  /// The field is intentionally scoped to this library so only the owning type can change the related scheduler or UI behavior.
  String? _timelineScrollTargetCardId;

  /// Private state stored as `_timelineScrollRequest` for this implementation.
  /// The field is intentionally scoped to this library so only the owning type can change the related scheduler or UI behavior.
  var _timelineScrollRequest = 0;

  /// Private state stored as `_timelineScrollToNowRequest` for this implementation.
  /// The field is intentionally scoped to this library so only the owning type can change the related scheduler or UI behavior.
  var _timelineScrollToNowRequest = 0;

  /// Runs the `_showUpcomingRequiredTask` helper used inside this library.
  /// The helper centralizes a small piece of transformation or validation so higher-level scheduler flow remains easier to read.
  void _showUpcomingRequiredTask() {
    final targetCardId = widget.data.requiredBanner?.timelineCardId;
    if (targetCardId == null) {
      return;
    }
    setState(() {
      _timelineScrollTargetCardId = targetCardId;
      _timelineScrollRequest += 1;
    });
  }

  /// Runs the `_scrollTimelineToCurrentTime` helper used inside this library.
  /// The helper centralizes a small piece of transformation or validation so higher-level scheduler flow remains easier to read.
  void _scrollTimelineToCurrentTime() {
    setState(() {
      _timelineScrollTargetCardId = null;
      _timelineScrollToNowRequest += 1;
    });
  }

  /// Performs the `didUpdateWidget` behavior for this scheduler component.
  /// The method provides a named entry point for this operation so callers do not need to know the lower-level state or persistence steps involved.
  @override
  void didUpdateWidget(covariant _TodayScreenScaffold oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.data.dateLabel == widget.data.dateLabel) {
      return;
    }
    _timelineScrollTargetCardId = null;
    _timelineScrollRequest = 0;
    _timelineScrollToNowRequest = 0;
  }

  /// Builds the widget subtree for this component.
  /// The method translates the current widget configuration and state into Flutter UI without mutating scheduler domain data.
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(
            FocusFlowTokens.mainGutter,
            32,
            FocusFlowTokens.mainGutter,
            28,
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              TopBar(
                dateLabel: widget.data.dateLabel,
                onPreviousDate: widget.onPreviousDate,
                onNextDate: widget.onNextDate,
                onDatePressed: widget.onChooseDate,
                onDateLabelPressed: _scrollTimelineToCurrentTime,
              ),
              if (widget.data.requiredBanner == null)
                const SizedBox(height: 16)
              else ...[
                const SizedBox(height: 24),
                RequiredBanner(
                  model: widget.data.requiredBanner,
                  onShowUpcoming: _showUpcomingRequiredTask,
                ),
                const SizedBox(height: 22),
              ],
              Expanded(
                child: TimelineView(
                  cards: widget.data.cards,
                  range: widget.data.timelineRange,
                  scrollTargetCardId: _timelineScrollTargetCardId,
                  scrollRequest: _timelineScrollRequest,
                  scrollToNowRequest: _timelineScrollToNowRequest,
                  onCardSelected: widget.onSelectCard,
                  onAddTask: widget.onAddTask,
                  onCardCompleted: widget.onCompleteCard,
                  onPushToNext: widget.onPushToNext,
                  onPushToTomorrow: widget.onPushToTomorrow,
                  onPushToBacklog: widget.onPushToBacklog,
                  now: () =>
                      DateTime.now().toUtc().add(widget.data.timeZoneOffset),
                ),
              ),
            ],
          ),
        ),
        if (widget.selectedCard != null) ...[
          Positioned(
            left: 0,
            top: _modalScrimTopInset,
            right: 0,
            bottom: 0,
            child: GestureDetector(
              key: const ValueKey('modal-click-away'),
              behavior: HitTestBehavior.opaque,
              onTap: widget.onClearSelection,
              child: const ColoredBox(color: Colors.transparent),
            ),
          ),
          Center(
            child: TaskSelectionModal(
              card: widget.selectedCard!,
              onClose: widget.onClearSelection,
              onStatusPressed: widget.selectedCard!.canToggleCompletion
                  ? () => widget.onCompleteCard(widget.selectedCard!)
                  : null,
              onPushToNext: widget.onPushToNext,
              onPushToTomorrow: widget.onPushToTomorrow,
              onPushToBacklog: widget.onPushToBacklog,
              onRemove: widget.onRemoveCard,
            ),
          ),
        ],
      ],
    );
  }
}
