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

/// Renders Backlog board task cards for the FocusFlow Flutter UI.
library;

import 'package:flutter/material.dart';
import 'package:scheduler_core/scheduler_core.dart';

import '../../theme/backlog_board_visual_tokens.dart';
import '../../theme/focus_flow_tokens.dart';
import '../timeline/difficulty_bars.dart';
import '../timeline/reward_icon.dart';

/// Card widget for one Backlog board task read model.
class BacklogTaskCard extends StatelessWidget {
  /// Creates a Backlog task card.
  const BacklogTaskCard({
    required this.item,
    required this.selected,
    required this.onTap,
    super.key,
  });

  /// Read model that supplies all card content.
  final BacklogBoardItemReadModel item;

  /// Whether this card is the current UI selection.
  final bool selected;

  /// Callback invoked when the user selects the card.
  final VoidCallback onTap;

  /// 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) {
    final accent = BacklogBoardVisualTokens.bucketAccent(item.bucket);
    final subtitle = item.subtitle ?? item.bucketReason;
    return Material(
      color: Colors.transparent,
      child: InkWell(
        key: ValueKey('backlog-card-${item.taskId}'),
        onTap: onTap,
        borderRadius: BorderRadius.circular(8),
        child: AnimatedContainer(
          key: ValueKey('backlog-card-container-${item.taskId}'),
          duration: const Duration(milliseconds: 120),
          curve: Curves.easeOut,
          padding: const EdgeInsets.fromLTRB(10, 10, 10, 11),
          decoration: BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
              colors: [
                FocusFlowTokens.elevatedPanel,
                accent.withValues(alpha: 0.06),
              ],
            ),
            borderRadius: BorderRadius.circular(8),
            border: Border.all(
              color: selected
                  ? FocusFlowTokens.accentMagenta
                  : FocusFlowTokens.subtleBorder,
              width: selected ? 2 : 1,
            ),
            boxShadow: [
              BoxShadow(
                color: Colors.black.withValues(alpha: 0.18),
                blurRadius: 12,
                offset: const Offset(0, 6),
              ),
            ],
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              _CardTitleRow(item: item, selected: selected),
              if (subtitle.isNotEmpty) ...[
                const SizedBox(height: 5),
                Padding(
                  padding: const EdgeInsets.only(left: 24),
                  child: Text(
                    subtitle,
                    maxLines: 2,
                    overflow: TextOverflow.ellipsis,
                    style: const TextStyle(
                      color: FocusFlowTokens.textMuted,
                      fontSize: 11,
                      height: 1.22,
                    ),
                  ),
                ),
              ],
              const SizedBox(height: 10),
              _CardMetadataRow(item: item),
              const SizedBox(height: 10),
              Divider(
                height: 1,
                color: FocusFlowTokens.subtleBorder.withValues(alpha: 0.55),
              ),
              const SizedBox(height: 9),
              _CardEffortRow(item: item, accent: accent),
              if (item.childPreview.isNotEmpty) ...[
                const SizedBox(height: 10),
                _ChildPreviewSection(children: item.childPreview),
              ],
            ],
          ),
        ),
      ),
    );
  }
}

/// Header row with checkbox-like selection square and task title.
class _CardTitleRow extends StatelessWidget {
  /// Creates a title row for [item].
  const _CardTitleRow({required this.item, required this.selected});

  /// Task card data to display.
  final BacklogBoardItemReadModel item;

  /// Whether this card is selected.
  final bool selected;

