// Copyright 2013 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/material.dart';
import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart';

import 'test_breakpoints.dart';

AnimatedWidget leftOutIn(Widget child, Animation<double> animation) {
  return SlideTransition(
    key: Key('in-${child.key}'),
    position: Tween<Offset>(
      begin: const Offset(-1, 0),
      end: Offset.zero,
    ).animate(animation),
    child: child,
  );
}

AnimatedWidget leftInOut(Widget child, Animation<double> animation) {
  return SlideTransition(
    key: Key('out-${child.key}'),
    position: Tween<Offset>(
      begin: Offset.zero,
      end: const Offset(-1, 0),
    ).animate(animation),
    child: child,
  );
}

class TestScaffold extends StatefulWidget {
  const TestScaffold({
    super.key,
    this.initialIndex = 0,
    this.isAnimated = true,
  });

  final int initialIndex;
  final bool isAnimated;

  static const List<NavigationDestination> destinations =
      <NavigationDestination>[
    NavigationDestination(
      key: Key('Inbox'),
      icon: Icon(Icons.inbox),
      label: 'Inbox',
    ),
    NavigationDestination(
      key: Key('Articles'),
      icon: Icon(Icons.article),
      label: 'Articles',
    ),
    NavigationDestination(
      key: Key('Chat'),
      icon: Icon(Icons.chat),
      label: 'Chat',
    ),
  ];

  @override
  State<TestScaffold> createState() => TestScaffoldState();
}

class TestScaffoldState extends State<TestScaffold> {
  late int index = widget.initialIndex;

  @override
  Widget build(BuildContext context) {
    return AdaptiveScaffold(
      selectedIndex: index,
      onSelectedIndexChange: (int index) {
        setState(() {
          this.index = index;
        });
      },
      drawerBreakpoint: NeverOnBreakpoint(),
      internalAnimations: widget.isAnimated,
      smallBreakpoint: TestBreakpoint0(),
      mediumBreakpoint: TestBreakpoint800(),
      largeBreakpoint: TestBreakpoint1000(),
      destinations: TestScaffold.destinations,
      smallBody: (_) => Container(color: Colors.red),
      body: (_) => Container(color: Colors.green),
      largeBody: (_) => Container(color: Colors.blue),
      smallSecondaryBody: (_) => Container(color: Colors.red),
      secondaryBody: (_) => Container(color: Colors.green),
      largeSecondaryBody: (_) => Container(color: Colors.blue),
    );
  }
}

enum SimulatedLayout {
  small(width: 400, navSlotKey: 'bottomNavigation'),
  medium(width: 800, navSlotKey: 'primaryNavigation'),
  large(width: 1100, navSlotKey: 'primaryNavigation1');

  const SimulatedLayout({
    required double width,
    required this.navSlotKey,
  }) : _width = width;

  final double _width;
  final double _height = 800;
  final String navSlotKey;

  Size get size => Size(_width, _height);

  MaterialApp app({
    int initialIndex = 0,
    bool animations = true,
  }) {
    return MaterialApp(
      home: MediaQuery(
        data: MediaQueryData(size: size),
        child: TestScaffold(
          initialIndex: initialIndex,
          isAnimated: animations,
        ),
      ),
    );
  }

  MediaQuery get slot {
    return MediaQuery(
      data: MediaQueryData.fromWindow(WidgetsBinding.instance.window)
          .copyWith(size: Size(_width, _height)),
      child: Theme(
        data: ThemeData(),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: SlotLayout(
            config: <Breakpoint, SlotLayoutConfig>{
              Breakpoints.small: SlotLayout.from(
                key: const Key('Breakpoints.small'),
                builder: (BuildContext context) => Container(),
              ),
              Breakpoints.smallMobile: SlotLayout.from(
                key: const Key('Breakpoints.smallMobile'),
                builder: (BuildContext context) => Container(),
              ),
              Breakpoints.smallDesktop: SlotLayout.from(
                key: const Key('Breakpoints.smallDesktop'),
                builder: (BuildContext context) => Container(),
              ),
              Breakpoints.medium: SlotLayout.from(
                key: const Key('Breakpoints.medium'),
                builder: (BuildContext context) => Container(),
              ),
              Breakpoints.mediumMobile: SlotLayout.from(
                key: const Key('Breakpoints.mediumMobile'),
                builder: (BuildContext context) => Container(),
              ),
              Breakpoints.mediumDesktop: SlotLayout.from(
                key: const Key('Breakpoints.mediumDesktop'),
                builder: (BuildContext context) => Container(),
              ),
              Breakpoints.large: SlotLayout.from(
                key: const Key('Breakpoints.large'),
                builder: (BuildContext context) => Container(),
              ),
              Breakpoints.largeMobile: SlotLayout.from(
                key: const Key('Breakpoints.largeMobile'),
                builder: (BuildContext context) => Container(),
              ),
              Breakpoints.largeDesktop: SlotLayout.from(
                key: const Key('Breakpoints.largeDesktop'),
                builder: (BuildContext context) => Container(),
              ),
            },
          ),
        ),
      ),
    );
  }
}
