// lib/editor/canvas/pen_palette_widgets.dart
//
// Shared Material 3 chrome for the pen-first editors (PDF, note, slide) so the
// floating tool palette looks and behaves identically everywhere — one source
// of truth for the inking UI.

import 'package:flutter/material.dart';

import '../../l10n/app_localizations.dart';
import '../engine/brush.dart';
import 'editor_tool.dart';

/// Shared ink color palette for PDF / note / slide / scratch editors.
const List<Color> kInkPalette = <Color>[
  Color(0xFF1A1A1A),
  Color(0xFFC62828),
  Color(0xFF1565C0),
  Color(0xFF2E7D32),
  Color(0xFFEF6C00),
  Color(0xFF6A1B9A),
  Color(0xFF00838F),
  Color(0xFF5D4037),
  Color(0xFFF9A825),
  Color(0xFFE91E63),
  Color(0xFF455A64),
  Color(0xFF37474F),
];

/// Localized display name for a brush (single source so all three editors agree).
String brushLabel(BrushKind kind, AppLocalizations l) => switch (kind) {
      BrushKind.fountainPen => l.brushFountainPen,
      BrushKind.ballpoint => l.brushBallpoint,
      BrushKind.pencil => l.brushPencil,
      BrushKind.highlighter => l.brushHighlighter,
    };

/// English fallback brush name, for the note/slide editors which (like their
/// other chrome) use hardcoded English strings rather than [AppLocalizations]
/// (their test harness mounts a MaterialApp without localization delegates).
/// TODO(brush-l10n-noteslide): localize the note/slide toolbars wholesale.
String brushLabelEn(BrushKind kind) => switch (kind) {
      BrushKind.fountainPen => 'Fountain pen',
      BrushKind.ballpoint => 'Ballpoint',
      BrushKind.pencil => 'Pencil',
      BrushKind.highlighter => 'Highlighter',
    };

/// Localized display name for a shape kind.
String shapeLabel(ShapeKind kind, AppLocalizations l) => switch (kind) {
      ShapeKind.line => l.shapeLine,
      ShapeKind.rectangle => l.shapeRectangle,
      ShapeKind.ellipse => l.shapeEllipse,
      ShapeKind.arrow => l.shapeArrow,
    };

/// English fallback shape name (for the note/slide editors which use hardcoded
/// English strings — see [brushLabelEn]).
/// TODO(brush-l10n-noteslide): localize the note/slide toolbars wholesale.
String shapeLabelEn(ShapeKind kind) => switch (kind) {
      ShapeKind.line => 'Line',
      ShapeKind.rectangle => 'Rectangle',
      ShapeKind.ellipse => 'Ellipse',
      ShapeKind.arrow => 'Arrow',
    };

/// The brushes selectable as the PEN tool. The highlighter is its own tool, so
/// it is NOT offered here (eraser is also a separate tool).
const List<BrushKind> kPenToolBrushes = [
  BrushKind.fountainPen,
  BrushKind.ballpoint,
  BrushKind.pencil,
];

/// Material icon for a brush (used in the brush picker + the pen tool button).
IconData brushIcon(BrushKind kind) => switch (kind) {
      BrushKind.fountainPen => Icons.edit_outlined, // nib pen
      BrushKind.ballpoint => Icons.create_outlined, // ballpoint
      BrushKind.pencil => Icons.draw_outlined, // pencil
      BrushKind.highlighter => Icons.brush_outlined, // marker
    };

/// Material icon for a [ShapeKind] (used in the shape picker + tool button).
IconData shapeIcon(ShapeKind kind) => switch (kind) {
      ShapeKind.line => Icons.show_chart, // straight line
      ShapeKind.rectangle => Icons.crop_square,
      ShapeKind.ellipse => Icons.circle_outlined,
      ShapeKind.arrow => Icons.arrow_outward,
    };

/// A dropdown that selects the active PEN brush (fountain / ballpoint / pencil).
///
/// Highlighter and eraser remain separate tools. Tapping the button opens a
/// menu of [kPenToolBrushes]; the chosen brush is reported via [onSelected].
/// [labelFor] localizes each brush name so the menu honors the app locale.
/// [colorFor] returns each brush's REMEMBERED color (rnote-style per-brush color
/// memory): the active brush's color is shown as an underline on the button and
/// as a dot beside each menu item, so the toolbar makes each brush's color
/// visible at a glance.
class BrushPickerButton extends StatelessWidget {
  const BrushPickerButton({
    super.key,
    required this.selected,
    required this.active,
    required this.onSelected,
    required this.labelFor,
    required this.colorFor,
    required this.tooltip,
  });

  /// The currently selected pen brush.
  final BrushKind selected;

  /// True when the pen tool (this brush) is the active tool — drives highlight.
  final bool active;

  final ValueChanged<BrushKind> onSelected;

  /// Localized display name for a brush.
  final String Function(BrushKind) labelFor;

  /// The remembered color for a brush (drives the underline + menu dots).
  final Color Function(BrushKind) colorFor;

