// 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';

class FortnightlyDemo extends StatelessWidget {
  const FortnightlyDemo({super.key});

  static const String routeName = '/fortnightly';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fortnightly Demo',
      theme: _fortnightlyTheme,
      home: Scaffold(
        body: Stack(
          children: <Widget>[
            const FruitPage(),
            SafeArea(
              child: ShortAppBar(
                onBackPressed: () {
                  Navigator.pop(context);
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ShortAppBar extends StatelessWidget {
  const ShortAppBar({ super.key, this.onBackPressed });

  final VoidCallback? onBackPressed;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 96,
      height: 50,
      child: Material(
        color: Theme.of(context).colorScheme.surface,
        elevation: 4,
        shape: const BeveledRectangleBorder(
          borderRadius: BorderRadius.only(bottomRight: Radius.circular(22)),
        ),
        child: Row(
          children: <Widget>[
            IconButton(
              icon: const Icon(Icons.arrow_back),
              tooltip: 'Back',
              onPressed: onBackPressed,
            ),
            const SizedBox(width: 12),
            Image.asset(
              'logos/fortnightly/fortnightly_logo.png',
              package: 'flutter_gallery_assets',
            ),
          ],
        ),
      ),
    );
  }
}

class FruitPage extends StatelessWidget {
  const FruitPage({super.key});

  static final String paragraph1 = '''
Have you ever held a quince? It's strange;
covered in a fuzz somewhere between peach skin and a spider web. And it's
hard as soft lumber. You'd be forgiven for thinking it's veneered Larch-wood.
But inhale the aroma and you'll instantly know you have something wonderful.
Its scent can fill a room for days. And all this before you've even cooked it.
'''.replaceAll('\n', ' ');

  static final String paragraph2 = '''
Pomegranates on the other hand have become
almost ubiquitous. You can find its juice in any bodega, Walmart, and even some
gas stations. But at what cost? The pomegranate juice craze of the aughts made
"megafarmers" Lynda and Stewart Resnick billions. Unfortunately, it takes a lot
of water to make that much pomegranate juice. Water the Resnicks get from their
majority stake in the Kern Water Bank. How did one family come to hold control
over water meant for the whole central valley of California? The story will shock you.
'''.replaceAll('\n', ' ');

  @override
  Widget build(BuildContext context) {
    final TextTheme textTheme = Theme.of(context).primaryTextTheme;

    return SingleChildScrollView(
      child: SafeArea(
        top: false,
        child: Container(
          color: Theme.of(context).colorScheme.surface,
          child: Column(
            children: <Widget>[
              Container(
                constraints: const BoxConstraints.expand(height: 248),
                child: Image.asset(
                  'food/fruits.png',
                  package: 'flutter_gallery_assets',
                  fit: BoxFit.fitWidth,
                ),
              ),
              const SizedBox(height: 17),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        Text(
                          'US',
                          style: textTheme.labelSmall,
                        ),
                        Text(
                          ' ¬ ',
                          // TODO(larche): Replace textTheme.headline2.color with a ColorScheme value when known.
                          style: textTheme.labelSmall!.apply(color: textTheme.displayMedium!.color),
                        ),
                        Text(
                          'CULTURE',
                          style: textTheme.labelSmall,
                        ),
                      ],
                    ),
                    const SizedBox(height: 10),
                    Text(
                      'Quince for Wisdom, Persimmon for Luck, Pomegranate for Love',
                      style: textTheme.headlineMedium,
                    ),
                    const SizedBox(height: 10),
                    Text(
                      'How these crazy fruits sweetened our hearts, relationships, '
                          'and puffed pastries',
                      style: textTheme.bodyMedium,
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 16),
                      child: Row(
                        children: <Widget>[
                          const CircleAvatar(
                            backgroundImage: ExactAssetImage(
                              'people/square/trevor.png',
                              package: 'flutter_gallery_assets',
                            ),
                            radius: 20,
                          ),
                          const SizedBox(width: 12),
                          Text(
                            'by',
                            style: textTheme.displayMedium,
                          ),
                          const SizedBox(width: 4),
                          const Text(
                            'Connor Eghan',
                            style: TextStyle(
                              fontFamily: 'Merriweather',
                              fontSize: 18,
                              fontWeight: FontWeight.w500,
                              color: Colors.black,
                            ),
                          ),
                        ],
                      ),
                    ),
                    Text(
                      '$paragraph1\n\n$paragraph2',
                      style: textTheme.bodyLarge,
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

final ThemeData _fortnightlyTheme = _buildFortnightlyTheme();

ThemeData _buildFortnightlyTheme() {
  final ThemeData base = ThemeData.light();
  return base.copyWith(
    primaryTextTheme: _buildTextTheme(base.primaryTextTheme),
    scaffoldBackgroundColor: Colors.white,
  );
}

TextTheme _buildTextTheme(TextTheme base) {
  TextTheme theme = base.apply(bodyColor: Colors.black);
  theme = theme.apply(displayColor: Colors.black);

  theme = theme.copyWith(
    headlineMedium: base.headlineMedium!.copyWith(
      fontFamily: 'Merriweather',
      fontStyle: FontStyle.italic,
      fontSize: 28,
      fontWeight: FontWeight.w800,
      color: Colors.black,
      height: .88,
    ),
    displayMedium: base.displayMedium!.copyWith(
      fontFamily: 'LibreFranklin',
      fontSize: 18,
      fontWeight: FontWeight.w500,
      color: Colors.black.withAlpha(153),
    ),
    headlineSmall: base.headlineSmall!.copyWith(fontWeight: FontWeight.w500),
    bodyMedium: base.bodyMedium!.copyWith(
      fontFamily: 'Merriweather',
      fontSize: 14,
      fontWeight: FontWeight.w300,
      color: const Color(0xFF666666),
      height: 1.11,
    ),
    bodyLarge: base.bodyLarge!.copyWith(
      fontFamily: 'Merriweather',
      fontSize: 16,
      fontWeight: FontWeight.w300,
      color: const Color(0xFF666666),
      height: 1.4,
      letterSpacing: .25,
    ),
    labelSmall: const TextStyle(
      fontFamily: 'LibreFranklin',
      fontSize: 10,
      fontWeight: FontWeight.w700,
      color: Colors.black,
    ),
  );

  return theme;
}
