import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:llswidget/llswidget.dart';

void main() {
  const text = 'click me';
  const textStyle = TextStyle(fontSize: 14, color: Colors.black);
  const size = LLSSize.SMALL;
  const childWidget = Text('tap me');

  testWidgets('Disabled LLS Button can be constructed', (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: null,
      text: text,
      size: size,
      disabledColor: Colors.teal.shade300,
      disabledElevation: 3,
      disabledTextColor: LLSColors.LIGHT,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.onPressed, null);
    expect(app.button.disabledColor, Colors.teal.shade300);
    expect(app.button.disabledElevation, 3);
    expect(app.button.disabledTextColor, LLSColors.LIGHT);

    await tester.tap(find.byKey(buttonKey));
    await tester.pump();

    await tester.pumpWidget(app);
  });

  testWidgets('LLS Button can be constructed', (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      color: LLSColors.ALT,
      textStyle: textStyle,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.textStyle, textStyle);
    expect(app.button.size, size);
    expect(app.button.color, LLSColors.ALT);

    await tester.tap(find.byKey(buttonKey));
    await tester.pump();

    await tester.pumpWidget(app);
  });

  testWidgets('LLS Button can be constructed with child for custom text',
      (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      child: childWidget,
      color: Colors.amber,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);
    expect(app.button.child, childWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.color, Colors.amber);

    await tester.tap(find.byKey(buttonKey));
    await tester.pump();

    await tester.pumpWidget(app);
  });

  testWidgets(
      'LLS Button can be constructed with standard type and shape i.e default',
      (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      textColor: LLSColors.DARK,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.textColor, LLSColors.DARK);
    expect(app.button.size, size);

    await tester.tap(find.byKey(buttonKey));
    await tester.pump();
    await tester.press(find.byKey(buttonKey));
    await tester.pump();
    await tester.longPress(find.byKey(buttonKey));
    await tester.pump();

    // await expectLater(() => tester.tap(find.byKey(buttonKey)), prints('onHighlight changed'));

    await tester.pumpWidget(app);
  });

  testWidgets(
      'LLS Button with icon and icon position'
      'and with Block Button', (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      child: childWidget,
      icon: const Icon(
        Icons.directions_bike_sharp,
      ),
      position: LLSPosition.start,
      blockButton: true,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);
    expect(find.byIcon(Icons.directions_bike_sharp), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.position, LLSPosition.start);
    expect(app.button.blockButton, isTrue);
  });

  testWidgets(
      'LLS Button with solid type and pills shape '
      'and Full Width Button', (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      child: childWidget,
      icon: const Icon(
        Icons.directions_bike_sharp,
      ),
      position: LLSPosition.start,
      type: LLSButtonType.solid,
      shape: LLSButtonShape.rounded,
      fullWidthButton: true,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);
    expect(find.byIcon(Icons.directions_bike_sharp), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.position, LLSPosition.start);
    expect(app.button.type, LLSButtonType.solid);
    expect(app.button.shape, LLSButtonShape.rounded);
    expect(app.button.fullWidthButton, isTrue);
  });

  testWidgets('LLS Button with type outline and square shape ', (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      child: childWidget,
      icon: const Icon(
        Icons.directions_bike_sharp,
      ),
      position: LLSPosition.start,
      type: LLSButtonType.outline,
      shape: LLSButtonShape.square,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);
    expect(find.byIcon(Icons.directions_bike_sharp), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.position, LLSPosition.start);
    expect(app.button.type, LLSButtonType.outline);
    expect(app.button.shape, LLSButtonShape.square);
  });

  testWidgets('LLS Button with custom border and shape ', (tester) async {
    const buttonKey = Key('header');

    const border = BorderSide(
        color: Colors.tealAccent, width: 1, style: BorderStyle.solid);
    const shape = RoundedRectangleBorder(
        side:
            BorderSide(color: Colors.pink, width: 2, style: BorderStyle.solid),
        borderRadius: BorderRadius.zero);

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      borderShape: shape,
      borderSide: border,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.borderShape, shape);
    expect(app.button.borderSide, border);
  });

  testWidgets('LLS Button with boxshadow ', (tester) async {
    const buttonKey = Key('header');

    const boxshadow = BoxShadow(
      color: Colors.pink,
      blurRadius: 2,
      spreadRadius: 1,
      offset: Offset.zero,
    );

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      buttonBoxShadow: true,
      boxShadow: boxshadow,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.buttonBoxShadow, isTrue);
    expect(app.button.boxShadow, boxshadow);
  });

  testWidgets(
      'LLS Button with hover, focus, highlight and splash color. Works only in web',
      (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      hoverColor: Colors.tealAccent,
      focusColor: Colors.teal,
      highlightColor: Colors.amber,
      splashColor: Colors.red,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.hoverColor, Colors.tealAccent);
    expect(app.button.focusColor, Colors.teal);
    expect(app.button.highlightColor, Colors.amber);
    expect(app.button.splashColor, Colors.red);
  });

  testWidgets(
      'LLS Button with hover, focus, highlight and splash color. Works only in web',
      (tester) async {
    const buttonKey = Key('header');

    final LLSButton button = LLSButton(
      key: buttonKey,
      onPressed: () {},
      text: text,
      size: size,
      elevation: 3,
      focusElevation: 2,
      hoverElevation: 2,
      highlightElevation: 4,
    );

    final TestApp app = TestApp(button);

    await tester.pumpWidget(app);

    expect(find.text('click me'), findsOneWidget);

    expect(app.button.text, text);
    expect(app.button.size, size);
    expect(app.button.elevation, 3);
    expect(app.button.focusElevation, 2);
    expect(app.button.hoverElevation, 2);
    expect(app.button.highlightElevation, 4);
  });
}

class TestApp extends StatefulWidget {
  const TestApp(this.button);

  final LLSButton button;

  @override
  _TestAppState createState() => _TestAppState();
}

class _TestAppState extends State<TestApp> {
  @override
  Widget build(BuildContext context) => MaterialApp(
      home: Scaffold(
        body: Column(
          children: [
            widget.button,
          ],
        ),
      ),
    );
}