  /// 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 Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
          width: 15,
          height: 15,
          margin: const EdgeInsets.only(top: 2),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(3),
            border: Border.all(
              color: selected
                  ? FocusFlowTokens.accentMagenta
                  : FocusFlowTokens.textFaint,
              width: selected ? 1.8 : 1.2,
            ),
            color: selected
                ? FocusFlowTokens.accentMagenta.withValues(alpha: 0.12)
                : Colors.transparent,
          ),
          child: selected
              ? const Icon(
                  Icons.check,
                  color: FocusFlowTokens.accentMagenta,
                  size: 11,
                )
              : null,
        ),
        const SizedBox(width: 9),
        Expanded(
          child: Text(
            item.title,
            maxLines: 2,
            overflow: TextOverflow.ellipsis,
            style: const TextStyle(
              color: FocusFlowTokens.textPrimary,
              fontSize: 13.5,
              fontWeight: FontWeight.w800,
              height: 1.18,
            ),
          ),
        ),
      ],
    );
  }
}

/// Row of duration, project, and priority metadata.
class _CardMetadataRow extends StatelessWidget {
  /// Creates a metadata row for [item].
  const _CardMetadataRow({required this.item});

  /// Task card data to display.
  final BacklogBoardItemReadModel item;

  /// 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) {
    final projectColor = BacklogBoardVisualTokens.projectColor(
      item.projectColorToken,
    );
    final priorityColor = BacklogBoardVisualTokens.priorityColor(item.priority);
    return Wrap(
      spacing: 12,
      runSpacing: 7,
      crossAxisAlignment: WrapCrossAlignment.center,
      children: [
        _IconMetadata(
          icon: Icons.schedule,
          color: FocusFlowTokens.textMuted,
          label: _durationLabel(item.durationMinutes),
        ),
        _DotMetadata(color: projectColor, label: item.projectName),
        _IconMetadata(
          icon: Icons.flag,
          color: priorityColor,
          label: BacklogBoardVisualTokens.priorityLabel(item.priority),
        ),
      ],
    );
  }
}

/// Compact metadata item with a Material icon.
class _IconMetadata extends StatelessWidget {
  /// Creates icon metadata.
  const _IconMetadata({
    required this.icon,
    required this.color,
    required this.label,
  });

  /// Icon shown before the label.
  final IconData icon;

  /// Color used by the icon.
  final Color color;

  /// Display label.
  final String label;

  /// 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 Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Icon(icon, color: color, size: 13),
        const SizedBox(width: 5),
        Text(
          label,
          style: const TextStyle(
            color: FocusFlowTokens.textMuted,
            fontSize: 11,
            fontWeight: FontWeight.w600,
          ),
        ),
      ],
    );
  }
}

/// Compact metadata item with a color dot.
class _DotMetadata extends StatelessWidget {
  /// Creates dot metadata.
  const _DotMetadata({required this.color, required this.label});

  /// Dot color.
  final Color color;

  /// Display label.
  final String label;

  /// 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 Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          width: 8,
          height: 8,
          decoration: BoxDecoration(color: color, shape: BoxShape.circle),
        ),
        const SizedBox(width: 6),
        Text(
          label,
          style: const TextStyle(
            color: FocusFlowTokens.textMuted,
            fontSize: 11,
            fontWeight: FontWeight.w600,
          ),
        ),
      ],
    );
  }
}

/// Footer row with difficulty bars and reward marks.
class _CardEffortRow extends StatelessWidget {
  /// Creates an effort row for [item].
  const _CardEffortRow({required this.item, required this.accent});

  /// Task card data to display.
  final BacklogBoardItemReadModel item;

  /// Bucket accent used for compact indicators.
  final Color accent;

  /// 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 Row(
      children: [
        Expanded(
          child: _MetricCluster(
            label: 'Difficulty',
            child: DifficultyBars.forLevel(
              difficulty: item.difficulty,
              color: accent,
              size: const Size(36, 18),
            ),
          ),
        ),
        const SizedBox(width: 10),
        Expanded(
          child: _MetricCluster(
            label: 'Reward',
            alignment: MainAxisAlignment.end,
            child: _RewardMarks(reward: item.reward, color: accent),
          ),
        ),
      ],
    );
  }
}

/// Label-and-value cluster used by the card footer.
class _MetricCluster extends StatelessWidget {
  /// Creates a compact metric cluster.
  const _MetricCluster({
    required this.label,
    required this.child,
    this.alignment = MainAxisAlignment.start,
  });

