import 'dart:ui';

import 'package:flutter/material.dart';

/// 自定义Tab的指示器
class CustomTabIndicator extends Decoration {
  const CustomTabIndicator({
    // 指示器的宽度
    this.width = 20,
    // 指示器的形状，默认为圆角
    this.strokeCap = StrokeCap.round,
    // 指示器的高度和纯颜色，渐变色优先于这里的纯颜色
    this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
    // 指示器距离Tab的外边距
    this.insets = EdgeInsets.zero,
    // 渐变色
    this.gradient,
  });

  final BorderSide borderSide;
  final EdgeInsetsGeometry insets;

  /// 新增属性：控制器宽度
  final double width;

  /// 新增属性：控制器边角形状
  final StrokeCap strokeCap;

  /// 新增属性：渐变色
  final Gradient? gradient;

  @override
  Decoration? lerpFrom(Decoration? a, double t) {
    if (a is CustomTabIndicator) {
      return CustomTabIndicator(
        borderSide: BorderSide.lerp(a.borderSide, borderSide, t),
        insets: EdgeInsetsGeometry.lerp(a.insets, insets, t)!,
        width: lerpDouble(a.width, width, t)!,
        // 渐变插值
        gradient: Gradient.lerp(a.gradient, gradient, t),
      );
    }
    return super.lerpFrom(a, t);
  }

  @override
  Decoration? lerpTo(Decoration? b, double t) {
    if (b is CustomTabIndicator) {
      return CustomTabIndicator(
        borderSide: BorderSide.lerp(borderSide, b.borderSide, t),
        insets: EdgeInsetsGeometry.lerp(insets, b.insets, t)!,
        width: lerpDouble(width, b.width, t)!,
        // 渐变插值
        gradient: Gradient.lerp(gradient, b.gradient, t),
      );
    }
    return super.lerpTo(b, t);
  }

  @override
  BoxPainter createBoxPainter([VoidCallback? onChanged]) {
    return _UnderlinePainter(this, onChanged);
  }

  /// 决定控制器宽度的方法
  Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
    final Rect indicator = insets.resolve(textDirection).deflateRect(rect);
    double cw = (indicator.left + indicator.right) / 2;

    // 指示器居中
    return Rect.fromLTWH(
      cw - width / 2,
      indicator.bottom - borderSide.width,
      width,
      borderSide.width,
    );
  }

  @override
  Path getClipPath(Rect rect, TextDirection textDirection) {
    return Path()..addRect(_indicatorRectFor(rect, textDirection));
  }
}

class _UnderlinePainter extends BoxPainter {
  _UnderlinePainter(this.decoration, VoidCallback? onChanged)
    : super(onChanged);

  final CustomTabIndicator decoration;

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    final Rect rect = offset & configuration.size!;
    final TextDirection textDirection = configuration.textDirection!;
    final Rect indicator = decoration
        ._indicatorRectFor(rect, textDirection)
        .deflate(decoration.borderSide.width / 2.0);

    final Paint paint =
        Paint()
          ..strokeCap = decoration.strokeCap
          ..strokeWidth = decoration.borderSide.width;

    // 优先使用渐变色
    if (decoration.gradient != null) {
      final gradient = decoration.gradient!;
      paint.shader = gradient.createShader(
        Rect.fromPoints(indicator.bottomLeft, indicator.bottomRight),
      );
    } else {
      // 使用纯色
      paint.color = decoration.borderSide.color;
    }

    canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
  }
}