  final String tooltip;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final iconColor =
        active ? cs.onSecondaryContainer : cs.onSurfaceVariant;
    return PopupMenuButton<BrushKind>(
      tooltip: tooltip,
      initialValue: selected,
      onSelected: onSelected,
      itemBuilder: (context) => [
        for (final b in kPenToolBrushes)
          PopupMenuItem<BrushKind>(
            value: b,
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(brushIcon(b), size: 20),
                const SizedBox(width: 10),
                Text(labelFor(b)),
                const SizedBox(width: 8),
                // The brush's remembered color (rnote per-brush color memory).
                Container(
                  width: 12,
                  height: 12,
                  decoration: BoxDecoration(
                    color: colorFor(b),
                    shape: BoxShape.circle,
                    border: Border.all(color: cs.outlineVariant),
                  ),
                ),
                if (b == selected) ...[
                  const SizedBox(width: 8),
                  Icon(Icons.check, size: 18, color: cs.primary),
                ],
              ],
            ),
          ),
      ],
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 150),
        margin: const EdgeInsets.symmetric(horizontal: 2),
        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 8),
        decoration: BoxDecoration(
          color: active ? cs.secondaryContainer : Colors.transparent,
          borderRadius: BorderRadius.circular(20),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(brushIcon(selected), size: 22, color: iconColor),
                Icon(Icons.arrow_drop_down, size: 18, color: iconColor),
              ],
            ),
            // Per-brush color underline: shows the active brush's remembered
            // color so switching brushes visibly switches the color.
            Container(
              height: 3,
              width: 24,
              decoration: BoxDecoration(
                color: colorFor(selected),
                borderRadius: BorderRadius.circular(2),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

/// A toggle-style tool button that doubles as a [ShapeKind] picker: a short tap
/// activates the shape tool with the current shape; a long-press (or the dropdown
/// caret) opens the line / rectangle / ellipse / arrow submenu.
class ShapePickerButton extends StatelessWidget {
  const ShapePickerButton({
    super.key,
    required this.selected,
    required this.active,
    required this.onActivate,
    required this.onSelected,
    required this.labelFor,
    required this.tooltip,
  });

  /// The currently selected shape kind.
  final ShapeKind selected;

  /// True when the shape tool is the active tool — drives highlight.
  final bool active;

  /// Called when the button body is tapped (activate the shape tool).
  final VoidCallback onActivate;

  /// Called when a shape kind is picked from the submenu (also activates).
  final ValueChanged<ShapeKind> onSelected;

  /// Localized display name for a shape kind.
  final String Function(ShapeKind) labelFor;

  final String tooltip;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final iconColor = active ? cs.onSecondaryContainer : cs.onSurfaceVariant;
    return PopupMenuButton<ShapeKind>(
      tooltip: tooltip,
      initialValue: selected,
      onSelected: onSelected,
      itemBuilder: (context) => [
        for (final s in ShapeKind.values)
          PopupMenuItem<ShapeKind>(
            value: s,
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(shapeIcon(s), size: 20),
                const SizedBox(width: 10),
                Text(labelFor(s)),
                if (s == selected) ...[
                  const SizedBox(width: 8),
                  Icon(Icons.check, size: 18, color: cs.primary),
                ],
              ],
            ),
          ),
      ],
      child: InkWell(
        borderRadius: BorderRadius.circular(20),
        onTap: onActivate,
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 150),
          margin: const EdgeInsets.symmetric(horizontal: 2),
          padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 8),
          decoration: BoxDecoration(
            color: active ? cs.secondaryContainer : Colors.transparent,
            borderRadius: BorderRadius.circular(20),
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(shapeIcon(selected), size: 22, color: iconColor),
              Icon(Icons.arrow_drop_down, size: 18, color: iconColor),
            ],
          ),
        ),
      ),
    );
  }
}

/// A Material 3 toggle-style icon button for the floating tool palette.
class ToolButton extends StatelessWidget {
  const ToolButton({
    super.key,
    required this.icon,
    required this.selected,
    required this.tooltip,
    required this.onPressed,
  });

  final IconData icon;
  final bool selected;
  final String tooltip;

  /// Tap handler. When null the button renders disabled (dimmed, no ripple).
  final VoidCallback? onPressed;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final enabled = onPressed != null;
    final iconColor = !enabled
        ? cs.onSurfaceVariant.withValues(alpha: 0.38)
        : selected
            ? cs.onSecondaryContainer
            : cs.onSurfaceVariant;
    return Tooltip(
      message: tooltip,
      child: InkWell(
        borderRadius: BorderRadius.circular(20),
        onTap: onPressed,
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 150),
          margin: const EdgeInsets.symmetric(horizontal: 2),
          padding: const EdgeInsets.all(8),
          decoration: BoxDecoration(
            color: selected ? cs.secondaryContainer : Colors.transparent,
            borderRadius: BorderRadius.circular(20),
          ),
          child: Icon(icon, size: 22, color: iconColor),
        ),
      ),
    );
  }
}

/// A thin vertical divider between palette groups.
class PaletteDivider extends StatelessWidget {
  const PaletteDivider({super.key, required this.cs});
  final ColorScheme cs;
  @override
  Widget build(BuildContext context) => Container(
        width: 1,
        height: 24,
        margin: const EdgeInsets.symmetric(horizontal: 6),
        color: cs.outlineVariant,
      );
}

/// A round, tonal icon button (used for the floating back button).
class RoundIconButton extends StatelessWidget {
  const RoundIconButton({
    super.key,
    required this.icon,
    required this.tooltip,
    required this.onPressed,
  });

  final IconData icon;
  final String tooltip;
  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    return Material(
      color: cs.surfaceContainerHigh,
      elevation: 3,
      shape: const CircleBorder(),
      child: IconButton(
        tooltip: tooltip,
        icon: Icon(icon),
        color: cs.onSurfaceVariant,
        onPressed: onPressed,
      ),
    );
  }
}