  /// Metric label.
  final String label;

  /// Indicator widget.
  final Widget child;

  /// Horizontal alignment for the cluster content.
  final MainAxisAlignment alignment;

  /// 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 Row(
      mainAxisAlignment: alignment,
      mainAxisSize: MainAxisSize.min,
      children: [
        Flexible(
          child: Text(
            label,
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: const TextStyle(
              color: FocusFlowTokens.textMuted,
              fontSize: 10.5,
              fontWeight: FontWeight.w600,
            ),
          ),
        ),
        const SizedBox(width: 6),
        child,
      ],
    );
  }
}

/// Solid reward marks rendered from a domain reward level.
class _RewardMarks extends StatelessWidget {
  /// Creates reward marks.
  const _RewardMarks({required this.reward, required this.color});

  /// Reward level to display.
  final RewardLevel reward;

  /// Mark color.
  final Color color;

  /// 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) {
    final count = BacklogBoardVisualTokens.rewardCount(reward);
    if (count == 0) {
      return const Text(
        'None',
        style: TextStyle(color: FocusFlowTokens.textFaint, fontSize: 10.5),
      );
    }
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        for (var index = 0; index < count; index += 1)
          Padding(
            padding: EdgeInsets.only(left: index == 0 ? 0 : 1.5),
            child: RewardIcon(color: color, size: 11),
          ),
      ],
    );
  }
}

/// Nested child preview rows for parent Backlog cards.
class _ChildPreviewSection extends StatelessWidget {
  /// Creates a child preview section.
  const _ChildPreviewSection({required this.children});

  /// Child preview read models.
  final List<BacklogChildPreviewReadModel> children;

  /// 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 DecoratedBox(
      decoration: BoxDecoration(
        border: Border(
          left: BorderSide(
            color: FocusFlowTokens.subtleBorder.withValues(alpha: 0.75),
          ),
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.only(left: 10),
        child: Column(
          children: [
            for (final child in children)
              _ChildPreviewRow(
                key: ValueKey('backlog-child-${child.taskId}'),
                child: child,
              ),
          ],
        ),
      ),
    );
  }
}

/// One nested child preview row inside a Backlog task card.
class _ChildPreviewRow extends StatelessWidget {
  /// Creates a child preview row.
  const _ChildPreviewRow({required this.child, super.key});

  /// Child preview data.
  final BacklogChildPreviewReadModel child;

  /// 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 Padding(
      padding: const EdgeInsets.only(top: 7),
      child: Row(
        children: [
          Icon(
            child.isCompleted
                ? Icons.check_box_outlined
                : Icons.check_box_outline_blank,
            color: FocusFlowTokens.textFaint,
            size: 14,
          ),
          const SizedBox(width: 8),
          Expanded(
            child: Text(
              child.title,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                color: child.isCompleted
                    ? FocusFlowTokens.completedText
                    : FocusFlowTokens.textMuted,
                fontSize: 11,
                decoration: child.isCompleted
                    ? TextDecoration.lineThrough
                    : TextDecoration.none,
              ),
            ),
          ),
          if (child.durationMinutes != null) ...[
            const SizedBox(width: 8),
            _IconMetadata(
              icon: Icons.schedule,
              color: FocusFlowTokens.textFaint,
              label: _durationLabel(child.durationMinutes),
            ),
          ],
        ],
      ),
    );
  }
}

/// Formats [durationMinutes] as compact card metadata.
String _durationLabel(int? durationMinutes) {
  if (durationMinutes == null) {
    return 'No estimate';
  }
  if (durationMinutes < 60) {
    return '$durationMinutes min';
  }
  final hours = durationMinutes ~/ 60;
  final minutes = durationMinutes % 60;
  if (minutes == 0) {
    return '${hours}h';
  }
  return '${hours}h ${minutes}m';
}
