import 'package:flutter/material.dart';

import '../about/internal/application/TextType.dart';
import '../utils/Colors.dart';
import 'text/Text.dart';

/// The tick box. Square, hairline border when empty, filled with the accent
/// and a white check when set — and it animates, because the tick is the one
/// moment of satisfaction the app allows itself.
class TickBox extends StatelessWidget {
  final bool checked;

  final VoidCallback? onTap;

  /// The accent used when checked. Defaults to the app's positive green;
  /// callers pass the class colour so the row reads as its own weight.
  final Color? accent;

  final double size;

  /// Renders muted and ignores taps — used for items that are settled.
  final bool locked;

  const TickBox({
    super.key,
    required this.checked,
    this.onTap,
    this.accent,
    this.size = 24,
    this.locked = false,
  });

  @override
  Widget build(BuildContext context) {
    final Color tone = locked ? colorGrey : (accent ?? colorPositive);

    return GestureDetector(
      onTap: locked ? null : onTap,
      // A bare box is a small target; the padding brings it up to a
      // comfortable tap area without changing the drawn size.
      behavior: HitTestBehavior.opaque,
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 2),
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 160),
          curve: Curves.easeOut,
          width: size,
          height: size,
          decoration: BoxDecoration(
            color: checked ? tone : Colors.transparent,
            borderRadius: BorderRadius.circular(7),
            border: Border.all(
              color: checked ? tone : colorGrey.withValues(alpha: 0.55),
              width: 1.6,
            ),
          ),
          child: AnimatedOpacity(
            duration: const Duration(milliseconds: 140),
            opacity: checked ? 1 : 0,
            child: Icon(
              Icons.check_rounded,
              size: size * 0.68,
              color: colorWhite,
            ),
          ),
        ),
      ),
    );
  }
}

/// A task line: tick box, then the title struck through once it is done.
/// Everything else about the row — window, class, cost — is the caller's,
/// passed in as [detail] so this stays one shape used everywhere.
class TickRow extends StatelessWidget {
  final bool checked;

  final String title;

  final VoidCallback? onTick;

  final VoidCallback? onTap;

  final Color? accent;

  /// Secondary line beneath the title.
  final Widget? detail;

  /// Trailing widget — a class pill, a chevron.
  final Widget? trailing;

  /// Struck through and muted, but not tickable.
  final bool locked;

  const TickRow({
    super.key,
    required this.checked,
    required this.title,
    this.onTick,
    this.onTap,
    this.accent,
    this.detail,
    this.trailing,
    this.locked = false,
  });

  @override
  Widget build(BuildContext context) {
    final bool struck = checked || locked;

    return GestureDetector(
      onTap: onTap,
      behavior: HitTestBehavior.opaque,
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 4),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TickBox(
              checked: checked,
              onTap: onTick,
              accent: accent,
              locked: locked,
            ),
            const SizedBox(width: 13),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.only(top: 9),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    // The strikethrough is the whole point of the tick: the
                    // line stays in place so the day still reads as a record
                    // of what was asked, not just what is left.
                    AnimatedDefaultTextStyle(
                      duration: const Duration(milliseconds: 160),
                      style: TextStyle(
                        fontSize: 15,
                        fontFamily: struck ? "GroundedRegular" : "GroundedMedium",
                        color: struck ? colorGrey2 : colorPrimaryDark,
                        decoration: struck
                            ? TextDecoration.lineThrough
                            : TextDecoration.none,
                        decorationColor: colorGrey2,
                        decorationThickness: 1.5,
                        height: 1.35,
                      ),
                      child: Text(
                        title,
                        maxLines: 2,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                    if (detail != null) ...[
                      const SizedBox(height: 6),
                      DefaultTextStyle.merge(
                        style: TextStyle(
                          decoration: TextDecoration.none,
                          color: colorGrey2,
                        ),
                        child: detail!,
                      ),
                    ],
                  ],
                ),
              ),
            ),
            if (trailing != null) ...[
              const SizedBox(width: 10),
              Padding(
                padding: const EdgeInsets.only(top: 8),
                child: trailing!,
              ),
            ],
          ],
        ),
      ),
    );
  }
}

/// "Add new task" — the centred, low-key affordance beneath a day's list.
Widget addTaskAffordance(
  VoidCallback onTap, {
  String label = "Add new task",
  bool enabled = true,
}) {
  final Color tone = enabled ? colorPositive : colorGrey;

  return GestureDetector(
    onTap: enabled ? onTap : null,
    behavior: HitTestBehavior.opaque,
    child: Padding(
      padding: const EdgeInsets.symmetric(vertical: 18),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Container(
            width: 46,
            height: 46,
            alignment: Alignment.center,
            decoration: BoxDecoration(
              color: tone.withValues(alpha: 0.12),
              borderRadius: BorderRadius.circular(14),
              border: Border.all(color: tone.withValues(alpha: 0.25), width: 1),
            ),
            child: Icon(Icons.add_rounded, size: 22, color: tone),
          ),
          const SizedBox(height: 9),
          text(label, 12, TextType.Regular, color: colorGrey2),
        ],
      ),
    ),
  );
}
