// 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 PictureCachePage extends StatelessWidget {
  const PictureCachePage({Key? key}) : super(key: key);

  static const List<String> kTabNames = <String>['1', '2', '3', '4', '5'];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: kTabNames.length, // This is the number of tabs.
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Picture Cache'),
          // pinned: true,
          // expandedHeight: 50.0,
          // forceElevated: innerBoxIsScrolled,
          bottom: TabBar(
            tabs: kTabNames.map((String name) => Tab(text: name)).toList(),
          ),
        ),
        body: TabBarView(
          key: const Key('tabbar_view'), // this key is used by the driver test
          children: kTabNames.map((String name) {
            return SafeArea(
              top: false,
              bottom: false,
              child: Builder(
                builder: (BuildContext context) {
                  return ListView.builder(
                    itemBuilder: (BuildContext context, int index) => ListItem(index: index),
                  );
                },
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

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

  final int index;

  static const String kMockChineseTitle = '复杂的中文标题？复杂的中文标题！';
  static const String kMockName = '李耳123456';
  static const int kMockCount = 999;

  @override
  Widget build(BuildContext context) {
    final List<Widget> contents = <Widget>[
      const SizedBox(
        height: 15,
      ),
      _buildUserInfo(),
      const SizedBox(
        height: 10,
      )
    ];
    if (index % 3 != 0) {
      contents.add(_buildImageContent());
    } else {
      contents.addAll(<Widget>[
        Padding(
          padding: const EdgeInsets.only(left: 40, right: 15),
          child: _buildContentText(),
        ),
        const SizedBox(
          height: 10,
        ),
        Padding(
          padding: const EdgeInsets.only(left: 40, right: 15),
          child: _buildBottomRow(),
        ),
      ]);
    }
    contents.addAll(<Widget>[
      const SizedBox(
        height: 13,
      ),
      buildDivider(0.5, const EdgeInsets.only(left: 40, right: 15)),
    ]);
    return MaterialButton(
      onPressed: () {},
      padding: EdgeInsets.zero,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: contents,
      ),
    );
  }

  Text _buildRankText() {
    return Text(
      (index + 1).toString(),
      style: TextStyle(
        fontSize: 15,
        color: index + 1 <= 3 ? const Color(0xFFE5645F) : Colors.black,
        fontWeight: FontWeight.bold,
      ),
    );
  }

  Widget _buildImageContent() {
    return Row(
      children: <Widget>[
        const SizedBox(
          width: 40,
        ),
        Expanded(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.only(right: 30),
                child: _buildContentText(),
              ),
              const SizedBox(
                height: 10,
              ),
              _buildBottomRow(),
            ],
          ),
        ),
        Image.asset(
          index.isEven ? 'food/butternut_squash_soup.png' : 'food/cherry_pie.png',
          package: 'flutter_gallery_assets',
          fit: BoxFit.cover,
          width: 110,
          height: 70,
        ),
        const SizedBox(
          width: 15,
        )
      ],
    );
  }

  Widget _buildContentText() {
    return const Text(
      kMockChineseTitle,
      style: TextStyle(
        fontSize: 16,
      ),
      maxLines: 2,
      overflow: TextOverflow.ellipsis,
    );
  }

  Widget _buildBottomRow() {
    return Row(
      children: <Widget>[
        Container(
          padding: const EdgeInsets.symmetric(
            horizontal: 7,
          ),
          height: 16,
          alignment: Alignment.center,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(8),
            color: const Color(0xFFFBEEEE),
          ),
          child: Row(
            children: <Widget>[
              const SizedBox(
                width: 3,
              ),
              Text(
                'hot:${_convertCountToStr(kMockCount)}',
                style: const TextStyle(
                  color: Color(0xFFE5645F),
                  fontSize: 11,
                ),
              ),
            ],
          ),
        ),
        const SizedBox(
          width: 9,
        ),
        const Text(
          'ans:$kMockCount',
          style: TextStyle(
            color: Color(0xFF999999),
            fontSize: 11,
          ),
        ),
        const SizedBox(
          width: 9,
        ),
        const Text(
          'like:$kMockCount',
          style: TextStyle(
            color: Color(0xFF999999),
            fontSize: 11,
          ),
        ),
      ],
    );
  }

  String _convertCountToStr(int count) {
    if (count < 10000) {
      return count.toString();
    } else if (count < 100000) {
      return '${(count / 10000).toStringAsPrecision(2)}w';
    } else {
      return '${(count / 10000).floor()}w';
    }
  }

  Widget _buildUserInfo() {
    return GestureDetector(
      onTap: () {},
      child: Row(
        children: <Widget>[
          Container(
              width: 40, alignment: Alignment.center, child: _buildRankText()),
          const CircleAvatar(
            radius: 11.5,
          ),
          const SizedBox(
            width: 6,
          ),
          ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: 250),
            child: const Text(
              kMockName,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                fontSize: 14,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
          const SizedBox(
            width: 4,
          ),
          const SizedBox(
            width: 15,
          ),
        ],
      ),
    );
  }

  Widget buildDivider(double height, EdgeInsets padding) {
    return Container(
      padding: padding,
      height: height,
      color: const Color(0xFFF5F5F5),
    );
  }
}
