// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

import '../rendering/mock_canvas.dart';

const Color green = Color(0xFF00FF00);
const Color yellow = Color(0xFFFFFF00);

void main() {
  testWidgets('SlottedRenderObjectWidget test', (WidgetTester tester) async {
    await tester.pumpWidget(buildWidget(
      topLeft: Container(
        height: 100,
        width: 80,
        color: yellow,
        child: const Text('topLeft'),
      ),
      bottomRight: Container(
        height: 120,
        width: 110,
        color: green,
        child: const Text('bottomRight'),
      ),
    ));

    expect(find.text('topLeft'), findsOneWidget);
    expect(find.text('bottomRight'), findsOneWidget);
    expect(tester.getSize(find.byType(_Diagonal)), const Size(80 + 110, 100 + 120));
    expect(find.byType(_Diagonal), paints
      ..rect(
        rect: const Rect.fromLTWH(0, 0, 80, 100),
        color: yellow,
      )
      ..rect(
        rect: const Rect.fromLTWH(80, 100, 110, 120),
        color: green,
      )
    );

    await tester.pumpWidget(buildWidget(
      topLeft: Container(
        height: 200,
        width: 100,
        color: yellow,
        child: const Text('topLeft'),
      ),
      bottomRight: Container(
        height: 220,
        width: 210,
        color: green,
        child: const Text('bottomRight'),
      ),
    ));

    expect(find.text('topLeft'), findsOneWidget);
    expect(find.text('bottomRight'), findsOneWidget);
    expect(tester.getSize(find.byType(_Diagonal)), const Size(100 + 210, 200 + 220));
    expect(find.byType(_Diagonal), paints
      ..rect(
        rect: const Rect.fromLTWH(0, 0, 100, 200),
        color: yellow,
      )
      ..rect(
        rect: const Rect.fromLTWH(100, 200, 210, 220),
        color: green,
      )
    );

    await tester.pumpWidget(buildWidget(
      topLeft: Container(
        height: 200,
        width: 100,
        color: yellow,
        child: const Text('topLeft'),
      ),
      bottomRight: Container(
        key: UniqueKey(),
        height: 230,
        width: 220,
        color: green,
        child: const Text('bottomRight'),
      ),
    ));

    expect(find.text('topLeft'), findsOneWidget);
    expect(find.text('bottomRight'), findsOneWidget);
    expect(tester.getSize(find.byType(_Diagonal)), const Size(100 + 220, 200 + 230));
    expect(find.byType(_Diagonal), paints
      ..rect(
        rect: const Rect.fromLTWH(0, 0, 100, 200),
        color: yellow,
      )
      ..rect(
        rect: const Rect.fromLTWH(100, 200, 220, 230),
        color: green,
      )
    );

    await tester.pumpWidget(buildWidget(
      topLeft: Container(
        height: 200,
        width: 100,
        color: yellow,
        child: const Text('topLeft'),
      ),
    ));

    expect(find.text('topLeft'), findsOneWidget);
    expect(find.text('bottomRight'), findsNothing);
    expect(tester.getSize(find.byType(_Diagonal)), const Size(100, 200));
    expect(find.byType(_Diagonal), paints
      ..rect(
        rect: const Rect.fromLTWH(0, 0, 100, 200),
        color: yellow,
      )
    );

    await tester.pumpWidget(buildWidget());
    expect(find.text('topLeft'), findsNothing);
    expect(find.text('bottomRight'), findsNothing);
    expect(tester.getSize(find.byType(_Diagonal)), Size.zero);
    expect(find.byType(_Diagonal), paintsNothing);

    await tester.pumpWidget(Container());
    expect(find.byType(_Diagonal), findsNothing);
  });

  test('nameForSlot', () {
    expect(_RenderDiagonal().publicNameForSlot(_DiagonalSlot.bottomRight), 'bottomRight');
    expect(_RenderDiagonal().publicNameForSlot(_DiagonalSlot.topLeft), 'topLeft');
    final _Slot slot = _Slot();
    expect(_RenderTest().publicNameForSlot(slot), slot.toString());
  });

  testWidgets('key reparenting', (WidgetTester tester) async {
    const Widget widget1 = SizedBox(key: ValueKey<String>('smol'), height: 10, width: 10);
    const Widget widget2 = SizedBox(key: ValueKey<String>('big'), height: 100, width: 100);
    const Widget nullWidget = SizedBox(key: ValueKey<String>('null'), height: 50, width: 50);

    await tester.pumpWidget(buildWidget(topLeft: widget1, bottomRight: widget2, nullSlot: nullWidget));
    final _RenderDiagonal renderObject = tester.renderObject(find.byType(_Diagonal));
    expect(renderObject._topLeft!.size, const Size(10, 10));
    expect(renderObject._bottomRight!.size, const Size(100, 100));
    expect(renderObject._nullSlot!.size, const Size(50, 50));

    final Element widget1Element = tester.element(find.byWidget(widget1));
    final Element widget2Element = tester.element(find.byWidget(widget2));
    final Element nullWidgetElement = tester.element(find.byWidget(nullWidget));

    // Swapping 1 and 2.
    await tester.pumpWidget(buildWidget(topLeft: widget2, bottomRight: widget1, nullSlot: nullWidget));
    expect(renderObject._topLeft!.size, const Size(100, 100));
    expect(renderObject._bottomRight!.size, const Size(10, 10));
    expect(renderObject._nullSlot!.size, const Size(50, 50));
    expect(widget1Element, same(tester.element(find.byWidget(widget1))));
    expect(widget2Element, same(tester.element(find.byWidget(widget2))));
    expect(nullWidgetElement, same(tester.element(find.byWidget(nullWidget))));

    // Shifting slots
    await tester.pumpWidget(buildWidget(topLeft: nullWidget, bottomRight: widget2, nullSlot: widget1));
    expect(renderObject._topLeft!.size, const Size(50, 50));
    expect(renderObject._bottomRight!.size, const Size(100, 100));
    expect(renderObject._nullSlot!.size, const Size(10, 10));
    expect(widget1Element, same(tester.element(find.byWidget(widget1))));
    expect(widget2Element, same(tester.element(find.byWidget(widget2))));
    expect(nullWidgetElement, same(tester.element(find.byWidget(nullWidget))));

    // Moving + Deleting.
    await tester.pumpWidget(buildWidget(bottomRight: widget2));
    expect(renderObject._topLeft, null);
    expect(renderObject._bottomRight!.size, const Size(100, 100));
    expect(renderObject._nullSlot, null);
    expect(widget1Element.debugIsDefunct, isTrue);
    expect(nullWidgetElement.debugIsDefunct, isTrue);
    expect(widget2Element, same(tester.element(find.byWidget(widget2))));

    // Moving.
    await tester.pumpWidget(buildWidget(topLeft: widget2));
    expect(renderObject._topLeft!.size, const Size(100, 100));
    expect(renderObject._bottomRight, null);
    expect(widget2Element, same(tester.element(find.byWidget(widget2))));
  });

  testWidgets('duplicated key error message', (WidgetTester tester) async {
    const Widget widget1 = SizedBox(key: ValueKey<String>('widget 1'), height: 10, width: 10);
    const Widget widget2 = SizedBox(key: ValueKey<String>('widget 1'), height: 100, width: 100);
    const Widget widget3 = SizedBox(key: ValueKey<String>('widget 1'), height: 50, width: 50);

    await tester.pumpWidget(buildWidget(topLeft: widget1, bottomRight: widget2, nullSlot: widget3));

    expect((tester.takeException() as FlutterError).toString(), equalsIgnoringHashCodes(
     'Multiple widgets used the same key in _Diagonal.\n'
     "The key [<'widget 1'>] was used by multiple widgets. The offending widgets were:\n"
     "  - SizedBox-[<'widget 1'>](width: 50.0, height: 50.0, renderObject: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT)\n"
     "  - SizedBox-[<'widget 1'>](width: 10.0, height: 10.0, renderObject: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT)\n"
     "  - SizedBox-[<'widget 1'>](width: 100.0, height: 100.0, renderObject: RenderConstrainedBox#a4685 NEEDS-LAYOUT NEEDS-PAINT)\n"
     'A key can only be specified on one widget at a time in the same parent widget.'
    ));
  });

  testWidgets('debugDescribeChildren', (WidgetTester tester) async {
    await tester.pumpWidget(buildWidget(
      topLeft: const SizedBox(
        height: 100,
        width: 80,
      ),
      bottomRight: const SizedBox(
        height: 120,
        width: 110,
      ),
    ));

    expect(
      tester.renderObject(find.byType(_Diagonal)).toStringDeep(),
      equalsIgnoringHashCodes(r'''
_RenderDiagonal#00000 relayoutBoundary=up1
 │ creator: _Diagonal ← Align ← Directionality ← [root]
 │ parentData: offset=Offset(0.0, 0.0) (can use size)
 │ constraints: BoxConstraints(0.0<=w<=800.0, 0.0<=h<=600.0)
 │ size: Size(190.0, 220.0)
 │
 ├─topLeft: RenderConstrainedBox#00000 relayoutBoundary=up2
 │   creator: SizedBox ← _Diagonal ← Align ← Directionality ← [root]
 │   parentData: offset=Offset(0.0, 0.0) (can use size)
 │   constraints: BoxConstraints(unconstrained)
 │   size: Size(80.0, 100.0)
 │   additionalConstraints: BoxConstraints(w=80.0, h=100.0)
 │
 └─bottomRight: RenderConstrainedBox#00000 relayoutBoundary=up2
     creator: SizedBox ← _Diagonal ← Align ← Directionality ← [root]
     parentData: offset=Offset(80.0, 100.0) (can use size)
     constraints: BoxConstraints(unconstrained)
     size: Size(110.0, 120.0)
     additionalConstraints: BoxConstraints(w=110.0, h=120.0)
''')
    );
  });
}

