import 'package:flutter/material.dart';
import 'package:hl_lieferservice/model/article.dart';
import 'package:hl_lieferservice/model/component.dart';

/// Identifier-Helpers für den Hold-State-Set: ein Artikel ohne Komponenten
/// wird mit seiner [Article.internalId] referenziert, eine Komponente mit
/// `<articleInternalId>:<componentArticleNumber>`.
///
/// Wir nutzen bewusst ein einfaches String-Schema statt einer eigenen Klasse,
/// weil der Set-Lookup in jedem Row-Rebuild stattfindet und Sets von
/// einfachen Strings am preisgünstigsten sind.
class HoldKey {
  /// Schlüssel für einen ganzen (Nicht-Parent-)Artikel.
  static String article(Article a) => "art:${a.internalId}";

  /// Schlüssel für eine Komponente (Stücklisten-Position) unterhalb eines
  /// Parent-Artikels.
  static String component(Article parent, Component c) =>
      "comp:${parent.internalId}:${c.articleNumber}";
}

/// Visuelle Konstanten für die "Heute zurückgehalten"-Markierung.
const _holdBadgeColor = Colors.deepOrange;

/// Renderer für eine Artikelzeile innerhalb der Beladen-Phase.
///
/// Unterscheidet automatisch zwischen Parent-Artikel (Stückliste) und
/// regulärem Artikel — die Komponenten werden in einem [ParentArticleRow]
/// inkl. Liste von [ComponentRow] aufgeklappt dargestellt. Außerhalb dieser
/// Klasse sollte nur [ArticleRow] direkt verwendet werden; die anderen
/// beiden Widgets sind als Subkomponenten exportiert, falls jemand sie
/// gezielt ansteuern möchte.
class ArticleRow extends StatelessWidget {
  const ArticleRow({
    super.key,
    required this.article,
    required this.isHeld,
    required this.disabled,
    this.heldComponents = const <String>{},
    this.onTap,
    this.onLongPress,
  });

  /// Der darzustellende Artikel.
  final Article article;

  /// `true`, wenn der Artikel als Ganzes für heute zurückgehalten ist.
  /// Bei Parent-Artikeln wird dies an die Komponenten weitergereicht.
  final bool isHeld;

  /// `true`, wenn die Lieferung selbst (z. B. wegen Abbruch) deaktiviert
  /// ist — die Zeile wird grundsätzlich ausgegraut, Tap deaktiviert.
  final bool disabled;

  /// Set der gehaltenen Komponenten-Schlüssel (siehe [HoldKey.component]).
  /// Wird nur ausgewertet, wenn der Artikel ein Parent ist.
  final Set<String> heldComponents;

  /// Optional: Tap-Callback, z. B. um den Artikel "manuell" zu inkrementieren.
  /// Bleibt für die Beladen-Phase aktuell `null` — der Scan-Flow geht über
  /// den Scanner, nicht den Tap. Lässt aber Raum für spätere Komfort-Aktionen.
  final VoidCallback? onTap;

  /// Optional: Long-Press, z. B. für ein Kontext-Menü (Unscan).
  final VoidCallback? onLongPress;

  @override
  Widget build(BuildContext context) {
    if (article.isParent && article.components.isNotEmpty) {
      return ParentArticleRow(
        article: article,
        parentHeld: isHeld,
        disabled: disabled,
        heldComponents: heldComponents,
      );
    }
    return _RegularArticleRow(
      article: article,
      isHeld: isHeld,
      disabled: disabled,
      onTap: onTap,
      onLongPress: onLongPress,
    );
  }
}

/// Reguläre Artikel-Zeile (ohne Stückliste) als Card.
class _RegularArticleRow extends StatelessWidget {
  const _RegularArticleRow({
    required this.article,
    required this.isHeld,
    required this.disabled,
    this.onTap,
    this.onLongPress,
  });

  final Article article;
  final bool isHeld;
  final bool disabled;
  final VoidCallback? onTap;
  final VoidCallback? onLongPress;

