part of let_log;

class NetWidget extends StatefulWidget {
  const NetWidget({Key key}) : super(key: key);

  @override
  _NetWidgetState createState() => _NetWidgetState();
}

class _NetWidgetState extends State<NetWidget> {
  bool _showSearch = false;
  String _keyword = "";
  TextEditingController _textController;
  ScrollController _scrollController;
  FocusNode _focusNode;
  bool _goDown = true;

  @override
  void initState() {
    _textController = TextEditingController(text: _keyword);
    _scrollController = ScrollController();
    _focusNode = FocusNode();
    super.initState();
  }

  @override
  void dispose() {
    _textController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          ValueListenableBuilder<int>(
            valueListenable: _Net.typeLength,
            builder: (context, value, child) {
              return _buildTools();
            },
          ),
          Expanded(
            child: ValueListenableBuilder<int>(
              valueListenable: _Net.length,
              builder: (context, value, child) {
                List<_Net> logs = _Net.list;
                if (!_selectTypes.contains(_Net.all)) {
                  logs = _Net.list.where((test) {
                    return _selectTypes.contains(test.type) &&
                        test.contains(_keyword);
                  }).toList();
                } else if (_keyword.isNotEmpty) {
                  logs = _Net.list.where((test) {
                    return test.contains(_keyword);
                  }).toList();
                }

                final len = logs.length;
                return ListView.separated(
                  itemBuilder: (context, index) {
                    final item = Logger.config.reverse
                        ? logs[len - index - 1]
                        : logs[index];
                    return _buildItem(item, context);
                  },
                  itemCount: len,
                  controller: _scrollController,
                  reverse: Logger.config.reverse,
                  separatorBuilder: (context, index) {
                    return const Divider(
                      height: 10,
                      thickness: 0.5,
                      color: Color(0xFFE0E0E0),
                    );
                  },
                );
              },
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          if (_goDown) {
            _scrollController.animateTo(
              _scrollController.position.maxScrollExtent * 2,
              curve: Curves.easeOut,
              duration: const Duration(milliseconds: 300),
            );
          } else {
            _scrollController.animateTo(
              0,
              curve: Curves.easeOut,
              duration: const Duration(milliseconds: 300),
            );
          }
          _goDown = !_goDown;
          setState(() {});
        },
        mini: true,
        child: Icon(
          _goDown ? Icons.arrow_downward : Icons.arrow_upward,
        ),
      ),
    );
  }

  Widget _buildItem(_Net item, context) {
    final color = _getColor(item.status);
    return InkWell(
      onTap: () {
        item.showDetail = !item.showDetail;
        setState(() {});
      },
      child: Padding(
        padding: const EdgeInsets.fromLTRB(16, 8, 16, 0),
        child: Row(
          children: [
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    "[${item.type}] ${item.api}",
                    style: const TextStyle(fontSize: 16),
                  ),
                  if (item.showDetail)
                    Padding(
                      padding: const EdgeInsets.only(top: 8),
                      child: Text(
                        "Request: ${item.req ?? ""}",
                        maxLines: 100,
                        overflow: TextOverflow.ellipsis,
                        style: const TextStyle(fontSize: 14),
                      ),
                    ),
                  if (item.showDetail)
                    Padding(
                      padding: const EdgeInsets.only(top: 8),
                      child: Text(
                        "Response: ${item.res ?? ""}",
                        maxLines: 100,
                        overflow: TextOverflow.ellipsis,
                        style: const TextStyle(fontSize: 14),
                      ),
                    ),
                  if (item.showDetail && item.headers != null)
                    Padding(
                      padding: const EdgeInsets.only(top: 8),
                      child: Text(
                        "Headers: ${item.headers ?? ""}",
                        maxLines: 100,
                        overflow: TextOverflow.ellipsis,
                        style: const TextStyle(fontSize: 14),
                      ),
                    ),
                  Padding(
                    padding: const EdgeInsets.only(top: 8, bottom: 8),
                    child: Row(
                      children: [
                        SizedBox(
                          width: 120,
                          child: Text(
                            "${item.start.hour}:${item.start.minute}:${item.start.second}:${item.start.millisecond}",
                            style: const TextStyle(fontSize: 14),
                            maxLines: 1,
                          ),
                        ),
                        SizedBox(
                          width: 100,
                          child: Text(
                            "${item.spend ?? "0"} ms",
                            style: const TextStyle(fontSize: 14),
                            overflow: TextOverflow.visible,
                            maxLines: 1,
                          ),
                        ),
                        Text(
                          "${item.getReqSize()}/${item.getResSize()}B",
                          style: const TextStyle(fontSize: 14),
                          overflow: TextOverflow.visible,
                          maxLines: 1,
                        ),
                      ],
                    ),
                  )
                ],
              ),
            ),
            InkWell(
              onTap: () {
                final ClipboardData data = ClipboardData(text: item.toString());
                Clipboard.setData(data);
                showDialog(
                  context: context,
                  barrierDismissible: true,
                  builder: (context) {
                    return const Center(
                      child: Material(
                        color: Colors.transparent,
                        child: Text(
                          "copy success!",
                          style: TextStyle(color: Colors.white, fontSize: 30),
                        ),
                      ),
                    );
                  },
                );
              },
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Text(
                    item.status.toString(),
                    style: TextStyle(fontSize: 20, color: color),
                  ),
                  if (item.showDetail)
                    const Text(
                      "copy",
                      style: TextStyle(fontSize: 16, color: Colors.blue),
                    ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Color _getColor(int status) {
    if (status == 200 || status == 0) {
      return Colors.green;
    } else if (status < 200) {
      return Colors.blue;
    } else {
      return Colors.red;
    }
  }

  final List<String> _selectTypes = [_Net.all];

  Widget _buildTools() {
    final List<ChoiceChip> arr = [];
    _Net.types.forEach((f) {
      arr.add(
        ChoiceChip(
          label: Text(f, style: const TextStyle(fontSize: 14)),
          selectedColor: const Color(0xFFCBE2F6),
          selected: _selectTypes.contains(f),
          onSelected: (value) {
            _selectTypes.contains(f)
                ? _selectTypes.remove(f)
                : _selectTypes.add(f);
            setState(() {});
          },
        ),
      );
    });
    return Padding(
      padding: const EdgeInsets.fromLTRB(16, 5, 0, 5),
      child: AnimatedCrossFade(
        crossFadeState:
            _showSearch ? CrossFadeState.showSecond : CrossFadeState.showFirst,
        duration: const Duration(milliseconds: 300),
        firstChild: Row(
          children: [
            Expanded(
              child: Wrap(
                spacing: 5,
                children: arr,
              ),
            ),
            const IconButton(
              icon: Icon(Icons.clear),
              onPressed: _Net.clear,
            ),
            IconButton(
              icon: _keyword.isEmpty
                  ? const Icon(Icons.search)
                  : const Icon(Icons.filter_1),
              onPressed: () {
                _showSearch = true;
                setState(() {});
                _focusNode.requestFocus();
              },
            ),
          ],
        ),
        secondChild: Row(
          children: [
            Expanded(
              child: SizedBox(
                height: 36,
                child: TextField(
                  decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    contentPadding: EdgeInsets.all(6),
                  ),
                  controller: _textController,
                  focusNode: _focusNode,
                ),
              ),
            ),
            IconButton(
              icon: const Icon(Icons.search),
              onPressed: () {
                _showSearch = false;
                _keyword = _textController.text;
                setState(() {});
              },
            ),
          ],
        ),
      ),
    );
  }
}