Widget buildWidget({Widget? topLeft, Widget? bottomRight, Widget? nullSlot}) {
  return Directionality(
    textDirection: TextDirection.ltr,
    child: Align(
      alignment: Alignment.topLeft,
      child: _Diagonal(
        topLeft: topLeft,
        bottomRight: bottomRight,
        nullSlot: nullSlot,
      ),
    ),
  );
}

enum _DiagonalSlot {
  topLeft,
  bottomRight,
}

class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_DiagonalSlot?> {
  const _Diagonal({
    this.topLeft,
    this.bottomRight,
    this.nullSlot,
  });

  final Widget? topLeft;
  final Widget? bottomRight;
  final Widget? nullSlot;

  @override
  Iterable<_DiagonalSlot?> get slots => <_DiagonalSlot?>[null, ..._DiagonalSlot.values];

  @override
  Widget? childForSlot(_DiagonalSlot? slot) {
    switch (slot) {
      case null:
        return nullSlot;
      case _DiagonalSlot.topLeft:
        return topLeft;
      case _DiagonalSlot.bottomRight:
        return bottomRight;
    }
  }

  @override
  SlottedContainerRenderObjectMixin<_DiagonalSlot?> createRenderObject(
    BuildContext context,
  ) {
    return _RenderDiagonal();
  }
}