  @override
  Widget build(BuildContext context) {
    final entryDone = article.isFullyScanned;
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;
    final effectiveDisabled = disabled || isHeld;

    // Card-Styling abhängig vom Status: gescannt = grünlicher Akzent,
    // zurückgehalten = orange-Akzent, sonst neutral. So sieht der Fahrer
    // beim Scrollen ohne Lesen, was schon erledigt ist.
    final Color cardColor;
    final Color borderColor;
    final IconData leadingIcon;
    final Color leadingColor;

    if (isHeld) {
      cardColor = _holdBadgeColor.withValues(alpha: 0.07);
      borderColor = _holdBadgeColor.withValues(alpha: 0.45);
      leadingIcon = Icons.pause_circle_outline;
      leadingColor = _holdBadgeColor;
    } else if (entryDone) {
      cardColor = Colors.green.withValues(alpha: 0.07);
      borderColor = Colors.green.withValues(alpha: 0.45);
      leadingIcon = Icons.check_circle;
      leadingColor = Colors.green.shade700;
    } else {
      cardColor = scheme.surfaceContainerLow;
      borderColor = scheme.outlineVariant.withValues(alpha: 0.4);
      leadingIcon = Icons.inventory_2_outlined;
      leadingColor = scheme.onSurfaceVariant;
    }

    return Opacity(
      opacity: effectiveDisabled ? 0.45 : 1.0,
      child: Card(
        margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
        elevation: 0,
        color: cardColor,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12),
          side: BorderSide(color: borderColor),
        ),
        child: InkWell(
          onTap: effectiveDisabled ? null : onTap,
          onLongPress: effectiveDisabled ? null : onLongPress,
          borderRadius: BorderRadius.circular(12),
          child: Padding(
            padding: const EdgeInsets.fromLTRB(12, 10, 12, 10),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Container(
                      width: 36,
                      height: 36,
                      decoration: BoxDecoration(
                        color: leadingColor.withValues(alpha: 0.15),
                        shape: BoxShape.circle,
                      ),
                      child: Icon(leadingIcon, color: leadingColor, size: 20),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            article.name,
                            style: TextStyle(
                              fontSize: 15,
                              fontWeight: FontWeight.w600,
                              decoration: isHeld
                                  ? TextDecoration.lineThrough
                                  : TextDecoration.none,
                            ),
                          ),
                          const SizedBox(height: 2),
                          Text(
                            "Artikelnr. ${article.articleNumber}",
                            style: TextStyle(
                              fontSize: 12,
                              color: scheme.onSurfaceVariant,
                            ),
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(width: 8),
                    _ScanCountBadge(
                      done: article.scannedAmount + article.scannedRemovedAmount,
                      total: article.amount,
                      isComplete: entryDone,
                    ),
                  ],
                ),
                if (isHeld) ...[
                  const SizedBox(height: 8),
                  const _HeldBadge(),
                ],
              ],
            ),
          ),
        ),
      ),
    );
  }
}

/// Parent-Artikel (Stückliste) — zeigt eine Header-Zeile und darunter die
/// einzelnen Komponenten als [ComponentRow].
class ParentArticleRow extends StatelessWidget {
  const ParentArticleRow({
    super.key,
    required this.article,
    required this.parentHeld,
    required this.disabled,
    this.heldComponents = const <String>{},
  });

  /// Der Parent-Artikel (muss `isParent == true` und `components.isNotEmpty`).
  final Article article;

  /// `true`, wenn der gesamte Parent-Artikel zurückgehalten ist
  /// (vererbt sich auf alle Komponenten).
  final bool parentHeld;

  /// `true`, wenn die Lieferung deaktiviert ist (z. B. abgebrochen).
  final bool disabled;

  /// Set der gehaltenen Komponenten-Schlüssel (siehe [HoldKey.component]).
  final Set<String> heldComponents;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;
    final allDone = article.isFullyScanned;
    final scannedCount =
        article.components.where((c) => c.isFullyScanned).length;
    final effectiveDisabled = disabled || parentHeld;

    // Card-Styling für Stückliste — gleiche Logik wie reguläre Artikel,
    // aber mit Stücklisten-Icon und der Komponenten-Liste innerhalb derselben
    // Card (visuell gruppiert).
    final Color cardColor;
    final Color borderColor;
    final IconData headerIcon;
    final Color headerIconColor;

    if (parentHeld) {
      cardColor = _holdBadgeColor.withValues(alpha: 0.07);
      borderColor = _holdBadgeColor.withValues(alpha: 0.45);
      headerIcon = Icons.pause_circle_outline;
      headerIconColor = _holdBadgeColor;
    } else if (allDone) {
      cardColor = Colors.green.withValues(alpha: 0.07);
      borderColor = Colors.green.withValues(alpha: 0.45);
      headerIcon = Icons.check_circle;
      headerIconColor = Colors.green.shade700;
    } else {
      cardColor = scheme.surfaceContainerLow;
      borderColor = scheme.outlineVariant.withValues(alpha: 0.4);
      headerIcon = Icons.account_tree_outlined;
      headerIconColor = scheme.primary;
    }

    return Opacity(
      opacity: effectiveDisabled ? 0.45 : 1.0,
      child: Card(
        margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
        elevation: 0,
        color: cardColor,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12),
          side: BorderSide(color: borderColor),
        ),
        child: Padding(
          padding: const EdgeInsets.fromLTRB(12, 10, 12, 10),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              // Header-Reihe mit Icon, Name, Komponenten-Counter.
              Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                    width: 36,
                    height: 36,
                    decoration: BoxDecoration(
                      color: headerIconColor.withValues(alpha: 0.15),
                      shape: BoxShape.circle,
                    ),
                    child:
                        Icon(headerIcon, color: headerIconColor, size: 20),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          article.name,
                          style: TextStyle(
                            fontSize: 15,
                            fontWeight: FontWeight.w600,
                            decoration: parentHeld
                                ? TextDecoration.lineThrough
                                : TextDecoration.none,
                          ),
                        ),
                        const SizedBox(height: 2),
                        Text(
                          "Stückliste · $scannedCount/${article.components.length} Komponenten",
                          style: TextStyle(
                            fontSize: 12,
                            color: scheme.onSurfaceVariant,
                          ),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(width: 8),
                  Icon(
                    allDone ? Icons.check_circle : Icons.pending_outlined,
                    color: allDone ? Colors.green : Colors.orange,
                    size: 22,
                  ),
                ],
              ),
              if (parentHeld) ...[
                const SizedBox(height: 8),
                const _HeldBadge(),
              ],
              if (article.components.isNotEmpty) ...[
                const SizedBox(height: 10),
                Divider(
                  height: 1,
                  color: scheme.outlineVariant.withValues(alpha: 0.6),
                ),
                const SizedBox(height: 6),
                ...article.components.map(
                  (c) => ComponentRow(
                    component: c,
                    parentArticle: article,
                    isHeld: parentHeld ||
                        heldComponents.contains(HoldKey.component(article, c)),
                    disabled: disabled,
                  ),
                ),
              ],
            ],
          ),
        ),
      ),
    );
  }
}

