/*
 * @Author: XianKaiQun
 * @Date: 2020-04-29 10:38:26
 * @LastEditors  : WuWei
 * @LastEditTime : 2023-05-18 15:34:53
 * @Descripttion:
 */
import 'package:flutter/material.dart';

class WisBoxInkWell {
  WisBoxInkWell({
    this.onTap,
    this.onDoubleTap,
    this.onLongPress,
    this.onTapDown,
    this.onTapCancel,
    this.onHighlightChanged,
    this.onHover,
    this.focusColor,
    this.hoverColor,
    this.highlightColor,
    this.splashColor,
    this.splashFactory,
    this.radius,
    this.borderRadius,
    this.customBorder,
    this.enableFeedback = true,
    this.excludeFromSemantics = false,
    this.focusNode,
    this.canRequestFocus = true,
    this.onFocusChange,
    this.autofocus,
  });

  final GestureTapCallback? onTap;
  final GestureTapCallback? onDoubleTap;
  final GestureLongPressCallback? onLongPress;
  final GestureTapDownCallback? onTapDown;
  final GestureTapCancelCallback? onTapCancel;
  final ValueChanged<bool>? onHighlightChanged;
  final ValueChanged<bool>? onHover;
  final Color? focusColor;
  final Color? hoverColor;
  final Color? highlightColor;
  final Color? splashColor;
  final InteractiveInkFeatureFactory? splashFactory;
  final double? radius;
  final BorderRadius? borderRadius;
  final ShapeBorder? customBorder;
  final bool enableFeedback;
  final bool excludeFromSemantics;
  final FocusNode? focusNode;
  final bool canRequestFocus;
  final ValueChanged<bool>? onFocusChange;
  final bool? autofocus;
}

class Wisdom extends StatelessWidget {
  const Wisdom({
    Key? key,
    this.onTap,
    this.inkWell,
    this.alignment,
    this.width,
    this.height,
    this.minWidth,
    this.maxWidth,
    this.minHeight,
    this.maxHeight,
    this.padding,
    this.margin,
    this.color,
    this.image,
    this.border,
    this.borderRadius,
    this.boxShadow,
    this.gradient,
    this.backgroundBlendMode,
    this.shape,
    this.foregroundDecoration,
    this.transform,
    this.child,
  }) : super(key: key);

  /// Wisdom下套一个row
  Wisdom.row({
    Key? key,
    this.onTap,
    this.inkWell,
    this.alignment,
    this.width,
    this.height,
    this.minWidth,
    this.maxWidth,
    this.minHeight,
    this.maxHeight,
    this.padding,
    this.margin,
    this.color,
    this.image,
    this.border,
    this.borderRadius,
    this.boxShadow,
    this.gradient,
    this.backgroundBlendMode,
    this.shape,
    this.foregroundDecoration,
    this.transform,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection? textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline? textBaseline,
    List<Widget> children = const <Widget>[],
  })  : this.child = Row(
          mainAxisAlignment: mainAxisAlignment,
          mainAxisSize: mainAxisSize,
          crossAxisAlignment: crossAxisAlignment,
          textDirection: textDirection,
          verticalDirection: verticalDirection,
          textBaseline: textBaseline,
          children: children,
        ),
        super(key: key);

  /// Wisdom下套一个column
  Wisdom.column({
    Key? key,
    this.onTap,
    this.inkWell,
    this.alignment,
    this.width,
    this.height,
    this.minWidth,
    this.maxWidth,
    this.minHeight,
    this.maxHeight,
    this.padding,
    this.margin,
    this.color,
    this.image,
    this.border,
    this.borderRadius,
    this.boxShadow,
    this.gradient,
    this.backgroundBlendMode,
    this.shape,
    this.foregroundDecoration,
    this.transform,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection? textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline? textBaseline,
    List<Widget> children = const <Widget>[],
  })  : this.child = Column(
          mainAxisAlignment: mainAxisAlignment,
          mainAxisSize: mainAxisSize,
          crossAxisAlignment: crossAxisAlignment,
          textDirection: textDirection,
          verticalDirection: verticalDirection,
          textBaseline: textBaseline,
          children: children,
        ),
        super(key: key);

