// 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/material.dart';

import 'stock_arrow.dart';
import 'stock_data.dart';

class _StockSymbolView extends StatelessWidget {
  const _StockSymbolView({
    required this.stock,
    required this.arrow,
  });

  final Stock stock;
  final Widget arrow;

  @override
  Widget build(BuildContext context) {
    assert(stock != null);
    final String lastSale = '\$${stock.lastSale.toStringAsFixed(2)}';
    String changeInPrice = '${stock.percentChange.toStringAsFixed(2)}%';
    if (stock.percentChange > 0)
      changeInPrice = '+$changeInPrice';

    final TextStyle headings = Theme.of(context).textTheme.bodyText1!;
    return Container(
      padding: const EdgeInsets.all(20.0),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Text(
                stock.symbol,
                key: ValueKey<String>('${stock.symbol}_symbol_name'),
                style: Theme.of(context).textTheme.headline3,
              ),
              arrow,
            ],
          ),
          Text('Last Sale', style: headings),
          Text('$lastSale ($changeInPrice)'),
          Container(
            height: 8.0
          ),
          Text('Market Cap', style: headings),
          Text(stock.marketCap),
          Container(
            height: 8.0
          ),
          RichText(
            text: TextSpan(
              style: DefaultTextStyle.of(context).style.merge(const TextStyle(fontSize: 8.0)),
              text: 'Prices may be delayed by ',
              children: const <TextSpan>[
                TextSpan(text: 'several', style: TextStyle(fontStyle: FontStyle.italic)),
                TextSpan(text: ' years.'),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class StockSymbolPage extends StatelessWidget {
  const StockSymbolPage({
    Key? key,
    required this.symbol,
    required this.stocks,
  }) : super(key: key);

  final String symbol;
  final StockData stocks;

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: stocks,
      builder: (BuildContext context, Widget? child) {
        final Stock? stock = stocks[symbol];
        return Scaffold(
          appBar: AppBar(
            title: Text(stock?.name ?? symbol),
          ),
          body: SingleChildScrollView(
            child: Container(
              margin: const EdgeInsets.all(20.0),
              child: Card(
                child: AnimatedCrossFade(
                  duration: const Duration(milliseconds: 300),
                  firstChild: const Padding(
                    padding: EdgeInsets.all(20.0),
                    child: Center(child: CircularProgressIndicator()),
                  ),
                  secondChild: stock != null
                    ? _StockSymbolView(
                      stock: stock,
                      arrow: Hero(
                        tag: stock,
                        child: StockArrow(percentChange: stock.percentChange),
                      ),
                    ) : Padding(
                        padding: const EdgeInsets.all(20.0),
                        child: Center(child: Text('$symbol not found')),
                    ),
                  crossFadeState: stock == null && stocks.loading ? CrossFadeState.showFirst : CrossFadeState.showSecond,
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

class StockSymbolBottomSheet extends StatelessWidget {
  const StockSymbolBottomSheet({
    Key? key,
    required this.stock,
  }) : super(key: key);

  final Stock stock;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(10.0),
      decoration: const BoxDecoration(
        border: Border(top: BorderSide(color: Colors.black26))
      ),
      child: _StockSymbolView(
        stock: stock,
        arrow: StockArrow(percentChange: stock.percentChange),
      ),
   );
  }
}