/// Eine einzelne Komponenten-Zeile (Position einer Stückliste).
class ComponentRow extends StatelessWidget {
  const ComponentRow({
    super.key,
    required this.component,
    required this.parentArticle,
    required this.isHeld,
    required this.disabled,
  });

  /// Die Komponente.
  final Component component;

  /// Parent-Artikel zur Auflösung des Hold-Keys & Anzeige-Kontextes.
  final Article parentArticle;

  /// `true`, wenn diese Komponente (oder der Parent) zurückgehalten ist.
  final bool isHeld;

  /// `true`, wenn die Lieferung deaktiviert ist.
  final bool disabled;

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    final done = component.isFullyScanned;
    final effectiveDisabled = disabled || isHeld;

    // Component-Reihe sitzt INNERHALB der Parent-Card — daher kein eigener
    // Card-Wrapper. Stattdessen klare Einrückung + dezente Status-Markierung.
    final Color iconColor = done
        ? Colors.green.shade700
        : (isHeld ? _holdBadgeColor : scheme.onSurfaceVariant);
    final IconData icon = isHeld
        ? Icons.pause_circle_outline
        : (done ? Icons.check_circle : Icons.radio_button_unchecked);

    return Opacity(
      opacity: effectiveDisabled ? 0.45 : 1.0,
      child: Padding(
        padding: const EdgeInsets.fromLTRB(48, 6, 4, 6),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Row(
              children: [
                Icon(icon, color: iconColor, size: 18),
                const SizedBox(width: 10),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        component.name,
                        style: TextStyle(
                          fontSize: 13,
                          fontWeight: FontWeight.w500,
                          decoration: isHeld
                              ? TextDecoration.lineThrough
                              : TextDecoration.none,
                        ),
                      ),
                      Text(
                        "Artikelnr. ${component.articleNumber}",
                        style: TextStyle(
                          fontSize: 11,
                          color: scheme.onSurfaceVariant,
                        ),
                      ),
                    ],
                  ),
                ),
                _ScanCountBadge(
                  done: component.scannedAmount,
                  total: component.requiredAmount,
                  isComplete: done,
                  compact: true,
                ),
              ],
            ),
            if (isHeld) ...[
              const SizedBox(height: 4),
              const _HeldBadge(indented: true),
            ],
          ],
        ),
      ),
    );
  }
}

/// Kompaktes Mengen-Badge `x / y×` für Artikel-/Komponenten-Karten.
/// `compact: true` reduziert Padding und Schriftgröße für die Verwendung
/// innerhalb der Parent-Card.
class _ScanCountBadge extends StatelessWidget {
  const _ScanCountBadge({
    required this.done,
    required this.total,
    required this.isComplete,
    this.compact = false,
  });

  final int done;
  final int total;
  final bool isComplete;
  final bool compact;

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    final color = isComplete ? Colors.green.shade700 : scheme.primary;

    return Container(
      padding: EdgeInsets.symmetric(
        horizontal: compact ? 8 : 10,
        vertical: compact ? 3 : 5,
      ),
      decoration: BoxDecoration(
        color: color.withValues(alpha: 0.12),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        "$done / $total×",
        style: TextStyle(
          fontSize: compact ? 11 : 13,
          fontWeight: FontWeight.bold,
          color: color,
        ),
      ),
    );
  }
}

class _HeldBadge extends StatelessWidget {
  const _HeldBadge({this.indented = false});

  /// Linke Einrückung — für Komponenten unter dem Parent-Header in der Card.
  final bool indented;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(left: indented ? 28 : 0),
      child: Align(
        alignment: Alignment.centerLeft,
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
          decoration: BoxDecoration(
            color: _holdBadgeColor.withValues(alpha: 0.14),
            borderRadius: BorderRadius.circular(6),
            border: Border.all(color: _holdBadgeColor.withValues(alpha: 0.5)),
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: const [
              Icon(Icons.pause_circle_outline,
                  size: 12, color: _holdBadgeColor),
              SizedBox(width: 4),
              Text(
                "Heute zurückgehalten",
                style: TextStyle(
                  fontSize: 11,
                  fontWeight: FontWeight.w600,
                  color: _holdBadgeColor,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