  /// Wisdom下套一个wrap
  Wisdom.wrap({
    Key? key,
    this.onTap,
    this.inkWell,
    this.alignment,
    this.width,
    this.height,
    this.minWidth,
    this.maxWidth,
    this.minHeight,
    this.maxHeight,
    this.padding,
    this.margin,
    this.color,
    this.image,
    this.border,
    this.borderRadius,
    this.boxShadow,
    this.gradient,
    this.backgroundBlendMode,
    this.shape = BoxShape.rectangle,
    this.foregroundDecoration,
    this.transform,
    Axis direction = Axis.horizontal,
    WrapAlignment wrapAlignment = WrapAlignment.start,
    double spacing = 0.0,
    WrapAlignment runAlignment = WrapAlignment.start,
    double runSpacing = 0.0,
    WrapCrossAlignment crossAxisAlignment = WrapCrossAlignment.start,
    TextDirection? textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    List<Widget> children = const <Widget>[],
  })  : this.child = Wrap(
          alignment: wrapAlignment,
          spacing: spacing,
          runAlignment: runAlignment,
          runSpacing: runSpacing,
          crossAxisAlignment: crossAxisAlignment,
          textDirection: textDirection,
          verticalDirection: verticalDirection,
          children: children,
        ),
        super(key: key);

  /// Wisdom下套一个Stack
  Wisdom.stack({
    Key? key,
    this.onTap,
    this.inkWell,
    this.alignment,
    this.width,
    this.height,
    this.minWidth,
    this.maxWidth,
    this.minHeight,
    this.maxHeight,
    this.padding,
    this.margin,
    this.color,
    this.image,
    this.border,
    this.borderRadius,
    this.boxShadow,
    this.gradient,
    this.backgroundBlendMode,
    this.shape = BoxShape.rectangle,
    this.foregroundDecoration,
    this.transform,
    AlignmentGeometry stackalignment = AlignmentDirectional.topStart,
    TextDirection? textDirection,
    StackFit fit = StackFit.loose,
    Clip? clipBehavior,
    // Overflow overflow = Overflow.clip,
    List<Widget> children = const <Widget>[],
  })  : this.child = Stack(
          alignment: stackalignment,
          textDirection: textDirection,
          fit: fit,
          clipBehavior: clipBehavior ?? Clip.none,
          children: children,
        ),
        super(key: key);

  /// Wisdom富文本
  Wisdom.rich({
    Key? key,
    this.onTap,
    this.inkWell,
    this.alignment,
    this.width,
    this.height,
    this.minWidth,
    this.maxWidth,
    this.minHeight,
    this.maxHeight,
    this.padding,
    this.margin,
    this.color,
    this.image,
    this.border,
    this.borderRadius,
    this.boxShadow,
    this.gradient,
    this.backgroundBlendMode,
    this.shape = BoxShape.rectangle,
    this.foregroundDecoration,
    this.transform,
    List<InlineSpan>? children,
    TextAlign textAlign = TextAlign.start,
    TextDirection? textDirection,
    bool softWrap = true,
    TextOverflow overflow = TextOverflow.clip,
    double textScaleFactor = 1.0,
    int? maxLines,
    Locale? locale,
    StrutStyle? strutStyle,
    TextWidthBasis textWidthBasis = TextWidthBasis.parent,
    TextStyle? style,
  })  : this.child = Text.rich(
          TextSpan(
            children: children,
            style: style,
          ),
          textAlign: textAlign,
          textDirection: textDirection,
          softWrap: softWrap,
          overflow: overflow,
          textScaleFactor: textScaleFactor,
          maxLines: maxLines,
          locale: locale,
          strutStyle: strutStyle,
          textWidthBasis: textWidthBasis,
        ),
        super(key: key);
  final GestureTapCallback? onTap;
  final WisBoxInkWell? inkWell;
  final AlignmentGeometry? alignment;
  final double? width;
  final double? height;
  final double? minWidth;
  final double? maxWidth;
  final double? minHeight;
  final double? maxHeight;
  final EdgeInsetsGeometry? padding;
  final EdgeInsetsGeometry? margin;
  final Color? color;
  final DecorationImage? image;
  final BoxBorder? border;
  final BorderRadiusGeometry? borderRadius;
  final List<BoxShadow>? boxShadow;
  final Gradient? gradient;
  final BlendMode? backgroundBlendMode;
  final BoxShape? shape;
  final Decoration? foregroundDecoration;
  final Matrix4? transform;
  final Widget? child;

