// Copyright 2019 The Fuchsia 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 'sizer.dart';
import 'tile_model.dart';
import 'utils.dart';

typedef TileChromeBuilder = Widget Function(
    BuildContext context, TileModel tile);
typedef CustomTilesBuilder = Widget Function(
    BuildContext context, List<TileModel> tiles);

/// A [Widget] that renders a tile give its [TileModel]. If the tile type is
/// [TileType.content], it calls [chromeBuilder] to build a widget to render
/// the tile. Otherwise, it renders the [tiles] children in row or column
/// order. It calls [sizerBuilder] to get a sizing widget to display between
/// rows or columns of tiles.
class Tile extends StatelessWidget {
  final TileModel model;
  final TileChromeBuilder chromeBuilder;
  final TileSizerBuilder sizerBuilder;
  final CustomTilesBuilder customTilesBuilder;
  final double sizerThickness;
  final ValueChanged<TileModel> onFloat;

  const Tile({
    @required this.model,
    @required this.chromeBuilder,
    this.customTilesBuilder,
    this.sizerBuilder,
    this.sizerThickness,
    this.onFloat,
  });

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: model,
      builder: (context, child) {
        final type = model.type;
        if (model.isContent) {
          return chromeBuilder(context, model);
        } else if (model.tiles.isEmpty) {
          return SizedBox.shrink();
        } else {
          return LayoutBuilder(
            builder: (context, constraints) {
              assert(constraints.isTight);

              // Filter out tiles that are floating.
              final availableTiles = model.tiles;

              /// Filter out tiles that don't fit based on their minSize.
              final availableSize =
                  _availableSize(type, availableTiles, constraints.biggest);
              final tiles = _fit(type, availableTiles, availableSize).toList();
              bool fit = tiles.length == availableTiles.length;

              if (type != TileType.custom &&
                  (fit || customTilesBuilder == null)) {
                // Float the tiles that did not fit.
                availableTiles
                    .where((t) => !tiles.contains(t))
                    .toList()
                    .forEach(onFloat?.call);

                // All tiles fit, set flex,width and height and return tiles.
                final flex = _totalFlex(tiles);
                for (var tile in tiles) {
                  tile
                    ..flex = tile.flex / flex
                    ..width = availableSize.width
                    ..height = availableSize.height;
                }

                // Generate tile widgets with sizer widgets interleaved.
                final count = tiles.length + tiles.length - 1;
                final tileWidgets = List<Widget>.generate(count, (index) {
                  if (index.isOdd) {
                    return Sizer(
                      direction: model.type == TileType.row
                          ? Axis.horizontal
                          : Axis.vertical,
                      tileBefore: tiles[index ~/ 2],
                      tileAfter: tiles[index ~/ 2 + 1],
                      sizerBuilder: sizerBuilder,
                    );
                  } else {
                    return _tileBuilder(
                      tile: tiles[index ~/ 2],
                      chromeBuilder: chromeBuilder,
                      sizerBuilder: sizerBuilder,
                      customTilesBuilder: customTilesBuilder,
                      sizerThickness: sizerThickness,
                      onFloat: onFloat,
                    );
                  }
                });

                return model.type == TileType.row
                    ? Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: tileWidgets,
                      )
                    : Row(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: tileWidgets,
                      );
              } else {
                // Flatten all tiles to group them for tabbing between them.
                final allTiles = flatten(availableTiles).toList();
                // Display tabs only when we have more than 1 tile.
                if (allTiles.length > 1) {
                  return customTilesBuilder?.call(context, allTiles) ??
                      Offstage();
                } else {
                  return _tileBuilder(
                      tile: allTiles.first,
                      chromeBuilder: chromeBuilder,
                      sizerBuilder: sizerBuilder,
                      customTilesBuilder: customTilesBuilder,
                      sizerThickness: sizerThickness,
                      onFloat: onFloat);
                }
              }
            },
          );
        }
      },
    );
  }

  Widget _tileBuilder({
    TileModel tile,
    TileChromeBuilder chromeBuilder,
    TileSizerBuilder sizerBuilder,
    CustomTilesBuilder customTilesBuilder,
    ValueChanged<TileModel> onFloat,
    double sizerThickness,
  }) =>
      AnimatedBuilder(
        animation: tile,
        child: Tile(
          model: tile,
          chromeBuilder: chromeBuilder,
          sizerBuilder: sizerBuilder,
          customTilesBuilder: customTilesBuilder,
          onFloat: onFloat,
          sizerThickness: sizerThickness,
        ),
        builder: (context, child) => SizedBox(
              width: tile.width,
              height: tile.height,
              child: child,
            ),
      );

  /// Fit as many tiles as possible within [size].
  Iterable<TileModel> _fit(
      TileType type, Iterable<TileModel> tiles, Size size) {
    if (tiles.isEmpty) {
      return tiles;
    }

    // Calculate the normalized flex of each tile.
    final flex = _totalFlex(tiles);
    final width = size.width;
    final height = size.height;

    // Find tiles that don't fit based on their minSize.
    final unfitableTiles = tiles.where((tile) {
      double tileFlex = tile.flex / flex;
      double tileWidth = type == TileType.column ? tileFlex * width : width;
      double tileHeight = type == TileType.row ? tileFlex * height : height;
      return type == TileType.column
          ? tile.minSize.width > tileWidth
          : tile.minSize.height > tileHeight;
    });

    if (unfitableTiles.isEmpty) {
      return tiles;
    } else {
      // Remove the last tile in unfittableTiles from tiles and run fit again.
      return _fit(type, tiles.where((t) => t != unfitableTiles.last), size);
    }
  }

  // Returns the size available after sizers thickness is accounted for.
  Size _availableSize(TileType type, Iterable<TileModel> tiles, Size size) {
    final numTiles = tiles.length;
    final numSizers = numTiles - 1;

    // Calculate the width/height of a tile minus sizer thickness.
    final width = type == TileType.column
        ? (size.width - sizerThickness * numSizers)
        : size.width;
    final height = type == TileType.row
        ? (size.height - sizerThickness * numSizers)
        : size.height;
    return Size(width, height);
  }

  double _totalFlex(Iterable<TileModel> tiles) =>
      tiles.map((t) => t.flex).reduce((f1, f2) => f1 + f2);
}