class _RenderDiagonal extends RenderBox with SlottedContainerRenderObjectMixin<_DiagonalSlot?> {
  RenderBox? get _topLeft => childForSlot(_DiagonalSlot.topLeft);
  RenderBox? get _bottomRight => childForSlot(_DiagonalSlot.bottomRight);
  RenderBox? get _nullSlot => childForSlot(null);

  @override
  void performLayout() {
    const BoxConstraints childConstraints = BoxConstraints();

    Size topLeftSize = Size.zero;
    if (_topLeft != null) {
      _topLeft!.layout(childConstraints, parentUsesSize: true);
      _positionChild(_topLeft!, Offset.zero);
      topLeftSize = _topLeft!.size;
    }

    Size bottomRightSize = Size.zero;
    if (_bottomRight != null) {
      _bottomRight!.layout(childConstraints, parentUsesSize: true);
      _positionChild(
        _bottomRight!,
        Offset(topLeftSize.width, topLeftSize.height),
      );
      bottomRightSize = _bottomRight!.size;
    }

    Size nullSlotSize = Size.zero;
    final RenderBox? nullSlot = _nullSlot;
    if (nullSlot != null) {
      nullSlot.layout(childConstraints, parentUsesSize: true);
      _positionChild(nullSlot, Offset.zero);
      nullSlotSize = nullSlot.size;
    }

    size = constraints.constrain(Size(
      topLeftSize.width + bottomRightSize.width + nullSlotSize.width,
      topLeftSize.height + bottomRightSize.height + nullSlotSize.height,
    ));
  }

  void _positionChild(RenderBox child, Offset offset) {
    (child.parentData! as BoxParentData).offset = offset;
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    if (_topLeft != null) {
      _paintChild(_topLeft!, context, offset);
    }
    if (_bottomRight != null) {
      _paintChild(_bottomRight!, context, offset);
    }
  }

  void _paintChild(RenderBox child, PaintingContext context, Offset offset) {
    final BoxParentData childParentData = child.parentData! as BoxParentData;
    context.paintChild(child, childParentData.offset + offset);
  }

  String publicNameForSlot(_DiagonalSlot slot) => debugNameForSlot(slot);
}

class _Slot {
  @override
  String toString() => describeIdentity(this);
}

class _RenderTest extends RenderBox with SlottedContainerRenderObjectMixin<_Slot> {
  String publicNameForSlot(_Slot slot) => debugNameForSlot(slot);
}