  BoxDecoration? get _decoration {
    bool has = [
          color,
          image,
          border,
          borderRadius,
          boxShadow,
          gradient,
          backgroundBlendMode,
          shape,
        ].indexWhere((item) => item != null) !=
        -1;
    if (has) {
      return BoxDecoration(
        color: color,
        image: image,
        border: border,
        borderRadius: borderRadius,
        boxShadow: boxShadow,
        gradient: gradient,
        backgroundBlendMode: backgroundBlendMode,
        shape: shape ?? BoxShape.rectangle,
      );
    } else {
      return null;
    }
  }

  BoxConstraints? get _boxConstraints {
    bool has = [
          minWidth,
          maxWidth,
          minHeight,
          maxHeight,
        ].indexWhere((item) => item != null) !=
        -1;
    if (has) {
      return BoxConstraints(
        minWidth: minWidth ?? 0,
        maxWidth: maxWidth ?? double.infinity,
        minHeight: minHeight ?? 0,
        maxHeight: maxHeight ?? double.infinity,
      );
    } else {
      return null;
    }
  }

  bool get hasInkWell => onTap != null || inkWell != null;

  @override
  Widget build(BuildContext context) {
    Widget? current = child;

    current = Container(
      alignment: alignment,
      padding: padding,
      decoration: _decoration,
      foregroundDecoration: foregroundDecoration,
      width: width,
      height: height,
      constraints: _boxConstraints,
      margin: hasInkWell ? null : margin,
      transform: transform,
      child: current,
    );

    if (hasInkWell) {
      current = InkWell(
        onTap: inkWell?.onTap ?? onTap,
        onDoubleTap: inkWell?.onDoubleTap,
        onLongPress: inkWell?.onLongPress,
        onTapDown: inkWell?.onTapDown,
        onTapCancel: inkWell?.onTapCancel,
        onHighlightChanged: inkWell?.onHighlightChanged,
        onHover: inkWell?.onHover,
        focusColor: inkWell?.focusColor,
        hoverColor: inkWell?.hoverColor,
        highlightColor: inkWell?.highlightColor,
        splashColor: inkWell?.splashColor,
        splashFactory: inkWell?.splashFactory,
        radius: inkWell?.radius,
        borderRadius: inkWell?.borderRadius ?? borderRadius as BorderRadius?,
        customBorder: inkWell?.customBorder,
        enableFeedback: inkWell?.enableFeedback,
        excludeFromSemantics: inkWell?.excludeFromSemantics ?? false,
        focusNode: inkWell?.focusNode,
        canRequestFocus: inkWell?.canRequestFocus ?? true,
        onFocusChange: inkWell?.onFocusChange,
        autofocus: inkWell?.autofocus ?? false,
        child: current,
      );
      if (_decoration != null) {
        current = DecoratedBox(
          decoration: _decoration!,
          child: current,
        );
      }
      if (margin != null) {
        current = Padding(
          padding: margin!,
          child: current,
        );
      }
    }
    return current;
  }
}
