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

part of '../top_bar.dart';

/// Private implementation type for `_TopBarMetrics` 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 _TopBarMetrics {
  /// Creates a `_TopBarMetrics` instance with the values required by its invariants.
  /// Callers should pass already-normalized scheduler data because validation and defaulting belong at the model or service boundary, not in arbitrary UI code.
  const _TopBarMetrics(this.scale);

  /// Shared constant value for `referenceHeight`.
  /// The constant gives this repeated scheduler or UI value one documented source of truth instead of scattering literals across call sites.
  static const referenceHeight = 48.0;

  /// Shared constant value for `_referenceWidth`.
  /// The constant gives this repeated scheduler or UI value one documented source of truth instead of scattering literals across call sites.
  static const _referenceWidth = 900.0;

  /// Shared constant value for `_minimumScale`.
  /// The constant gives this repeated scheduler or UI value one documented source of truth instead of scattering literals across call sites.
  static const _minimumScale = 0.44;

  /// Creates a `_TopBarMetrics.fromWidth` instance with the values required by its invariants.
  /// Callers should pass already-normalized scheduler data because validation and defaulting belong at the model or service boundary, not in arbitrary UI code.
  factory _TopBarMetrics.fromWidth(double width) {
    final safeWidth = width.isFinite ? width : _referenceWidth;
    final scale = (safeWidth / _referenceWidth).clamp(_minimumScale, 1.0);
    return _TopBarMetrics(scale.toDouble());
  }

  /// Stores the `scale` value for this object.
  /// This field is part of the explicit state that downstream scheduling, persistence, or UI code reads when composing behavior.
  final double scale;

  /// Returns the derived `titleWidth` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get titleWidth => 112 * scale;

  /// Returns the derived `titleSize` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get titleSize => FocusFlowTokens.pageTitleSize * scale;

  /// Returns the derived `titleGap` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get titleGap => 30 * scale;

  /// Returns the derived `controlHeight` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get controlHeight => referenceHeight * scale;

  /// Returns the derived `iconButtonSize` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get iconButtonSize => referenceHeight * scale;

  /// Returns the derived `iconSize` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get iconSize => 24 * scale;

  /// Returns the derived `dateWidth` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get dateWidth => 144 * scale;

  /// Returns the derived `dateSize` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get dateSize => 17 * scale;

  /// Returns the derived `modeWidth` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get modeWidth => 220 * scale;

  /// Returns the derived `modeHeight` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get modeHeight => referenceHeight * scale;

  /// Returns the derived `modeLabelSize` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get modeLabelSize => 17 * scale;

  /// Returns the derived `settingsGap` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get settingsGap => 28 * scale;

  /// Returns the derived `settingsWidth` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get settingsWidth => 136 * scale;

  /// Returns the derived `settingsHeight` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get settingsHeight => referenceHeight * scale;

  /// Returns the derived `settingsIconSize` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get settingsIconSize => 20 * scale;

  /// Returns the derived `settingsTextSize` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get settingsTextSize => 15 * scale;

  /// Returns the derived `settingsTextGap` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get settingsTextGap => 8 * scale;

  /// Returns the derived `borderRadius` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get borderRadius => FocusFlowTokens.smallButtonRadius * scale;

  /// Returns the derived `borderWidth` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  double get borderWidth => scale < 0.7 ? 0.8 : 1;

  /// Returns the derived `buttonPadding` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  EdgeInsets get buttonPadding => EdgeInsets.symmetric(horizontal: 12 * scale);
}
